utilful 1.1.0 → 1.2.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.
- package/README.md +17 -30
- package/dist/csv.d.mts +3 -1
- package/dist/csv.d.ts +3 -1
- package/dist/csv.mjs +6 -5
- package/dist/emitter.d.mts +19 -67
- package/dist/emitter.d.ts +19 -67
- package/dist/emitter.mjs +56 -10
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,49 +113,36 @@ const data = parseCSV<'name' | 'age'>(csv) // [{ name: 'John', age: '30' }, { na
|
|
|
113
113
|
|
|
114
114
|
### Emitter
|
|
115
115
|
|
|
116
|
-
|
|
116
|
+
Tiny functional event emitter / pubsub, based on [mitt](https://github.com/developit/mitt).
|
|
117
117
|
|
|
118
|
-
|
|
118
|
+
**Example:**
|
|
119
119
|
|
|
120
120
|
```ts
|
|
121
121
|
import { createEmitter } from 'utilful'
|
|
122
122
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
123
|
+
// eslint-disable-next-line ts/consistent-type-definitions
|
|
124
|
+
type Events = {
|
|
125
|
+
foo: { a: string }
|
|
126
126
|
}
|
|
127
127
|
|
|
128
128
|
const emitter = createEmitter<Events>()
|
|
129
129
|
|
|
130
|
-
//
|
|
131
|
-
emitter.
|
|
132
|
-
emitter.emit('tick')
|
|
133
|
-
|
|
134
|
-
// Compilation errors:
|
|
135
|
-
emitter.emit('set', 'prop', '1')
|
|
136
|
-
emitter.emit('tick', 2)
|
|
137
|
-
```
|
|
130
|
+
// Listen to an event
|
|
131
|
+
emitter.on('foo', e => console.log('foo', e))
|
|
138
132
|
|
|
139
|
-
|
|
133
|
+
// Listen to all events
|
|
134
|
+
emitter.on('*', (type, e) => console.log(type, e))
|
|
140
135
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
console.log(`on ${number}`)
|
|
144
|
-
})
|
|
136
|
+
// Fire an event
|
|
137
|
+
emitter.emit('foo', { a: 'b' })
|
|
145
138
|
|
|
146
|
-
|
|
147
|
-
|
|
139
|
+
// Clearing all events
|
|
140
|
+
emitter.all.clear()
|
|
148
141
|
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
//
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
You can get the used events list by accessing the `events` property:
|
|
155
|
-
|
|
156
|
-
```ts
|
|
157
|
-
const unbind = emitter.on('tick', () => { })
|
|
158
|
-
emitter.events // => { tick: [ [Function] ] }
|
|
142
|
+
// Working with handler references:
|
|
143
|
+
function onFoo() {}
|
|
144
|
+
emitter.on('foo', onFoo) // Listen
|
|
145
|
+
emitter.off('foo', onFoo) // Unlisten
|
|
159
146
|
```
|
|
160
147
|
|
|
161
148
|
### JSON
|
package/dist/csv.d.mts
CHANGED
|
@@ -30,12 +30,14 @@ declare function createCSV<T extends Record<string, unknown>>(data: T[], columns
|
|
|
30
30
|
*
|
|
31
31
|
* @remarks
|
|
32
32
|
* Returns an empty string if the value is `null` or `undefined`.
|
|
33
|
+
* Values containing delimiters, quotes, or line breaks are quoted.
|
|
34
|
+
* Within quoted values, double quotes are escaped by doubling them.
|
|
33
35
|
*
|
|
34
36
|
* @example
|
|
35
37
|
* escapeCSVValue('hello, world'); // "hello, world"
|
|
36
38
|
* escapeCSVValue('contains "quotes"'); // "contains ""quotes"""
|
|
37
39
|
*/
|
|
38
|
-
declare function escapeCSVValue(value: unknown,
|
|
40
|
+
declare function escapeCSVValue(value: unknown, options?: {
|
|
39
41
|
/** @default ',' */
|
|
40
42
|
delimiter?: string;
|
|
41
43
|
/** @default false */
|
package/dist/csv.d.ts
CHANGED
|
@@ -30,12 +30,14 @@ declare function createCSV<T extends Record<string, unknown>>(data: T[], columns
|
|
|
30
30
|
*
|
|
31
31
|
* @remarks
|
|
32
32
|
* Returns an empty string if the value is `null` or `undefined`.
|
|
33
|
+
* Values containing delimiters, quotes, or line breaks are quoted.
|
|
34
|
+
* Within quoted values, double quotes are escaped by doubling them.
|
|
33
35
|
*
|
|
34
36
|
* @example
|
|
35
37
|
* escapeCSVValue('hello, world'); // "hello, world"
|
|
36
38
|
* escapeCSVValue('contains "quotes"'); // "contains ""quotes"""
|
|
37
39
|
*/
|
|
38
|
-
declare function escapeCSVValue(value: unknown,
|
|
40
|
+
declare function escapeCSVValue(value: unknown, options?: {
|
|
39
41
|
/** @default ',' */
|
|
40
42
|
delimiter?: string;
|
|
41
43
|
/** @default false */
|
package/dist/csv.mjs
CHANGED
|
@@ -13,14 +13,15 @@ function createCSV(data, columns, options = {}) {
|
|
|
13
13
|
}
|
|
14
14
|
return rows.join("\n");
|
|
15
15
|
}
|
|
16
|
-
function escapeCSVValue(value, {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
16
|
+
function escapeCSVValue(value, options = {}) {
|
|
17
|
+
const {
|
|
18
|
+
delimiter = ",",
|
|
19
|
+
quoteAll = false
|
|
20
|
+
} = options;
|
|
20
21
|
if (value == null) {
|
|
21
22
|
return "";
|
|
22
23
|
}
|
|
23
|
-
const stringValue = value
|
|
24
|
+
const stringValue = String(value);
|
|
24
25
|
const needsQuoting = quoteAll || stringValue.includes(delimiter) || stringValue.includes('"') || stringValue.includes("\n") || stringValue.includes("\r");
|
|
25
26
|
if (needsQuoting) {
|
|
26
27
|
return `"${stringValue.replaceAll('"', '""')}"`;
|
package/dist/emitter.d.mts
CHANGED
|
@@ -1,72 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
interface
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* emitter.emit('tick', tickType, tickDuration)
|
|
16
|
-
*
|
|
17
|
-
* @param event The event name.
|
|
18
|
-
* @param args The arguments for listeners.
|
|
19
|
-
*/
|
|
20
|
-
emit: <K extends keyof Events>(this: this, event: K, ...args: Parameters<Events[K]>) => void;
|
|
21
|
-
/**
|
|
22
|
-
* Event names in keys and arrays with listeners in values.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* emitter1.events = emitter2.events
|
|
26
|
-
* emitter2.events = { }
|
|
27
|
-
*/
|
|
28
|
-
events: Partial<{
|
|
29
|
-
[E in keyof Events]: Events[E][];
|
|
30
|
-
}>;
|
|
31
|
-
/**
|
|
32
|
-
* Add a listener for a given event.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* const unbind = emitter.on('tick', (tickType, tickDuration) => {
|
|
36
|
-
* count += 1
|
|
37
|
-
* })
|
|
38
|
-
*
|
|
39
|
-
* disable () {
|
|
40
|
-
* unbind()
|
|
41
|
-
* }
|
|
42
|
-
*
|
|
43
|
-
* @param event The event name.
|
|
44
|
-
* @param cb The listener function.
|
|
45
|
-
* @returns Unbind listener from event.
|
|
46
|
-
*/
|
|
47
|
-
on: <K extends keyof Events>(this: this, event: K, cb: Events[K]) => Unsubscribe;
|
|
1
|
+
type EventType = string | symbol;
|
|
2
|
+
type Handler<T = unknown> = (event: T) => void;
|
|
3
|
+
type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;
|
|
4
|
+
type EventHandlerList<T = unknown> = Handler<T>[];
|
|
5
|
+
type WildCardEventHandlerList<T = Record<string, unknown>> = WildcardHandler<T>[];
|
|
6
|
+
type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | '*', EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>>;
|
|
7
|
+
interface Emitter<Events extends Record<EventType, unknown>> {
|
|
8
|
+
all: EventHandlerMap<Events>;
|
|
9
|
+
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
|
|
10
|
+
on(type: '*', handler: WildcardHandler<Events>): void;
|
|
11
|
+
off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
|
|
12
|
+
off(type: '*', handler: WildcardHandler<Events>): void;
|
|
13
|
+
emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
|
|
14
|
+
emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;
|
|
48
15
|
}
|
|
49
16
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* import { createEmitter } from 'nanoevents'
|
|
54
|
-
*
|
|
55
|
-
* class Ticker {
|
|
56
|
-
* constructor() {
|
|
57
|
-
* this.emitter = createEmitter()
|
|
58
|
-
* }
|
|
59
|
-
* on(...args) {
|
|
60
|
-
* return this.emitter.on(...args)
|
|
61
|
-
* }
|
|
62
|
-
* tick() {
|
|
63
|
-
* this.emitter.emit('tick')
|
|
64
|
-
* }
|
|
65
|
-
* }
|
|
17
|
+
* Simple functional event emitter / pubsub.
|
|
66
18
|
*
|
|
67
|
-
* @remarks Ported from `
|
|
68
|
-
* @see https://github.com/
|
|
19
|
+
* @remarks Ported from `mitt`.
|
|
20
|
+
* @see https://github.com/developit/mitt
|
|
69
21
|
*/
|
|
70
|
-
declare function createEmitter<Events extends
|
|
22
|
+
declare function createEmitter<Events extends Record<EventType, unknown>>(all?: EventHandlerMap<Events>): Emitter<Events>;
|
|
71
23
|
|
|
72
|
-
export { type Emitter, createEmitter };
|
|
24
|
+
export { type Emitter, type EventHandlerList, type EventHandlerMap, type EventType, type Handler, type WildCardEventHandlerList, type WildcardHandler, createEmitter };
|
package/dist/emitter.d.ts
CHANGED
|
@@ -1,72 +1,24 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
interface
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
* emitter.emit('tick', tickType, tickDuration)
|
|
16
|
-
*
|
|
17
|
-
* @param event The event name.
|
|
18
|
-
* @param args The arguments for listeners.
|
|
19
|
-
*/
|
|
20
|
-
emit: <K extends keyof Events>(this: this, event: K, ...args: Parameters<Events[K]>) => void;
|
|
21
|
-
/**
|
|
22
|
-
* Event names in keys and arrays with listeners in values.
|
|
23
|
-
*
|
|
24
|
-
* @example
|
|
25
|
-
* emitter1.events = emitter2.events
|
|
26
|
-
* emitter2.events = { }
|
|
27
|
-
*/
|
|
28
|
-
events: Partial<{
|
|
29
|
-
[E in keyof Events]: Events[E][];
|
|
30
|
-
}>;
|
|
31
|
-
/**
|
|
32
|
-
* Add a listener for a given event.
|
|
33
|
-
*
|
|
34
|
-
* @example
|
|
35
|
-
* const unbind = emitter.on('tick', (tickType, tickDuration) => {
|
|
36
|
-
* count += 1
|
|
37
|
-
* })
|
|
38
|
-
*
|
|
39
|
-
* disable () {
|
|
40
|
-
* unbind()
|
|
41
|
-
* }
|
|
42
|
-
*
|
|
43
|
-
* @param event The event name.
|
|
44
|
-
* @param cb The listener function.
|
|
45
|
-
* @returns Unbind listener from event.
|
|
46
|
-
*/
|
|
47
|
-
on: <K extends keyof Events>(this: this, event: K, cb: Events[K]) => Unsubscribe;
|
|
1
|
+
type EventType = string | symbol;
|
|
2
|
+
type Handler<T = unknown> = (event: T) => void;
|
|
3
|
+
type WildcardHandler<T = Record<string, unknown>> = (type: keyof T, event: T[keyof T]) => void;
|
|
4
|
+
type EventHandlerList<T = unknown> = Handler<T>[];
|
|
5
|
+
type WildCardEventHandlerList<T = Record<string, unknown>> = WildcardHandler<T>[];
|
|
6
|
+
type EventHandlerMap<Events extends Record<EventType, unknown>> = Map<keyof Events | '*', EventHandlerList<Events[keyof Events]> | WildCardEventHandlerList<Events>>;
|
|
7
|
+
interface Emitter<Events extends Record<EventType, unknown>> {
|
|
8
|
+
all: EventHandlerMap<Events>;
|
|
9
|
+
on<Key extends keyof Events>(type: Key, handler: Handler<Events[Key]>): void;
|
|
10
|
+
on(type: '*', handler: WildcardHandler<Events>): void;
|
|
11
|
+
off<Key extends keyof Events>(type: Key, handler?: Handler<Events[Key]>): void;
|
|
12
|
+
off(type: '*', handler: WildcardHandler<Events>): void;
|
|
13
|
+
emit<Key extends keyof Events>(type: Key, event: Events[Key]): void;
|
|
14
|
+
emit<Key extends keyof Events>(type: undefined extends Events[Key] ? Key : never): void;
|
|
48
15
|
}
|
|
49
16
|
/**
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
* @example
|
|
53
|
-
* import { createEmitter } from 'nanoevents'
|
|
54
|
-
*
|
|
55
|
-
* class Ticker {
|
|
56
|
-
* constructor() {
|
|
57
|
-
* this.emitter = createEmitter()
|
|
58
|
-
* }
|
|
59
|
-
* on(...args) {
|
|
60
|
-
* return this.emitter.on(...args)
|
|
61
|
-
* }
|
|
62
|
-
* tick() {
|
|
63
|
-
* this.emitter.emit('tick')
|
|
64
|
-
* }
|
|
65
|
-
* }
|
|
17
|
+
* Simple functional event emitter / pubsub.
|
|
66
18
|
*
|
|
67
|
-
* @remarks Ported from `
|
|
68
|
-
* @see https://github.com/
|
|
19
|
+
* @remarks Ported from `mitt`.
|
|
20
|
+
* @see https://github.com/developit/mitt
|
|
69
21
|
*/
|
|
70
|
-
declare function createEmitter<Events extends
|
|
22
|
+
declare function createEmitter<Events extends Record<EventType, unknown>>(all?: EventHandlerMap<Events>): Emitter<Events>;
|
|
71
23
|
|
|
72
|
-
export { type Emitter, createEmitter };
|
|
24
|
+
export { type Emitter, type EventHandlerList, type EventHandlerMap, type EventType, type Handler, type WildCardEventHandlerList, type WildcardHandler, createEmitter };
|
package/dist/emitter.mjs
CHANGED
|
@@ -1,16 +1,62 @@
|
|
|
1
|
-
function createEmitter() {
|
|
1
|
+
function createEmitter(all) {
|
|
2
|
+
all ||= /* @__PURE__ */ new Map();
|
|
2
3
|
return {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
4
|
+
/**
|
|
5
|
+
* A Map of event names to registered handler functions.
|
|
6
|
+
*/
|
|
7
|
+
all,
|
|
8
|
+
/**
|
|
9
|
+
* Register an event handler for the given type.
|
|
10
|
+
* @param {string|symbol} type Type of event to listen for, or `'*'` for all events
|
|
11
|
+
* @param {Function} handler Function to call in response to given event
|
|
12
|
+
* @memberOf createEmitter
|
|
13
|
+
*/
|
|
14
|
+
on(type, handler) {
|
|
15
|
+
const handlers = all.get(type);
|
|
16
|
+
if (handlers) {
|
|
17
|
+
handlers.push(handler);
|
|
18
|
+
} else {
|
|
19
|
+
all.set(type, [handler]);
|
|
6
20
|
}
|
|
7
21
|
},
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
22
|
+
/**
|
|
23
|
+
* Remove an event handler for the given type.
|
|
24
|
+
* If `handler` is omitted, all handlers of the given type are removed.
|
|
25
|
+
*
|
|
26
|
+
* @param {string|symbol} type Type of event to unregister `handler` from (`'*'` to remove a wildcard handler)
|
|
27
|
+
* @param {Function} [handler] Handler function to remove
|
|
28
|
+
* @memberOf createEmitter
|
|
29
|
+
*/
|
|
30
|
+
off(type, handler) {
|
|
31
|
+
const handlers = all.get(type);
|
|
32
|
+
if (handlers) {
|
|
33
|
+
if (handler) {
|
|
34
|
+
handlers.splice(handlers.indexOf(handler) >>> 0, 1);
|
|
35
|
+
} else {
|
|
36
|
+
all.set(type, []);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
/**
|
|
41
|
+
* Invoke all handlers for the given type.
|
|
42
|
+
* If present, `'*'` handlers are invoked after type-matched handlers.
|
|
43
|
+
*
|
|
44
|
+
* @remarks
|
|
45
|
+
* Manually firing '*' handlers is not supported.
|
|
46
|
+
*
|
|
47
|
+
* @param {string|symbol} type The event type to invoke
|
|
48
|
+
* @param {Any} [evt] Any value (object is recommended and powerful), passed to each handler
|
|
49
|
+
* @memberOf createEmitter
|
|
50
|
+
*/
|
|
51
|
+
emit(type, evt) {
|
|
52
|
+
let handlers = all.get(type);
|
|
53
|
+
handlers?.slice().forEach((handler) => {
|
|
54
|
+
handler(evt);
|
|
55
|
+
});
|
|
56
|
+
handlers = all.get("*");
|
|
57
|
+
handlers?.slice().forEach((handler) => {
|
|
58
|
+
handler(type, evt);
|
|
59
|
+
});
|
|
14
60
|
}
|
|
15
61
|
};
|
|
16
62
|
}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { MaybeArray, toArray } from './array.mjs';
|
|
2
2
|
export { CSVRow, createCSV, escapeCSVValue, parseCSV } from './csv.mjs';
|
|
3
|
-
export { Emitter, createEmitter } from './emitter.mjs';
|
|
3
|
+
export { Emitter, EventHandlerList, EventHandlerMap, EventType, Handler, WildCardEventHandlerList, WildcardHandler, createEmitter } from './emitter.mjs';
|
|
4
4
|
export { cloneJSON, tryParseJSON } from './json.mjs';
|
|
5
5
|
export { lazy } from './lazy.mjs';
|
|
6
6
|
export { interopDefault } from './module.mjs';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { MaybeArray, toArray } from './array.js';
|
|
2
2
|
export { CSVRow, createCSV, escapeCSVValue, parseCSV } from './csv.js';
|
|
3
|
-
export { Emitter, createEmitter } from './emitter.js';
|
|
3
|
+
export { Emitter, EventHandlerList, EventHandlerMap, EventType, Handler, WildCardEventHandlerList, WildcardHandler, createEmitter } from './emitter.js';
|
|
4
4
|
export { cloneJSON, tryParseJSON } from './json.js';
|
|
5
5
|
export { lazy } from './lazy.js';
|
|
6
6
|
export { interopDefault } from './module.js';
|
package/package.json
CHANGED