@player-ui/pubsub-plugin 0.4.0-next.8 → 0.4.0-next.9

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/dist/index.cjs.js CHANGED
@@ -2,11 +2,99 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var pubsub = require('pubsub-js');
6
-
7
- function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
8
-
9
- var pubsub__default = /*#__PURE__*/_interopDefaultLegacy(pubsub);
5
+ function splitEvent(event) {
6
+ return event.split(".").reduce((prev, curr, index) => {
7
+ if (index === 0) {
8
+ return [curr];
9
+ }
10
+ return [...prev, `${prev[index - 1]}.${curr}`];
11
+ }, []);
12
+ }
13
+ let count = 1;
14
+ class TinyPubSub {
15
+ constructor() {
16
+ this.events = new Map();
17
+ this.tokens = new Map();
18
+ }
19
+ publish(event, ...args) {
20
+ if (typeof event !== "string") {
21
+ return;
22
+ }
23
+ if (event.includes(".")) {
24
+ const eventKeys = splitEvent(event);
25
+ eventKeys.forEach((key) => {
26
+ this.deliver(key, event, ...args);
27
+ });
28
+ } else {
29
+ this.deliver(event, event, ...args);
30
+ }
31
+ this.deliver("*", event, ...args);
32
+ }
33
+ subscribe(event, handler) {
34
+ const uuid = `uuid_${++count}`;
35
+ if (typeof event === "string") {
36
+ if (!this.events.has(event)) {
37
+ this.events.set(event, new Map());
38
+ }
39
+ const handlers = this.events.get(event);
40
+ handlers.set(uuid, handler);
41
+ this.tokens.set(uuid, event);
42
+ }
43
+ return uuid;
44
+ }
45
+ unsubscribe(value) {
46
+ if (typeof value === "string" && value.startsWith("uuid")) {
47
+ const path = this.tokens.get(value);
48
+ if (typeof path === "undefined") {
49
+ return;
50
+ }
51
+ const innerPath = this.events.get(path);
52
+ innerPath == null ? void 0 : innerPath.delete(value);
53
+ this.tokens.delete(value);
54
+ return;
55
+ }
56
+ if (typeof value === "string") {
57
+ for (const key of this.events.keys()) {
58
+ if (key.indexOf(value) === 0) {
59
+ const tokens = this.events.get(key);
60
+ if (tokens && tokens.size) {
61
+ for (const token of tokens.keys()) {
62
+ this.tokens.delete(token);
63
+ }
64
+ }
65
+ this.events.delete(key);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ count(event) {
71
+ let counter = 0;
72
+ if (typeof event === "undefined") {
73
+ for (const handlers2 of this.events.values()) {
74
+ counter += handlers2.size;
75
+ }
76
+ return counter;
77
+ }
78
+ const handlers = this.events.get(event);
79
+ if (handlers == null ? void 0 : handlers.size) {
80
+ return handlers.size;
81
+ }
82
+ return counter;
83
+ }
84
+ clear() {
85
+ this.events.clear();
86
+ this.tokens.clear();
87
+ }
88
+ deliver(path, event, ...args) {
89
+ const handlers = this.events.get(path);
90
+ if (handlers && handlers.size) {
91
+ for (const handler of handlers.values()) {
92
+ handler(event, ...args);
93
+ }
94
+ }
95
+ }
96
+ }
97
+ const pubsub = new TinyPubSub();
10
98
 
11
99
  const PubSubPluginSymbol = Symbol.for("PubSubPlugin");
12
100
 
@@ -19,26 +107,68 @@ const _PubSubPlugin = class {
19
107
  }
20
108
  apply(player) {
21
109
  player.hooks.expressionEvaluator.tap(this.name, (expEvaluator) => {
22
- expEvaluator.addExpressionFunction(this.expressionName, (_ctx, event, data) => {
23
- if (typeof event === "string") {
24
- this.publish(event, data);
25
- }
26
- });
110
+ const existingExpression = expEvaluator.operators.expressions.get(this.expressionName);
111
+ if (existingExpression) {
112
+ player.logger.warn(`[PubSubPlugin] expression ${this.expressionName} is already registered.`);
113
+ } else {
114
+ expEvaluator.addExpressionFunction(this.expressionName, (_ctx, event, ...args) => {
115
+ if (typeof event === "string") {
116
+ this.publish(event, ...args);
117
+ }
118
+ });
119
+ }
120
+ });
121
+ player.hooks.onEnd.tap(this.name, () => {
122
+ this.clear();
27
123
  });
28
124
  }
29
- publish(event, data) {
30
- pubsub__default["default"].publishSync(event, data);
125
+ publish(event, ...args) {
126
+ pubsub.publish(event, ...args);
31
127
  }
32
128
  subscribe(event, handler) {
33
- return pubsub__default["default"].subscribe(event, handler);
129
+ return pubsub.subscribe(event, handler);
34
130
  }
35
131
  unsubscribe(token) {
36
- pubsub__default["default"].unsubscribe(token);
132
+ pubsub.unsubscribe(token);
133
+ }
134
+ clear() {
135
+ pubsub.clear();
37
136
  }
38
137
  };
39
138
  let PubSubPlugin = _PubSubPlugin;
40
139
  PubSubPlugin.Symbol = PubSubPluginSymbol;
41
140
 
141
+ function getPubSubPlugin(player) {
142
+ const existing = player.findPlugin(PubSubPluginSymbol);
143
+ const plugin = existing || new PubSubPlugin();
144
+ if (!existing) {
145
+ player.registerPlugin(plugin);
146
+ }
147
+ return plugin;
148
+ }
149
+
150
+ class PubSubHandlerPlugin {
151
+ constructor(subscriptions) {
152
+ this.name = "pubsub-handler";
153
+ this.subscriptions = subscriptions;
154
+ }
155
+ apply(player) {
156
+ const pubsub = getPubSubPlugin(player);
157
+ player.hooks.onStart.tap(this.name, () => {
158
+ this.subscriptions.forEach((handler, key) => {
159
+ pubsub.subscribe(key, (_, ...args) => {
160
+ const state = player.getState();
161
+ if (state.status === "in-progress") {
162
+ return handler(state, ...args);
163
+ }
164
+ player.logger.info(`[PubSubHandlerPlugin] subscriber for ${key} was called when player was not in-progress`);
165
+ });
166
+ });
167
+ });
168
+ }
169
+ }
170
+
171
+ exports.PubSubHandlerPlugin = PubSubHandlerPlugin;
42
172
  exports.PubSubPlugin = PubSubPlugin;
43
173
  exports.PubSubPluginSymbol = PubSubPluginSymbol;
44
174
  //# sourceMappingURL=index.cjs.js.map
package/dist/index.d.ts CHANGED
@@ -1,11 +1,17 @@
1
- import { PlayerPlugin, Player } from '@player-ui/player';
1
+ import { PlayerPlugin, Player, InProgressState } from '@player-ui/player';
2
+
3
+ /**
4
+ * Based off the pubsub-js library and rewritten to match the same used APIs but modified so that
5
+ * multiple arguments could be passed into the publish and subscription handlers.
6
+ */
7
+ declare type SubscribeHandler<T extends string, A extends unknown[]> = (type: T, ...args: A) => void;
2
8
 
3
9
  interface PubSubConfig {
4
10
  /** A custom expression name to register */
5
11
  expressionName: string;
6
12
  }
7
13
  /**
8
- * The PubSubPlugin is a great way to enable your Content content to publish events back to your app
14
+ * The PubSubPlugin is a great way to enable your FRF content to publish events back to your app
9
15
  * It injects a publish() function into the expression language, and will forward all events back to any subscribers.
10
16
  *
11
17
  * Published/Subscribed events support a hierarchy:
@@ -26,7 +32,7 @@ declare class PubSubPlugin implements PlayerPlugin {
26
32
  * @param event - The name of the event to publish. Can take sub-topics like: foo.bar
27
33
  * @param data - Any additional data to attach to the event
28
34
  */
29
- publish(event: string, data: unknown): void;
35
+ publish(event: string, ...args: unknown[]): void;
30
36
  /**
31
37
  * Subscribe to an event with the given name. The handler will get called for any published event
32
38
  *
@@ -34,15 +40,31 @@ declare class PubSubPlugin implements PlayerPlugin {
34
40
  * @param handler - A function to be called when the event is triggered
35
41
  * @returns A token to be used to unsubscribe from the event
36
42
  */
37
- subscribe(event: string, handler: (e: string, data: unknown) => void): string;
43
+ subscribe<T extends string, A extends unknown[]>(event: T, handler: SubscribeHandler<T, A>): string;
38
44
  /**
39
45
  * Remove any subscriptions using the given token
40
46
  *
41
47
  * @param token - A token from a `subscribe` call
42
48
  */
43
49
  unsubscribe(token: string): void;
50
+ /**
51
+ * Remove all subscriptions
52
+ */
53
+ clear(): void;
44
54
  }
45
55
 
46
56
  declare const PubSubPluginSymbol: unique symbol;
47
57
 
48
- export { PubSubConfig, PubSubPlugin, PubSubPluginSymbol };
58
+ declare type PubSubHandler<T extends unknown[]> = (context: InProgressState, ...args: T) => void;
59
+ declare type SubscriptionMap = Map<string, PubSubHandler<any>>;
60
+ /**
61
+ * Plugin to easily add subscribers to the PubSubPlugin
62
+ */
63
+ declare class PubSubHandlerPlugin implements PlayerPlugin {
64
+ name: string;
65
+ private subscriptions;
66
+ constructor(subscriptions: SubscriptionMap);
67
+ apply(player: Player): void;
68
+ }
69
+
70
+ export { PubSubConfig, PubSubHandler, PubSubHandlerPlugin, PubSubPlugin, PubSubPluginSymbol, SubscriptionMap };
package/dist/index.esm.js CHANGED
@@ -1,4 +1,96 @@
1
- import pubsub from 'pubsub-js';
1
+ function splitEvent(event) {
2
+ return event.split(".").reduce((prev, curr, index) => {
3
+ if (index === 0) {
4
+ return [curr];
5
+ }
6
+ return [...prev, `${prev[index - 1]}.${curr}`];
7
+ }, []);
8
+ }
9
+ let count = 1;
10
+ class TinyPubSub {
11
+ constructor() {
12
+ this.events = new Map();
13
+ this.tokens = new Map();
14
+ }
15
+ publish(event, ...args) {
16
+ if (typeof event !== "string") {
17
+ return;
18
+ }
19
+ if (event.includes(".")) {
20
+ const eventKeys = splitEvent(event);
21
+ eventKeys.forEach((key) => {
22
+ this.deliver(key, event, ...args);
23
+ });
24
+ } else {
25
+ this.deliver(event, event, ...args);
26
+ }
27
+ this.deliver("*", event, ...args);
28
+ }
29
+ subscribe(event, handler) {
30
+ const uuid = `uuid_${++count}`;
31
+ if (typeof event === "string") {
32
+ if (!this.events.has(event)) {
33
+ this.events.set(event, new Map());
34
+ }
35
+ const handlers = this.events.get(event);
36
+ handlers.set(uuid, handler);
37
+ this.tokens.set(uuid, event);
38
+ }
39
+ return uuid;
40
+ }
41
+ unsubscribe(value) {
42
+ if (typeof value === "string" && value.startsWith("uuid")) {
43
+ const path = this.tokens.get(value);
44
+ if (typeof path === "undefined") {
45
+ return;
46
+ }
47
+ const innerPath = this.events.get(path);
48
+ innerPath == null ? void 0 : innerPath.delete(value);
49
+ this.tokens.delete(value);
50
+ return;
51
+ }
52
+ if (typeof value === "string") {
53
+ for (const key of this.events.keys()) {
54
+ if (key.indexOf(value) === 0) {
55
+ const tokens = this.events.get(key);
56
+ if (tokens && tokens.size) {
57
+ for (const token of tokens.keys()) {
58
+ this.tokens.delete(token);
59
+ }
60
+ }
61
+ this.events.delete(key);
62
+ }
63
+ }
64
+ }
65
+ }
66
+ count(event) {
67
+ let counter = 0;
68
+ if (typeof event === "undefined") {
69
+ for (const handlers2 of this.events.values()) {
70
+ counter += handlers2.size;
71
+ }
72
+ return counter;
73
+ }
74
+ const handlers = this.events.get(event);
75
+ if (handlers == null ? void 0 : handlers.size) {
76
+ return handlers.size;
77
+ }
78
+ return counter;
79
+ }
80
+ clear() {
81
+ this.events.clear();
82
+ this.tokens.clear();
83
+ }
84
+ deliver(path, event, ...args) {
85
+ const handlers = this.events.get(path);
86
+ if (handlers && handlers.size) {
87
+ for (const handler of handlers.values()) {
88
+ handler(event, ...args);
89
+ }
90
+ }
91
+ }
92
+ }
93
+ const pubsub = new TinyPubSub();
2
94
 
3
95
  const PubSubPluginSymbol = Symbol.for("PubSubPlugin");
4
96
 
@@ -11,15 +103,23 @@ const _PubSubPlugin = class {
11
103
  }
12
104
  apply(player) {
13
105
  player.hooks.expressionEvaluator.tap(this.name, (expEvaluator) => {
14
- expEvaluator.addExpressionFunction(this.expressionName, (_ctx, event, data) => {
15
- if (typeof event === "string") {
16
- this.publish(event, data);
17
- }
18
- });
106
+ const existingExpression = expEvaluator.operators.expressions.get(this.expressionName);
107
+ if (existingExpression) {
108
+ player.logger.warn(`[PubSubPlugin] expression ${this.expressionName} is already registered.`);
109
+ } else {
110
+ expEvaluator.addExpressionFunction(this.expressionName, (_ctx, event, ...args) => {
111
+ if (typeof event === "string") {
112
+ this.publish(event, ...args);
113
+ }
114
+ });
115
+ }
116
+ });
117
+ player.hooks.onEnd.tap(this.name, () => {
118
+ this.clear();
19
119
  });
20
120
  }
21
- publish(event, data) {
22
- pubsub.publishSync(event, data);
121
+ publish(event, ...args) {
122
+ pubsub.publish(event, ...args);
23
123
  }
24
124
  subscribe(event, handler) {
25
125
  return pubsub.subscribe(event, handler);
@@ -27,9 +127,42 @@ const _PubSubPlugin = class {
27
127
  unsubscribe(token) {
28
128
  pubsub.unsubscribe(token);
29
129
  }
130
+ clear() {
131
+ pubsub.clear();
132
+ }
30
133
  };
31
134
  let PubSubPlugin = _PubSubPlugin;
32
135
  PubSubPlugin.Symbol = PubSubPluginSymbol;
33
136
 
34
- export { PubSubPlugin, PubSubPluginSymbol };
137
+ function getPubSubPlugin(player) {
138
+ const existing = player.findPlugin(PubSubPluginSymbol);
139
+ const plugin = existing || new PubSubPlugin();
140
+ if (!existing) {
141
+ player.registerPlugin(plugin);
142
+ }
143
+ return plugin;
144
+ }
145
+
146
+ class PubSubHandlerPlugin {
147
+ constructor(subscriptions) {
148
+ this.name = "pubsub-handler";
149
+ this.subscriptions = subscriptions;
150
+ }
151
+ apply(player) {
152
+ const pubsub = getPubSubPlugin(player);
153
+ player.hooks.onStart.tap(this.name, () => {
154
+ this.subscriptions.forEach((handler, key) => {
155
+ pubsub.subscribe(key, (_, ...args) => {
156
+ const state = player.getState();
157
+ if (state.status === "in-progress") {
158
+ return handler(state, ...args);
159
+ }
160
+ player.logger.info(`[PubSubHandlerPlugin] subscriber for ${key} was called when player was not in-progress`);
161
+ });
162
+ });
163
+ });
164
+ }
165
+ }
166
+
167
+ export { PubSubHandlerPlugin, PubSubPlugin, PubSubPluginSymbol };
35
168
  //# sourceMappingURL=index.esm.js.map