@vandeurenglenn/little-pubsub 1.4.6 → 1.4.8

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/.prettierrc ADDED
@@ -0,0 +1,7 @@
1
+ {
2
+ "tabWidth": 2,
3
+ "semi": false,
4
+ "singleQuote": true,
5
+ "printWidth": 80,
6
+ "trailingComma": "none"
7
+ }
package/.travis.yml CHANGED
@@ -1,8 +1,8 @@
1
- language: node_js
2
- node_js:
3
- - '16'
4
- - '18'
5
- cache:
6
- yarn: true
7
- before_script:
8
- - npm run build
1
+ language: node_js
2
+ node_js:
3
+ - '16'
4
+ - '22'
5
+ cache:
6
+ yarn: true
7
+ before_script:
8
+ - npm run build
package/README.md CHANGED
@@ -1,81 +1,121 @@
1
- # little-pubsub
2
- > Small publish & subscribe class
3
-
4
- ## INSTALL
5
-
6
- #### npm
7
- ```sh
8
- npm i --save @vandeurenglenn/little-pubsub
9
- ```
10
-
11
- ## USAGE
12
-
13
- ```js
14
- import PubSub from '@vandeurenglenn/little-pubsub';
15
- const pubsub = new PubSub();
16
- ```
17
-
18
- ## Example
19
-
20
- ```js
21
- import PubSub from '@vandeurenglenn/little-pubsub';
22
- const pubsub = new PubSub();
23
-
24
- pubsub.subscribe('event', value => { console.log(value) })
25
-
26
- pubsub.publish('event', 'hello')
27
-
28
- pubsub.unsubscribe('event', value => { console.log(value) })
29
-
30
- pubsub.hasSubscribers('event')
31
-
32
- await pubsub.once('event')
33
- ```
34
-
35
- ## API
36
- ### pubsub([options])
37
- `verbose`: when false only fires after value change<br>
38
- ```js
39
- pubsub = new PubSub({
40
- verbose: false // default: true
41
- })
42
- ```
43
-
44
- #### subscribe
45
- `name`: name of the channel to subscribe to<br>
46
- `handler`: method<br>
47
- `context`: context<br>
48
- ```js
49
- pubsub.subscribe('event-name', data => {
50
- console.log(data);
51
- })
52
- ```
53
- #### unsubscribe
54
- `name`: name of the channel to unsubscribe<br>
55
- `handler`: method<br>
56
- `context`: context<br>
57
- ```js
58
- pubsub.unsubscribe('event-name', data => {
59
- console.log(data);
60
- })
61
- ```
62
-
63
- #### publish
64
- `name`: name of the channel to publish to<br>
65
- `handler`: method<br>
66
- `context`: context<br>
67
- ```js
68
- pubsub.publish('event-name', 'data')
69
- ```
70
-
71
- #### once
72
- `name`: name of the channel to publish to<br>
73
- ```js
74
- await pubsub.once('event-name')
75
- ```
76
-
77
- #### hasSubscribers
78
- `name`: name of the channel to publish to<br>
79
- ```js
80
- pubsub.hasSubscribers('event-name')
81
- ```
1
+ # little-pubsub
2
+
3
+ > Small publish & subscribe class
4
+
5
+ ## INSTALL
6
+
7
+ #### npm
8
+
9
+ ```sh
10
+ npm i --save @vandeurenglenn/little-pubsub
11
+ ```
12
+
13
+ ## USAGE
14
+
15
+ ```js
16
+ import PubSub from '@vandeurenglenn/little-pubsub'
17
+ const pubsub = new PubSub()
18
+ ```
19
+
20
+ ## Example
21
+
22
+ ```js
23
+ import PubSub from '@vandeurenglenn/little-pubsub'
24
+ const pubsub = new PubSub()
25
+
26
+ pubsub.subscribe('event', (value) => {
27
+ console.log(value)
28
+ })
29
+
30
+ pubsub.publish('event', 'hello')
31
+ // always runs handler
32
+ // (can use to overide littlePubsub.verbose setting without changing the behavior of the rest)
33
+ pubsub.publishVerbose('event', 'hello')
34
+
35
+ pubsub.unsubscribe('event', (value) => {
36
+ console.log(value)
37
+ })
38
+
39
+ pubsub.hasSubscribers('event')
40
+
41
+ await pubsub.once('event')
42
+ ```
43
+
44
+ ## API
45
+
46
+ ### pubsub([options])
47
+
48
+ `verbose`: when false only fires after value change<br>
49
+
50
+ ```js
51
+ pubsub = new PubSub({
52
+ verbose: false // default: true
53
+ })
54
+ ```
55
+
56
+ #### subscribe
57
+
58
+ `name`: name of the channel to subscribe to<br>
59
+ `handler`: method<br>
60
+ `context`: context<br>
61
+
62
+ ```js
63
+ pubsub.subscribe('event-name', (data) => {
64
+ console.log(data)
65
+ })
66
+ ```
67
+
68
+ #### unsubscribe
69
+
70
+ `name`: name of the channel to unsubscribe<br>
71
+ `handler`: method<br>
72
+ `context`: context<br>
73
+
74
+ ```js
75
+ pubsub.unsubscribe('event-name', (data) => {
76
+ console.log(data)
77
+ })
78
+ ```
79
+
80
+ #### publish
81
+
82
+ `name`: name of the channel to publish to<br>
83
+ `handler`: method<br>
84
+ `verbose`: boolean<br>
85
+
86
+ ```js
87
+ pubsub.publish('event-name', 'data')
88
+ ```
89
+
90
+ #### publish
91
+
92
+ `name`: name of the channel to publish to<br>
93
+ `handler`: method<br>
94
+
95
+ ```js
96
+ pubsub.publishVerbose('event-name', 'data')
97
+ ```
98
+
99
+ #### once
100
+
101
+ `name`: name of the channel to get the value from<br>
102
+
103
+ ```js
104
+ pubsub.getValue('event-name')
105
+ ```
106
+
107
+ #### once
108
+
109
+ `name`: name of the channel to publish to<br>
110
+
111
+ ```js
112
+ await pubsub.once('event-name')
113
+ ```
114
+
115
+ #### hasSubscribers
116
+
117
+ `name`: name of the channel to publish to<br>
118
+
119
+ ```js
120
+ pubsub.hasSubscribers('event-name')
121
+ ```
package/index.d.ts CHANGED
@@ -9,8 +9,10 @@ export default class LittlePubSub {
9
9
  constructor(verbose?: boolean);
10
10
  _handleContext(handler: Function, context?: Function): Function;
11
11
  hasSubscribers(event: string): boolean;
12
+ getValue(event: string): any;
12
13
  subscribe(event: string, handler: Function, context?: Function): void;
13
14
  unsubscribe(event: string, handler: Function, context?: Function): void;
14
- publish(event: string, value: string | number | boolean | object | Array<any>): void;
15
+ publish(event: string, value: string | number | boolean | object | Array<any>, verbose?: boolean): void;
16
+ publishVerbose(event: string, value: string | number | boolean | object | Array<any>): void;
15
17
  once(event: string): Promise<string | number | boolean | object | Array<any>>;
16
18
  }
package/index.js CHANGED
@@ -13,6 +13,11 @@ export default class LittlePubSub {
13
13
  hasSubscribers(event) {
14
14
  return this.subscribers[event] ? true : false;
15
15
  }
16
+ getValue(event) {
17
+ if (this.subscribers[event])
18
+ return this.subscribers[event].value;
19
+ return undefined;
20
+ }
16
21
  subscribe(event, handler, context) {
17
22
  if (!this.hasSubscribers(event))
18
23
  this.subscribers[event] = { handlers: [], value: undefined };
@@ -28,24 +33,28 @@ export default class LittlePubSub {
28
33
  if (this.subscribers[event].handlers.length === 0)
29
34
  delete this.subscribers[event];
30
35
  }
31
- publish(event, value) {
36
+ publish(event, value, verbose) {
32
37
  // always set value even when having no subscribers
33
38
  if (!this.hasSubscribers(event))
34
39
  this.subscribers[event] = {
35
40
  handlers: []
36
41
  };
37
42
  const oldValue = this.subscribers[event]?.value;
38
- this.subscribers[event].value = value;
39
- if (this.verbose || oldValue !== value)
43
+ if (this.verbose || verbose || oldValue !== value) {
44
+ this.subscribers[event].value = value;
40
45
  for (const handler of this.subscribers[event].handlers) {
41
46
  handler(value, oldValue);
42
47
  }
48
+ }
49
+ }
50
+ publishVerbose(event, value) {
51
+ this.publish(event, value, true);
43
52
  }
44
53
  once(event) {
45
54
  return new Promise((resolve) => {
46
55
  const cb = (value) => {
47
- this.unsubscribe(event, cb);
48
56
  resolve(value);
57
+ this.unsubscribe(event, cb);
49
58
  };
50
59
  this.subscribe(event, cb);
51
60
  });
package/package.json CHANGED
@@ -1,33 +1,33 @@
1
- {
2
- "name": "@vandeurenglenn/little-pubsub",
3
- "version": "1.4.6",
4
- "description": "Publish & Subscribe",
5
- "main": "./index.js",
6
- "types": "./index.d.ts",
7
- "exports": {
8
- ".": {
9
- "import": "./index.js",
10
- "types": "./index.d.ts"
11
- }
12
- },
13
- "repository": "https://github.com/vandeurenglenn/little-pubsub",
14
- "author": "vandeurenglenn <vandeurenglenn@gmail.com>",
15
- "license": "MIT",
16
- "type": "module",
17
- "private": false,
18
- "flat": true,
19
- "scripts": {
20
- "build": "npx tsc",
21
- "test": "node test.js"
22
- },
23
- "keywords": [
24
- "publish",
25
- "subscribe",
26
- "pubsub",
27
- "once"
28
- ],
29
- "devDependencies": {
30
- "tape": "^4.13.0",
31
- "typescript": "^5.1.6"
32
- }
33
- }
1
+ {
2
+ "name": "@vandeurenglenn/little-pubsub",
3
+ "version": "1.4.8",
4
+ "description": "Publish & Subscribe",
5
+ "main": "./index.js",
6
+ "types": "./index.d.ts",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./index.js",
10
+ "types": "./index.d.ts"
11
+ }
12
+ },
13
+ "repository": "https://github.com/vandeurenglenn/little-pubsub",
14
+ "author": "vandeurenglenn <vandeurenglenn@gmail.com>",
15
+ "license": "MIT",
16
+ "type": "module",
17
+ "private": false,
18
+ "flat": true,
19
+ "scripts": {
20
+ "build": "npx tsc",
21
+ "test": "node test.js"
22
+ },
23
+ "keywords": [
24
+ "publish",
25
+ "subscribe",
26
+ "pubsub",
27
+ "once"
28
+ ],
29
+ "devDependencies": {
30
+ "tape": "^5.8.1",
31
+ "typescript": "^5.5.3"
32
+ }
33
+ }
package/src/index.ts CHANGED
@@ -1,59 +1,83 @@
1
- export default class LittlePubSub {
2
- subscribers: {[index: string]: { value?: any, handlers?: Function[] }} = {}
3
- verbose: boolean
4
-
5
- constructor(verbose?: boolean) {
6
- this.verbose = verbose
7
- }
8
-
9
- _handleContext(handler: Function, context?: Function): Function {
10
- if (typeof context === 'undefined') {
11
- context = handler;
12
- }
13
- return context
14
- }
15
-
16
- hasSubscribers(event: string): boolean {
17
- return this.subscribers[event] ? true : false
18
- }
19
-
20
- subscribe(event: string, handler: Function, context?: Function): void {
21
- if (!this.hasSubscribers(event)) this.subscribers[event] = { handlers: [], value: undefined};
22
-
23
- context = this._handleContext(handler, context)
24
- this.subscribers[event].handlers.push(handler.bind(context))
25
- }
26
-
27
- unsubscribe(event: string, handler: Function, context?: Function): void {
28
- if (!this.hasSubscribers(event)) return
29
-
30
- context = this._handleContext(handler, context)
31
- const index = this.subscribers[event].handlers.indexOf(handler.bind(context));
32
- this.subscribers[event].handlers.splice(index);
33
- if (this.subscribers[event].handlers.length === 0) delete this.subscribers[event];
34
- }
35
-
36
- publish(event: string, value: string | number | boolean | object | Array<any>): void {
37
- // always set value even when having no subscribers
38
- if (!this.hasSubscribers(event)) this.subscribers[event] = {
39
- handlers: []
40
- }
41
- const oldValue = this.subscribers[event]?.value
42
- this.subscribers[event].value = value;
43
-
44
- if (this.verbose || oldValue !== value)
45
- for (const handler of this.subscribers[event].handlers) {
46
- handler(value, oldValue)
47
- }
48
- }
49
-
50
- once(event: string): Promise<string | number | boolean | object | Array<any>> {
51
- return new Promise((resolve) => {
52
- const cb = (value: string | number | boolean | object | Array<any>) => {
53
- this.unsubscribe(event, cb)
54
- resolve(value)
55
- }
56
- this.subscribe(event, cb)
57
- })
58
- }
59
- }
1
+ export default class LittlePubSub {
2
+ subscribers: { [index: string]: { value?: any; handlers?: Function[] } } = {}
3
+ verbose: boolean
4
+
5
+ constructor(verbose?: boolean) {
6
+ this.verbose = verbose
7
+ }
8
+
9
+ _handleContext(handler: Function, context?: Function): Function {
10
+ if (typeof context === 'undefined') {
11
+ context = handler
12
+ }
13
+ return context
14
+ }
15
+
16
+ hasSubscribers(event: string): boolean {
17
+ return this.subscribers[event] ? true : false
18
+ }
19
+
20
+ getValue(event: string): any {
21
+ if (this.subscribers[event]) return this.subscribers[event].value
22
+ return undefined
23
+ }
24
+
25
+ subscribe(event: string, handler: Function, context?: Function): void {
26
+ if (!this.hasSubscribers(event))
27
+ this.subscribers[event] = { handlers: [], value: undefined }
28
+
29
+ context = this._handleContext(handler, context)
30
+ this.subscribers[event].handlers.push(handler.bind(context))
31
+ }
32
+
33
+ unsubscribe(event: string, handler: Function, context?: Function): void {
34
+ if (!this.hasSubscribers(event)) return
35
+
36
+ context = this._handleContext(handler, context)
37
+ const index = this.subscribers[event].handlers.indexOf(
38
+ handler.bind(context)
39
+ )
40
+ this.subscribers[event].handlers.splice(index)
41
+ if (this.subscribers[event].handlers.length === 0)
42
+ delete this.subscribers[event]
43
+ }
44
+
45
+ publish(
46
+ event: string,
47
+ value: string | number | boolean | object | Array<any>,
48
+ verbose?: boolean
49
+ ): void {
50
+ // always set value even when having no subscribers
51
+ if (!this.hasSubscribers(event))
52
+ this.subscribers[event] = {
53
+ handlers: []
54
+ }
55
+ const oldValue = this.subscribers[event]?.value
56
+
57
+ if (this.verbose || verbose || oldValue !== value) {
58
+ this.subscribers[event].value = value
59
+ for (const handler of this.subscribers[event].handlers) {
60
+ handler(value, oldValue)
61
+ }
62
+ }
63
+ }
64
+
65
+ publishVerbose(
66
+ event: string,
67
+ value: string | number | boolean | object | Array<any>
68
+ ) {
69
+ this.publish(event, value, true)
70
+ }
71
+
72
+ once(
73
+ event: string
74
+ ): Promise<string | number | boolean | object | Array<any>> {
75
+ return new Promise((resolve) => {
76
+ const cb = (value: string | number | boolean | object | Array<any>) => {
77
+ resolve(value)
78
+ this.unsubscribe(event, cb)
79
+ }
80
+ this.subscribe(event, cb)
81
+ })
82
+ }
83
+ }
package/test.js CHANGED
@@ -1,38 +1,53 @@
1
- import test from 'tape'
2
- import PubSub from './index.js'
3
-
4
- test('pubsub is defined', tape => {
5
- tape.plan(1)
6
- const pubsub = new PubSub()
7
- tape.ok(typeof pubsub === 'object')
8
-
9
- test('pubsub subscribes & publishes', tape => {
10
- tape.plan(1)
11
- pubsub.subscribe('on', (value) => tape.ok(value))
12
- pubsub.publish('on', 5)
13
- })
14
-
15
- test('pubsub unsubscribes', tape => {
16
- tape.plan(1)
17
- pubsub.unsubscribe('on', (value) => tape.ok(value))
18
- tape.ok(Boolean(Object.keys(pubsub.subscribers).length === 0))
19
- })
20
-
21
- test('pubsub once', async (tape) => {
22
- tape.plan(1)
23
- setTimeout(() => pubsub.publish('on', true) ,1000)
24
- let value = await pubsub.once('on')
25
- tape.ok((value === true))
26
- })
27
-
28
- test('pubsub without subscribers', async (tape) => {
29
- tape.plan(1)
30
- try {
31
- pubsub.publish('on', true)
32
- tape.ok(true)
33
-
34
- } catch (error) {
35
- tape.ok(false)
36
- }
37
- })
38
- });
1
+ import test from 'tape'
2
+ import PubSub from './index.js'
3
+
4
+ test('pubsub is defined', (tape) => {
5
+ tape.plan(1)
6
+ const pubsub = new PubSub()
7
+ tape.ok(typeof pubsub === 'object')
8
+
9
+ test('pubsub subscribes & publishes & unsubscribes', (tape) => {
10
+ tape.plan(1)
11
+ pubsub.subscribe('on', (value) => {
12
+ tape.ok(value)
13
+ pubsub.unsubscribe('on', (value) => tape.ok(value))
14
+ })
15
+ pubsub.publish('on', 5)
16
+ })
17
+
18
+ test('pubsub subscribes & publishesVerbose', (tape) => {
19
+ tape.plan(2)
20
+ pubsub.subscribe('on', (value) => tape.ok(value))
21
+ pubsub.publish('on', 5)
22
+ pubsub.publishVerbose('on', 5)
23
+ })
24
+
25
+ test('pubsub getValue', (tape) => {
26
+ tape.plan(1)
27
+ let value = pubsub.getValue('on')
28
+ tape.ok(value === 5)
29
+ })
30
+
31
+ test('pubsub unsubscribes', (tape) => {
32
+ tape.plan(1)
33
+ pubsub.unsubscribe('on', (value) => tape.ok(value))
34
+ tape.ok(Boolean(Object.keys(pubsub.subscribers).length === 0))
35
+ })
36
+
37
+ test('pubsub once', async (tape) => {
38
+ tape.plan(1)
39
+ setTimeout(() => pubsub.publish('on', true), 1000)
40
+ let value = await pubsub.once('on')
41
+ tape.ok(value === true)
42
+ })
43
+
44
+ test('pubsub without subscribers', async (tape) => {
45
+ tape.plan(1)
46
+ try {
47
+ pubsub.publish('on', true)
48
+ tape.ok(true)
49
+ } catch (error) {
50
+ tape.ok(false)
51
+ }
52
+ })
53
+ })
package/tsconfig.json CHANGED
@@ -1,17 +1,14 @@
1
- {
2
- "compilerOptions": {
3
- "outDir": "./",
4
- "esModuleInterop": true,
5
- "allowSyntheticDefaultImports": true,
6
- "allowJs": false,
7
- "declaration": true,
8
- "target": "ES2022",
9
- "module": "es2022"
10
- },
11
- "include": [
12
- "./src/**/*"
13
- ],
14
- "exclude": [
15
- "node_modules"
16
- ]
17
- }
1
+ {
2
+ "compilerOptions": {
3
+ "outDir": "./",
4
+ "moduleResolution": "NodeNext",
5
+ "esModuleInterop": true,
6
+ "allowSyntheticDefaultImports": true,
7
+ "allowJs": false,
8
+ "declaration": true,
9
+ "target": "ES2022",
10
+ "module": "NodeNext"
11
+ },
12
+ "include": ["./src/**/*"],
13
+ "exclude": ["node_modules"]
14
+ }