@fluid-experimental/data-objects 1.1.0-76254 → 1.2.0-78837
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/signalManager/signalManager.d.ts +1 -32
- package/dist/signalManager/signalManager.d.ts.map +1 -1
- package/dist/signalManager/signalManager.js +0 -26
- package/dist/signalManager/signalManager.js.map +1 -1
- package/lib/signalManager/signalManager.d.ts +1 -32
- package/lib/signalManager/signalManager.d.ts.map +1 -1
- package/lib/signalManager/signalManager.js +0 -26
- package/lib/signalManager/signalManager.js.map +1 -1
- package/package.json +6 -6
- package/src/signalManager/README.md +55 -0
- package/src/signalManager/signalManager.ts +1 -77
|
@@ -31,37 +31,13 @@ export interface ISignaler {
|
|
|
31
31
|
* @param listener - The callback signal handler to remove
|
|
32
32
|
* @returns This ISignaler
|
|
33
33
|
*/
|
|
34
|
-
offSignal(signalName: string, listener: SignalListener
|
|
34
|
+
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
35
35
|
/**
|
|
36
36
|
* Send a signal with payload to its connected listeners.
|
|
37
37
|
* @param signalName - The name of the signal
|
|
38
38
|
* @param payload - The data to send with the signal
|
|
39
39
|
*/
|
|
40
40
|
submitSignal(signalName: string, payload?: Jsonable): any;
|
|
41
|
-
/**
|
|
42
|
-
* Adds a listener for a broadcast request. The listener is called when a client calls
|
|
43
|
-
* `requestBroadcast` for that signal. It behaves in the same way as EventEmitter's `on`
|
|
44
|
-
* method regarding multiple registrations, callback order, etc.
|
|
45
|
-
* @param signalName - The signal for which broadcast is requested
|
|
46
|
-
* @param listener - The callback for the broadcast request to add
|
|
47
|
-
* @returns This ISignaler
|
|
48
|
-
*/
|
|
49
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
50
|
-
/**
|
|
51
|
-
* Remove a listener for a broadcast request. It behaves in the same way as EventEmitter's
|
|
52
|
-
* `off` method regarding multiple registrations, removal order, etc.
|
|
53
|
-
* @param signalName - The signal for which broadcast is requested
|
|
54
|
-
* @param listener - The callback for the broadcast request to remove
|
|
55
|
-
* @returns This ISignaler
|
|
56
|
-
*/
|
|
57
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
58
|
-
/**
|
|
59
|
-
* Request broadcast of a signal from other connected clients. Other clients must have
|
|
60
|
-
* registered to respond to broadcast requests using the `onBroadcastRequested` method.
|
|
61
|
-
* @param signalName - The signal for which broadcast is requested
|
|
62
|
-
* @param payload - A payload to send with the broadcast request
|
|
63
|
-
*/
|
|
64
|
-
requestBroadcast(signalName: string, payload?: Jsonable): any;
|
|
65
41
|
}
|
|
66
42
|
/**
|
|
67
43
|
* Duck type of something that provides the expected signalling functionality:
|
|
@@ -100,13 +76,9 @@ export declare class Signaler extends TypedEventEmitter<IErrorEvent> implements
|
|
|
100
76
|
*/
|
|
101
77
|
managerId?: string);
|
|
102
78
|
private getManagerSignalName;
|
|
103
|
-
private getBroadcastSignalName;
|
|
104
79
|
onSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
105
80
|
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
106
81
|
submitSignal(signalName: string, payload?: Jsonable): void;
|
|
107
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
108
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
109
|
-
requestBroadcast(signalName: string, payload?: Jsonable): void;
|
|
110
82
|
}
|
|
111
83
|
/**
|
|
112
84
|
* Note: currently experimental and under development
|
|
@@ -128,8 +100,5 @@ export declare class SignalManager extends DataObject<{
|
|
|
128
100
|
onSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
129
101
|
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
130
102
|
submitSignal(signalName: string, payload?: Jsonable): void;
|
|
131
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
132
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
133
|
-
requestBroadcast(signalName: string, payload?: Jsonable): void;
|
|
134
103
|
}
|
|
135
104
|
//# sourceMappingURL=signalManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signalManager.d.ts","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAM5E,oBAAY,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE3F;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACjE;;;;;;MAME;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,
|
|
1
|
+
{"version":3,"file":"signalManager.d.ts","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAM5E,oBAAY,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE3F;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACjE;;;;;;MAME;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACnE;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,OAAE;CACxD;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,OAAE;IACxF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,qBAAa,QAAS,SAAQ,iBAAiB,CAAC,WAAW,CAAE,YAAW,SAAS;IAMzE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAE9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;;IAG3C;;OAEG;IACc,QAAQ,EAAE,gBAAgB;IAC3C;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM;IAkBtB,OAAO,CAAC,oBAAoB;IAMrB,QAAQ,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAML,SAAS,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAML,YAAY,CACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,QAAQ;CAOzB;AAED;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,UAAU,CAAC;IAAE,MAAM,EAAE,WAAW,CAAC;CAAE,CAAE,YAAW,YAAY,EAAE,SAAS;IACtG,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,KAAK,OAAO,GAGlB;IAED,WAAkB,IAAI,WAA8C;IAEpE,gBAAuB,OAAO;gBATsB,WAAW;OAc7D;cAEc,cAAc;IASvB,QAAQ,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAKL,SAAS,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAKL,YAAY,CACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,QAAQ;CAIzB"}
|
|
@@ -46,9 +46,6 @@ export class Signaler extends TypedEventEmitter {
|
|
|
46
46
|
getManagerSignalName(signalName) {
|
|
47
47
|
return this.managerId ? `${signalName}${this.managerId}` : signalName;
|
|
48
48
|
}
|
|
49
|
-
getBroadcastSignalName(signalName) {
|
|
50
|
-
return `${signalName}#req`;
|
|
51
|
-
}
|
|
52
49
|
// ISignaler methods
|
|
53
50
|
onSignal(signalName, listener) {
|
|
54
51
|
const managerSignalName = this.getManagerSignalName(signalName);
|
|
@@ -66,18 +63,6 @@ export class Signaler extends TypedEventEmitter {
|
|
|
66
63
|
this.signaler.submitSignal(managerSignalName, payload);
|
|
67
64
|
}
|
|
68
65
|
}
|
|
69
|
-
onBroadcastRequested(signalName, listener) {
|
|
70
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
71
|
-
return this.onSignal(broadcastSignalName, listener);
|
|
72
|
-
}
|
|
73
|
-
offBroadcastRequested(signalName, listener) {
|
|
74
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
75
|
-
return this.offSignal(broadcastSignalName, listener);
|
|
76
|
-
}
|
|
77
|
-
requestBroadcast(signalName, payload) {
|
|
78
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
79
|
-
this.submitSignal(broadcastSignalName, payload);
|
|
80
|
-
}
|
|
81
66
|
}
|
|
82
67
|
/**
|
|
83
68
|
* Note: currently experimental and under development
|
|
@@ -110,17 +95,6 @@ export class SignalManager extends DataObject {
|
|
|
110
95
|
submitSignal(signalName, payload) {
|
|
111
96
|
this.manager.submitSignal(signalName, payload);
|
|
112
97
|
}
|
|
113
|
-
onBroadcastRequested(signalName, listener) {
|
|
114
|
-
this.manager.onBroadcastRequested(signalName, listener);
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
offBroadcastRequested(signalName, listener) {
|
|
118
|
-
this.manager.offBroadcastRequested(signalName, listener);
|
|
119
|
-
return this;
|
|
120
|
-
}
|
|
121
|
-
requestBroadcast(signalName, payload) {
|
|
122
|
-
this.manager.requestBroadcast(signalName, payload);
|
|
123
|
-
}
|
|
124
98
|
}
|
|
125
99
|
SignalManager.factory = new DataObjectFactory(SignalManager.Name, SignalManager, [], {});
|
|
126
100
|
//# sourceMappingURL=signalManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signalManager.js","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AAEzE,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AA2EzE;;;;;;;;GAQG;AACH,MAAM,OAAO,QAAS,SAAQ,iBAA8B;IAKxD;IACI;;OAEG;IACc,QAA0B;IAC3C;;;;OAIG;IACH,SAAkB;QAElB,KAAK,EAAE,CAAC;QARS,aAAQ,GAAR,QAAQ,CAAkB;QAR9B,YAAO,GAAG,IAAI,YAAY,EAAE,CAAC;QAiB1C,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,SAAS,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;QACzD,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,EAAE,CAAC,OAA8B,EAAE,KAAc,EAAE,EAAE;YAC1E,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;YAClC,6EAA6E;YAC7E,8EAA8E;YAC9E,0CAA0C;YAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,IAAI,QAAQ,KAAK,IAAI,EAAE;gBAC9C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;aACrE;QACL,CAAC,CAAC,CAAC;IACP,CAAC;IAEO,oBAAoB,CAAC,UAAkB;QAC3C,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC;IAC1E,CAAC;IAEO,sBAAsB,CAAC,UAAkB;QAC7C,OAAO,GAAG,UAAU,MAAM,CAAC;IAC/B,CAAC;IAED,oBAAoB;IAEb,QAAQ,CACX,UAAkB,EAClB,QAAwB;QAExB,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,SAAS,CACZ,UAAkB,EAClB,QAAwB;QAExB,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,QAAQ,CAAC,CAAC;QAC9C,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,YAAY,CACf,UAAkB,EAClB,OAAkB;QAElB,MAAM,iBAAiB,GAAG,IAAI,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC;QAChE,IAAI,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE;YACzB,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;SAC1D;IACL,CAAC;IAEM,oBAAoB,CACvB,UAAkB,EAClB,QAAwB;QAExB,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,QAAQ,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IACxD,CAAC;IAEM,qBAAqB,CACxB,UAAkB,EAClB,QAAwB;QAExB,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACpE,OAAO,IAAI,CAAC,SAAS,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAC;IACzD,CAAC;IAEM,gBAAgB,CACnB,UAAkB,EAClB,OAAkB;QAElB,MAAM,mBAAmB,GAAG,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACpE,IAAI,CAAC,YAAY,CAAC,mBAAmB,EAAE,OAAO,CAAC,CAAC;IACpD,CAAC;CACJ;AAED;;;;;;GAMG;AACH,MAAM,OAAO,aAAc,SAAQ,UAAoC;IAEnE,IAAY,OAAO;QACf,MAAM,CAAC,IAAI,CAAC,QAAQ,KAAK,SAAS,EAAE,KAAK,CAAC,2CAA2C,CAAC,CAAC;QACvF,OAAO,IAAI,CAAC,QAAQ,CAAC;IACzB,CAAC;IAEM,MAAM,KAAK,IAAI,KAAK,OAAO,+BAA+B,CAAC,CAAC,CAAC;IAS1D,KAAK,CAAC,cAAc;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YAC/B,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QAC9B,CAAC,CAAC,CAAC;IACP,CAAC;IAED,qDAAqD;IAE9C,QAAQ,CACX,UAAkB,EAClB,QAAwB;QAExB,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC5C,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,SAAS,CACZ,UAAkB,EAClB,QAAwB;QAExB,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC7C,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,YAAY,CACf,UAAkB,EAClB,OAAkB;QAElB,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC;IAEM,oBAAoB,CACvB,UAAkB,EAClB,QAAwB;QAExB,IAAI,CAAC,OAAO,CAAC,oBAAoB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACxD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,qBAAqB,CACxB,UAAkB,EAClB,QAAwB;QAExB,IAAI,CAAC,OAAO,CAAC,qBAAqB,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QACzD,OAAO,IAAI,CAAC;IAChB,CAAC;IAEM,gBAAgB,CACnB,UAAkB,EAClB,OAAkB;QAElB,IAAI,CAAC,OAAO,CAAC,gBAAgB,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvD,CAAC;;AA5DsB,qBAAO,GAAG,IAAI,iBAAiB,CAClD,aAAa,CAAC,IAAI,EAClB,aAAa,EACb,EAAE,EACF,EAAE,CACL,CAAC","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { DataObject, DataObjectFactory } from \"@fluidframework/aqueduct\";\nimport { IErrorEvent } from \"@fluidframework/common-definitions\";\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { Jsonable } from \"@fluidframework/datastore-definitions\";\nimport { IInboundSignalMessage } from \"@fluidframework/runtime-definitions\";\n\n// TODO:\n// add way to mark with current sequence number for ordering signals relative to ops\n// throttling and batching\n\nexport type SignalListener = (clientId: string, local: boolean, payload: Jsonable) => void;\n\n/**\n * ISignaler defines an interface for working with signals that is similar to the more common\n * eventing patterns of EventEmitter. In addition to sending and responding to signals, it\n * provides explicit methods around signal requests to other connected clients.\n */\nexport interface ISignaler {\n /**\n * Adds a listener for the specified signal. It behaves in the same way as EventEmitter's `on`\n * method regarding multiple registrations, callback order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to add\n * @returns This ISignaler\n */\n onSignal(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Remove a listener for the specified signal. It behaves in the same way as EventEmitter's\n * `off` method regarding multiple registrations, removal order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to remove\n * @returns This ISignaler\n */\n offSignal(signalName: string, listener: SignalListener | ((message: any) => void)): ISignaler;\n /**\n * Send a signal with payload to its connected listeners.\n * @param signalName - The name of the signal\n * @param payload - The data to send with the signal\n */\n submitSignal(signalName: string, payload?: Jsonable);\n\n /**\n * Adds a listener for a broadcast request. The listener is called when a client calls\n * `requestBroadcast` for that signal. It behaves in the same way as EventEmitter's `on`\n * method regarding multiple registrations, callback order, etc.\n * @param signalName - The signal for which broadcast is requested\n * @param listener - The callback for the broadcast request to add\n * @returns This ISignaler\n */\n onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Remove a listener for a broadcast request. It behaves in the same way as EventEmitter's\n * `off` method regarding multiple registrations, removal order, etc.\n * @param signalName - The signal for which broadcast is requested\n * @param listener - The callback for the broadcast request to remove\n * @returns This ISignaler\n */\n offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Request broadcast of a signal from other connected clients. Other clients must have\n * registered to respond to broadcast requests using the `onBroadcastRequested` method.\n * @param signalName - The signal for which broadcast is requested\n * @param payload - A payload to send with the broadcast request\n */\n requestBroadcast(signalName: string, payload?: Jsonable);\n}\n\n/**\n * Duck type of something that provides the expected signalling functionality:\n * A way to verify we can signal, a way to send a signal, and a way to listen for incoming signals\n */\nexport interface IRuntimeSignaler {\n connected: boolean;\n on(event: \"signal\", listener: (message: IInboundSignalMessage, local: boolean) => void);\n submitSignal(type: string, content: any): void;\n}\n\n/**\n * Note: currently experimental and under development\n *\n * Helper class to assist common scenarios around working with signals. Signaler wraps a runtime\n * object with signaling functionality (e.g. ContainerRuntime or FluidDataStoreRuntime) and can\n * then be used in place of the original signaler. It uses a separate internal EventEmitter to\n * manage callbacks, and thus will reflect that behavior with regards to callback registration and\n * deregistration.\n */\nexport class Signaler extends TypedEventEmitter<IErrorEvent> implements ISignaler {\n private readonly emitter = new EventEmitter();\n\n private readonly managerId: string | undefined;\n\n constructor(\n /**\n * Object to wrap that can submit and listen to signals\n */\n private readonly signaler: IRuntimeSignaler,\n /**\n * Optional id to assign to this manager that will be attached to\n * signal names. Useful to avoid collisions if there are multiple\n * signal users at the Container level\n */\n managerId?: string,\n ) {\n super();\n this.emitter.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n this.managerId = managerId ? `#${managerId}` : undefined;\n this.signaler.on(\"signal\", (message: IInboundSignalMessage, local: boolean) => {\n const clientId = message.clientId;\n // Only call listeners when the runtime is connected and if the signal has an\n // identifiable sender clientId. The listener is responsible for deciding how\n // it wants to handle local/remote signals\n if (this.signaler.connected && clientId !== null) {\n this.emitter.emit(message.type, clientId, local, message.content);\n }\n });\n }\n\n private getManagerSignalName(signalName: string): string {\n return this.managerId ? `${signalName}${this.managerId}` : signalName;\n }\n\n private getBroadcastSignalName(signalName: string): string {\n return `${signalName}#req`;\n }\n\n // ISignaler methods\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.on(managerSignalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.off(managerSignalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n const managerSignalName = this.getManagerSignalName(signalName);\n if (this.signaler.connected) {\n this.signaler.submitSignal(managerSignalName, payload);\n }\n }\n\n public onBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const broadcastSignalName = this.getBroadcastSignalName(signalName);\n return this.onSignal(broadcastSignalName, listener);\n }\n\n public offBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const broadcastSignalName = this.getBroadcastSignalName(signalName);\n return this.offSignal(broadcastSignalName, listener);\n }\n\n public requestBroadcast(\n signalName: string,\n payload?: Jsonable,\n ) {\n const broadcastSignalName = this.getBroadcastSignalName(signalName);\n this.submitSignal(broadcastSignalName, payload);\n }\n}\n\n/**\n * Note: currently experimental and under development\n *\n * DataObject implementation of ISignaler for fluid-static plug-and-play. Allows fluid-static\n * users to get an ISignaler without a custom DO. Where possible, consumers should instead\n * create a Signaler themselves instead of using the DO wrapper to avoid the DO overhead.\n */\nexport class SignalManager extends DataObject<{ Events: IErrorEvent; }> implements EventEmitter, ISignaler {\n private _manager: Signaler | undefined;\n private get manager(): Signaler {\n assert(this._manager !== undefined, 0x24b /* \"internal signaler should be defined\" */);\n return this._manager;\n }\n\n public static get Name() { return \"@fluid-example/signal-manager\"; }\n\n public static readonly factory = new DataObjectFactory(\n SignalManager.Name,\n SignalManager,\n [],\n {},\n );\n\n protected async hasInitialized() {\n this._manager = new Signaler(this.runtime);\n this.manager.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n }\n\n // ISignaler methods Note these are all passthroughs\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.onSignal(signalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.offSignal(signalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n this.manager.submitSignal(signalName, payload);\n }\n\n public onBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.onBroadcastRequested(signalName, listener);\n return this;\n }\n\n public offBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.offBroadcastRequested(signalName, listener);\n return this;\n }\n\n public requestBroadcast(\n signalName: string,\n payload?: Jsonable,\n ) {\n this.manager.requestBroadcast(signalName, payload);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"signalManager.js","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { DataObject, DataObjectFactory } from \"@fluidframework/aqueduct\";\nimport { IErrorEvent } from \"@fluidframework/common-definitions\";\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { Jsonable } from \"@fluidframework/datastore-definitions\";\nimport { IInboundSignalMessage } from \"@fluidframework/runtime-definitions\";\n\n// TODO:\n// add way to mark with current sequence number for ordering signals relative to ops\n// throttling and batching\n\nexport type SignalListener = (clientId: string, local: boolean, payload: Jsonable) => void;\n\n/**\n * ISignaler defines an interface for working with signals that is similar to the more common\n * eventing patterns of EventEmitter. In addition to sending and responding to signals, it\n * provides explicit methods around signal requests to other connected clients.\n */\nexport interface ISignaler {\n /**\n * Adds a listener for the specified signal. It behaves in the same way as EventEmitter's `on`\n * method regarding multiple registrations, callback order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to add\n * @returns This ISignaler\n */\n onSignal(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Remove a listener for the specified signal. It behaves in the same way as EventEmitter's\n * `off` method regarding multiple registrations, removal order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to remove\n * @returns This ISignaler\n */\n offSignal(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Send a signal with payload to its connected listeners.\n * @param signalName - The name of the signal\n * @param payload - The data to send with the signal\n */\n submitSignal(signalName: string, payload?: Jsonable);\n}\n\n/**\n * Duck type of something that provides the expected signalling functionality:\n * A way to verify we can signal, a way to send a signal, and a way to listen for incoming signals\n */\nexport interface IRuntimeSignaler {\n connected: boolean;\n on(event: \"signal\", listener: (message: IInboundSignalMessage, local: boolean) => void);\n submitSignal(type: string, content: any): void;\n}\n\n/**\n * Note: currently experimental and under development\n *\n * Helper class to assist common scenarios around working with signals. Signaler wraps a runtime\n * object with signaling functionality (e.g. ContainerRuntime or FluidDataStoreRuntime) and can\n * then be used in place of the original signaler. It uses a separate internal EventEmitter to\n * manage callbacks, and thus will reflect that behavior with regards to callback registration and\n * deregistration.\n */\nexport class Signaler extends TypedEventEmitter<IErrorEvent> implements ISignaler {\n private readonly emitter = new EventEmitter();\n\n private readonly managerId: string | undefined;\n\n constructor(\n /**\n * Object to wrap that can submit and listen to signals\n */\n private readonly signaler: IRuntimeSignaler,\n /**\n * Optional id to assign to this manager that will be attached to\n * signal names. Useful to avoid collisions if there are multiple\n * signal users at the Container level\n */\n managerId?: string,\n ) {\n super();\n this.emitter.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n this.managerId = managerId ? `#${managerId}` : undefined;\n this.signaler.on(\"signal\", (message: IInboundSignalMessage, local: boolean) => {\n const clientId = message.clientId;\n // Only call listeners when the runtime is connected and if the signal has an\n // identifiable sender clientId. The listener is responsible for deciding how\n // it wants to handle local/remote signals\n if (this.signaler.connected && clientId !== null) {\n this.emitter.emit(message.type, clientId, local, message.content);\n }\n });\n }\n\n private getManagerSignalName(signalName: string): string {\n return this.managerId ? `${signalName}${this.managerId}` : signalName;\n }\n\n // ISignaler methods\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.on(managerSignalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.off(managerSignalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n const managerSignalName = this.getManagerSignalName(signalName);\n if (this.signaler.connected) {\n this.signaler.submitSignal(managerSignalName, payload);\n }\n }\n}\n\n/**\n * Note: currently experimental and under development\n *\n * DataObject implementation of ISignaler for fluid-static plug-and-play. Allows fluid-static\n * users to get an ISignaler without a custom DO. Where possible, consumers should instead\n * create a Signaler themselves instead of using the DO wrapper to avoid the DO overhead.\n */\nexport class SignalManager extends DataObject<{ Events: IErrorEvent; }> implements EventEmitter, ISignaler {\n private _manager: Signaler | undefined;\n private get manager(): Signaler {\n assert(this._manager !== undefined, 0x24b /* \"internal signaler should be defined\" */);\n return this._manager;\n }\n\n public static get Name() { return \"@fluid-example/signal-manager\"; }\n\n public static readonly factory = new DataObjectFactory(\n SignalManager.Name,\n SignalManager,\n [],\n {},\n );\n\n protected async hasInitialized() {\n this._manager = new Signaler(this.runtime);\n this.manager.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n }\n\n // ISignaler methods Note these are all passthroughs\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.onSignal(signalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.offSignal(signalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n this.manager.submitSignal(signalName, payload);\n }\n}\n"]}
|
|
@@ -31,37 +31,13 @@ export interface ISignaler {
|
|
|
31
31
|
* @param listener - The callback signal handler to remove
|
|
32
32
|
* @returns This ISignaler
|
|
33
33
|
*/
|
|
34
|
-
offSignal(signalName: string, listener: SignalListener
|
|
34
|
+
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
35
35
|
/**
|
|
36
36
|
* Send a signal with payload to its connected listeners.
|
|
37
37
|
* @param signalName - The name of the signal
|
|
38
38
|
* @param payload - The data to send with the signal
|
|
39
39
|
*/
|
|
40
40
|
submitSignal(signalName: string, payload?: Jsonable): any;
|
|
41
|
-
/**
|
|
42
|
-
* Adds a listener for a broadcast request. The listener is called when a client calls
|
|
43
|
-
* `requestBroadcast` for that signal. It behaves in the same way as EventEmitter's `on`
|
|
44
|
-
* method regarding multiple registrations, callback order, etc.
|
|
45
|
-
* @param signalName - The signal for which broadcast is requested
|
|
46
|
-
* @param listener - The callback for the broadcast request to add
|
|
47
|
-
* @returns This ISignaler
|
|
48
|
-
*/
|
|
49
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
50
|
-
/**
|
|
51
|
-
* Remove a listener for a broadcast request. It behaves in the same way as EventEmitter's
|
|
52
|
-
* `off` method regarding multiple registrations, removal order, etc.
|
|
53
|
-
* @param signalName - The signal for which broadcast is requested
|
|
54
|
-
* @param listener - The callback for the broadcast request to remove
|
|
55
|
-
* @returns This ISignaler
|
|
56
|
-
*/
|
|
57
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
58
|
-
/**
|
|
59
|
-
* Request broadcast of a signal from other connected clients. Other clients must have
|
|
60
|
-
* registered to respond to broadcast requests using the `onBroadcastRequested` method.
|
|
61
|
-
* @param signalName - The signal for which broadcast is requested
|
|
62
|
-
* @param payload - A payload to send with the broadcast request
|
|
63
|
-
*/
|
|
64
|
-
requestBroadcast(signalName: string, payload?: Jsonable): any;
|
|
65
41
|
}
|
|
66
42
|
/**
|
|
67
43
|
* Duck type of something that provides the expected signalling functionality:
|
|
@@ -100,13 +76,9 @@ export declare class Signaler extends TypedEventEmitter<IErrorEvent> implements
|
|
|
100
76
|
*/
|
|
101
77
|
managerId?: string);
|
|
102
78
|
private getManagerSignalName;
|
|
103
|
-
private getBroadcastSignalName;
|
|
104
79
|
onSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
105
80
|
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
106
81
|
submitSignal(signalName: string, payload?: Jsonable): void;
|
|
107
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
108
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
109
|
-
requestBroadcast(signalName: string, payload?: Jsonable): void;
|
|
110
82
|
}
|
|
111
83
|
/**
|
|
112
84
|
* Note: currently experimental and under development
|
|
@@ -128,8 +100,5 @@ export declare class SignalManager extends DataObject<{
|
|
|
128
100
|
onSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
129
101
|
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
130
102
|
submitSignal(signalName: string, payload?: Jsonable): void;
|
|
131
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
132
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
133
|
-
requestBroadcast(signalName: string, payload?: Jsonable): void;
|
|
134
103
|
}
|
|
135
104
|
//# sourceMappingURL=signalManager.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signalManager.d.ts","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAM5E,oBAAY,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE3F;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACjE;;;;;;MAME;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,
|
|
1
|
+
{"version":3,"file":"signalManager.d.ts","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"AAAA;;;GAGG;;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAC;AACtC,OAAO,EAAE,UAAU,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAC;AACzE,OAAO,EAAE,WAAW,EAAE,MAAM,oCAAoC,CAAC;AACjE,OAAO,EAAU,iBAAiB,EAAE,MAAM,8BAA8B,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,uCAAuC,CAAC;AACjE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAM5E,oBAAY,cAAc,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,QAAQ,KAAK,IAAI,CAAC;AAE3F;;;;GAIG;AACH,MAAM,WAAW,SAAS;IACtB;;;;;;OAMG;IACH,QAAQ,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACjE;;;;;;MAME;IACH,SAAS,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,cAAc,GAAG,SAAS,CAAC;IACnE;;;;OAIG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,QAAQ,OAAE;CACxD;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,OAAO,CAAC;IACnB,EAAE,CAAC,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,OAAO,EAAE,qBAAqB,EAAE,KAAK,EAAE,OAAO,KAAK,IAAI,OAAE;IACxF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,GAAG,GAAG,IAAI,CAAC;CAClD;AAED;;;;;;;;GAQG;AACH,qBAAa,QAAS,SAAQ,iBAAiB,CAAC,WAAW,CAAE,YAAW,SAAS;IAMzE;;OAEG;IACH,OAAO,CAAC,QAAQ,CAAC,QAAQ;IAR7B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAE9C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAqB;;IAG3C;;OAEG;IACc,QAAQ,EAAE,gBAAgB;IAC3C;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM;IAkBtB,OAAO,CAAC,oBAAoB;IAMrB,QAAQ,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAML,SAAS,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAML,YAAY,CACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,QAAQ;CAOzB;AAED;;;;;;GAMG;AACH,qBAAa,aAAc,SAAQ,UAAU,CAAC;IAAE,MAAM,EAAE,WAAW,CAAC;CAAE,CAAE,YAAW,YAAY,EAAE,SAAS;IACtG,OAAO,CAAC,QAAQ,CAAuB;IACvC,OAAO,KAAK,OAAO,GAGlB;IAED,WAAkB,IAAI,WAA8C;IAEpE,gBAAuB,OAAO;gBATsB,WAAW;OAc7D;cAEc,cAAc;IASvB,QAAQ,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAKL,SAAS,CACZ,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,cAAc,GACzB,SAAS;IAKL,YAAY,CACf,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,QAAQ;CAIzB"}
|
|
@@ -46,9 +46,6 @@ export class Signaler extends TypedEventEmitter {
|
|
|
46
46
|
getManagerSignalName(signalName) {
|
|
47
47
|
return this.managerId ? `${signalName}${this.managerId}` : signalName;
|
|
48
48
|
}
|
|
49
|
-
getBroadcastSignalName(signalName) {
|
|
50
|
-
return `${signalName}#req`;
|
|
51
|
-
}
|
|
52
49
|
// ISignaler methods
|
|
53
50
|
onSignal(signalName, listener) {
|
|
54
51
|
const managerSignalName = this.getManagerSignalName(signalName);
|
|
@@ -66,18 +63,6 @@ export class Signaler extends TypedEventEmitter {
|
|
|
66
63
|
this.signaler.submitSignal(managerSignalName, payload);
|
|
67
64
|
}
|
|
68
65
|
}
|
|
69
|
-
onBroadcastRequested(signalName, listener) {
|
|
70
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
71
|
-
return this.onSignal(broadcastSignalName, listener);
|
|
72
|
-
}
|
|
73
|
-
offBroadcastRequested(signalName, listener) {
|
|
74
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
75
|
-
return this.offSignal(broadcastSignalName, listener);
|
|
76
|
-
}
|
|
77
|
-
requestBroadcast(signalName, payload) {
|
|
78
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
79
|
-
this.submitSignal(broadcastSignalName, payload);
|
|
80
|
-
}
|
|
81
66
|
}
|
|
82
67
|
/**
|
|
83
68
|
* Note: currently experimental and under development
|
|
@@ -110,17 +95,6 @@ export class SignalManager extends DataObject {
|
|
|
110
95
|
submitSignal(signalName, payload) {
|
|
111
96
|
this.manager.submitSignal(signalName, payload);
|
|
112
97
|
}
|
|
113
|
-
onBroadcastRequested(signalName, listener) {
|
|
114
|
-
this.manager.onBroadcastRequested(signalName, listener);
|
|
115
|
-
return this;
|
|
116
|
-
}
|
|
117
|
-
offBroadcastRequested(signalName, listener) {
|
|
118
|
-
this.manager.offBroadcastRequested(signalName, listener);
|
|
119
|
-
return this;
|
|
120
|
-
}
|
|
121
|
-
requestBroadcast(signalName, payload) {
|
|
122
|
-
this.manager.requestBroadcast(signalName, payload);
|
|
123
|
-
}
|
|
124
98
|
}
|
|
125
99
|
SignalManager.factory = new DataObjectFactory(SignalManager.Name, SignalManager, [], {});
|
|
126
100
|
//# sourceMappingURL=signalManager.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"signalManager.js","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { DataObject, DataObjectFactory } from \"@fluidframework/aqueduct\";\nimport { IErrorEvent } from \"@fluidframework/common-definitions\";\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { Jsonable } from \"@fluidframework/datastore-definitions\";\nimport { IInboundSignalMessage } from \"@fluidframework/runtime-definitions\";\n\n// TODO:\n// add way to mark with current sequence number for ordering signals relative to ops\n// throttling and batching\n\nexport type SignalListener = (clientId: string, local: boolean, payload: Jsonable) => void;\n\n/**\n * ISignaler defines an interface for working with signals that is similar to the more common\n * eventing patterns of EventEmitter. In addition to sending and responding to signals, it\n * provides explicit methods around signal requests to other connected clients.\n */\nexport interface ISignaler {\n /**\n * Adds a listener for the specified signal. It behaves in the same way as EventEmitter's `on`\n * method regarding multiple registrations, callback order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to add\n * @returns This ISignaler\n */\n onSignal(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Remove a listener for the specified signal. It behaves in the same way as EventEmitter's\n * `off` method regarding multiple registrations, removal order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to remove\n * @returns This ISignaler\n */\n offSignal(signalName: string, listener: SignalListener | ((message: any) => void)): ISignaler;\n /**\n * Send a signal with payload to its connected listeners.\n * @param signalName - The name of the signal\n * @param payload - The data to send with the signal\n */\n submitSignal(signalName: string, payload?: Jsonable);\n\n /**\n * Adds a listener for a broadcast request. The listener is called when a client calls\n * `requestBroadcast` for that signal. It behaves in the same way as EventEmitter's `on`\n * method regarding multiple registrations, callback order, etc.\n * @param signalName - The signal for which broadcast is requested\n * @param listener - The callback for the broadcast request to add\n * @returns This ISignaler\n */\n onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Remove a listener for a broadcast request. It behaves in the same way as EventEmitter's\n * `off` method regarding multiple registrations, removal order, etc.\n * @param signalName - The signal for which broadcast is requested\n * @param listener - The callback for the broadcast request to remove\n * @returns This ISignaler\n */\n offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Request broadcast of a signal from other connected clients. Other clients must have\n * registered to respond to broadcast requests using the `onBroadcastRequested` method.\n * @param signalName - The signal for which broadcast is requested\n * @param payload - A payload to send with the broadcast request\n */\n requestBroadcast(signalName: string, payload?: Jsonable);\n}\n\n/**\n * Duck type of something that provides the expected signalling functionality:\n * A way to verify we can signal, a way to send a signal, and a way to listen for incoming signals\n */\nexport interface IRuntimeSignaler {\n connected: boolean;\n on(event: \"signal\", listener: (message: IInboundSignalMessage, local: boolean) => void);\n submitSignal(type: string, content: any): void;\n}\n\n/**\n * Note: currently experimental and under development\n *\n * Helper class to assist common scenarios around working with signals. Signaler wraps a runtime\n * object with signaling functionality (e.g. ContainerRuntime or FluidDataStoreRuntime) and can\n * then be used in place of the original signaler. It uses a separate internal EventEmitter to\n * manage callbacks, and thus will reflect that behavior with regards to callback registration and\n * deregistration.\n */\nexport class Signaler extends TypedEventEmitter<IErrorEvent> implements ISignaler {\n private readonly emitter = new EventEmitter();\n\n private readonly managerId: string | undefined;\n\n constructor(\n /**\n * Object to wrap that can submit and listen to signals\n */\n private readonly signaler: IRuntimeSignaler,\n /**\n * Optional id to assign to this manager that will be attached to\n * signal names. Useful to avoid collisions if there are multiple\n * signal users at the Container level\n */\n managerId?: string,\n ) {\n super();\n this.emitter.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n this.managerId = managerId ? `#${managerId}` : undefined;\n this.signaler.on(\"signal\", (message: IInboundSignalMessage, local: boolean) => {\n const clientId = message.clientId;\n // Only call listeners when the runtime is connected and if the signal has an\n // identifiable sender clientId. The listener is responsible for deciding how\n // it wants to handle local/remote signals\n if (this.signaler.connected && clientId !== null) {\n this.emitter.emit(message.type, clientId, local, message.content);\n }\n });\n }\n\n private getManagerSignalName(signalName: string): string {\n return this.managerId ? `${signalName}${this.managerId}` : signalName;\n }\n\n private getBroadcastSignalName(signalName: string): string {\n return `${signalName}#req`;\n }\n\n // ISignaler methods\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.on(managerSignalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.off(managerSignalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n const managerSignalName = this.getManagerSignalName(signalName);\n if (this.signaler.connected) {\n this.signaler.submitSignal(managerSignalName, payload);\n }\n }\n\n public onBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const broadcastSignalName = this.getBroadcastSignalName(signalName);\n return this.onSignal(broadcastSignalName, listener);\n }\n\n public offBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const broadcastSignalName = this.getBroadcastSignalName(signalName);\n return this.offSignal(broadcastSignalName, listener);\n }\n\n public requestBroadcast(\n signalName: string,\n payload?: Jsonable,\n ) {\n const broadcastSignalName = this.getBroadcastSignalName(signalName);\n this.submitSignal(broadcastSignalName, payload);\n }\n}\n\n/**\n * Note: currently experimental and under development\n *\n * DataObject implementation of ISignaler for fluid-static plug-and-play. Allows fluid-static\n * users to get an ISignaler without a custom DO. Where possible, consumers should instead\n * create a Signaler themselves instead of using the DO wrapper to avoid the DO overhead.\n */\nexport class SignalManager extends DataObject<{ Events: IErrorEvent; }> implements EventEmitter, ISignaler {\n private _manager: Signaler | undefined;\n private get manager(): Signaler {\n assert(this._manager !== undefined, 0x24b /* \"internal signaler should be defined\" */);\n return this._manager;\n }\n\n public static get Name() { return \"@fluid-example/signal-manager\"; }\n\n public static readonly factory = new DataObjectFactory(\n SignalManager.Name,\n SignalManager,\n [],\n {},\n );\n\n protected async hasInitialized() {\n this._manager = new Signaler(this.runtime);\n this.manager.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n }\n\n // ISignaler methods Note these are all passthroughs\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.onSignal(signalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.offSignal(signalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n this.manager.submitSignal(signalName, payload);\n }\n\n public onBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.onBroadcastRequested(signalName, listener);\n return this;\n }\n\n public offBroadcastRequested(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.offBroadcastRequested(signalName, listener);\n return this;\n }\n\n public requestBroadcast(\n signalName: string,\n payload?: Jsonable,\n ) {\n this.manager.requestBroadcast(signalName, payload);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"signalManager.js","sourceRoot":"","sources":["../../src/signalManager/signalManager.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { EventEmitter } from \"events\";\nimport { DataObject, DataObjectFactory } from \"@fluidframework/aqueduct\";\nimport { IErrorEvent } from \"@fluidframework/common-definitions\";\nimport { assert, TypedEventEmitter } from \"@fluidframework/common-utils\";\nimport { Jsonable } from \"@fluidframework/datastore-definitions\";\nimport { IInboundSignalMessage } from \"@fluidframework/runtime-definitions\";\n\n// TODO:\n// add way to mark with current sequence number for ordering signals relative to ops\n// throttling and batching\n\nexport type SignalListener = (clientId: string, local: boolean, payload: Jsonable) => void;\n\n/**\n * ISignaler defines an interface for working with signals that is similar to the more common\n * eventing patterns of EventEmitter. In addition to sending and responding to signals, it\n * provides explicit methods around signal requests to other connected clients.\n */\nexport interface ISignaler {\n /**\n * Adds a listener for the specified signal. It behaves in the same way as EventEmitter's `on`\n * method regarding multiple registrations, callback order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to add\n * @returns This ISignaler\n */\n onSignal(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Remove a listener for the specified signal. It behaves in the same way as EventEmitter's\n * `off` method regarding multiple registrations, removal order, etc.\n * @param signalName - The name of the signal\n * @param listener - The callback signal handler to remove\n * @returns This ISignaler\n */\n offSignal(signalName: string, listener: SignalListener): ISignaler;\n /**\n * Send a signal with payload to its connected listeners.\n * @param signalName - The name of the signal\n * @param payload - The data to send with the signal\n */\n submitSignal(signalName: string, payload?: Jsonable);\n}\n\n/**\n * Duck type of something that provides the expected signalling functionality:\n * A way to verify we can signal, a way to send a signal, and a way to listen for incoming signals\n */\nexport interface IRuntimeSignaler {\n connected: boolean;\n on(event: \"signal\", listener: (message: IInboundSignalMessage, local: boolean) => void);\n submitSignal(type: string, content: any): void;\n}\n\n/**\n * Note: currently experimental and under development\n *\n * Helper class to assist common scenarios around working with signals. Signaler wraps a runtime\n * object with signaling functionality (e.g. ContainerRuntime or FluidDataStoreRuntime) and can\n * then be used in place of the original signaler. It uses a separate internal EventEmitter to\n * manage callbacks, and thus will reflect that behavior with regards to callback registration and\n * deregistration.\n */\nexport class Signaler extends TypedEventEmitter<IErrorEvent> implements ISignaler {\n private readonly emitter = new EventEmitter();\n\n private readonly managerId: string | undefined;\n\n constructor(\n /**\n * Object to wrap that can submit and listen to signals\n */\n private readonly signaler: IRuntimeSignaler,\n /**\n * Optional id to assign to this manager that will be attached to\n * signal names. Useful to avoid collisions if there are multiple\n * signal users at the Container level\n */\n managerId?: string,\n ) {\n super();\n this.emitter.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n this.managerId = managerId ? `#${managerId}` : undefined;\n this.signaler.on(\"signal\", (message: IInboundSignalMessage, local: boolean) => {\n const clientId = message.clientId;\n // Only call listeners when the runtime is connected and if the signal has an\n // identifiable sender clientId. The listener is responsible for deciding how\n // it wants to handle local/remote signals\n if (this.signaler.connected && clientId !== null) {\n this.emitter.emit(message.type, clientId, local, message.content);\n }\n });\n }\n\n private getManagerSignalName(signalName: string): string {\n return this.managerId ? `${signalName}${this.managerId}` : signalName;\n }\n\n // ISignaler methods\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.on(managerSignalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n const managerSignalName = this.getManagerSignalName(signalName);\n this.emitter.off(managerSignalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n const managerSignalName = this.getManagerSignalName(signalName);\n if (this.signaler.connected) {\n this.signaler.submitSignal(managerSignalName, payload);\n }\n }\n}\n\n/**\n * Note: currently experimental and under development\n *\n * DataObject implementation of ISignaler for fluid-static plug-and-play. Allows fluid-static\n * users to get an ISignaler without a custom DO. Where possible, consumers should instead\n * create a Signaler themselves instead of using the DO wrapper to avoid the DO overhead.\n */\nexport class SignalManager extends DataObject<{ Events: IErrorEvent; }> implements EventEmitter, ISignaler {\n private _manager: Signaler | undefined;\n private get manager(): Signaler {\n assert(this._manager !== undefined, 0x24b /* \"internal signaler should be defined\" */);\n return this._manager;\n }\n\n public static get Name() { return \"@fluid-example/signal-manager\"; }\n\n public static readonly factory = new DataObjectFactory(\n SignalManager.Name,\n SignalManager,\n [],\n {},\n );\n\n protected async hasInitialized() {\n this._manager = new Signaler(this.runtime);\n this.manager.on(\"error\", (error) => {\n this.emit(\"error\", error);\n });\n }\n\n // ISignaler methods Note these are all passthroughs\n\n public onSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.onSignal(signalName, listener);\n return this;\n }\n\n public offSignal(\n signalName: string,\n listener: SignalListener,\n ): ISignaler {\n this.manager.offSignal(signalName, listener);\n return this;\n }\n\n public submitSignal(\n signalName: string,\n payload?: Jsonable,\n ) {\n this.manager.submitSignal(signalName, payload);\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fluid-experimental/data-objects",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0-78837",
|
|
4
4
|
"description": "A collection of ready to use Fluid Data Objects",
|
|
5
5
|
"homepage": "https://fluidframework.com",
|
|
6
6
|
"repository": {
|
|
@@ -31,15 +31,15 @@
|
|
|
31
31
|
"tsfmt:fix": "tsfmt --replace"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@fluidframework/aqueduct": "1.
|
|
34
|
+
"@fluidframework/aqueduct": "1.2.0-78837",
|
|
35
35
|
"@fluidframework/common-definitions": "^0.20.1",
|
|
36
36
|
"@fluidframework/common-utils": "^0.32.1",
|
|
37
|
-
"@fluidframework/datastore-definitions": "1.
|
|
38
|
-
"@fluidframework/map": "1.
|
|
39
|
-
"@fluidframework/runtime-definitions": "1.
|
|
37
|
+
"@fluidframework/datastore-definitions": "1.2.0-78837",
|
|
38
|
+
"@fluidframework/map": "1.2.0-78837",
|
|
39
|
+
"@fluidframework/runtime-definitions": "1.2.0-78837"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@fluidframework/build-common": "^0.24.0
|
|
42
|
+
"@fluidframework/build-common": "^0.24.0",
|
|
43
43
|
"@fluidframework/eslint-config-fluid": "^0.28.2000",
|
|
44
44
|
"@microsoft/api-extractor": "^7.22.2",
|
|
45
45
|
"@rushstack/eslint-config": "^2.5.1",
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# SignalManager
|
|
2
|
+
The `SignalManager` is a DataObject that can be used to communicate transient data via signals. Transient data refers to impermanent information that is not persisted with the container.
|
|
3
|
+
|
|
4
|
+
## Usage
|
|
5
|
+
User presence scenarios are well-suited for `SignalManager`, as users are required to tell other users their own information and their past data is mostly irrelavant. Using `SignalManager` over other distributed data structures in these scenarios is beneficial, as its usage does not result in the storage of data that is not useful in the long-term.
|
|
6
|
+
|
|
7
|
+
### Creation
|
|
8
|
+
Just like with DDSes, you can include `SignalManager` as a shared object you would like to load in your `FluidContainer` schema.
|
|
9
|
+
|
|
10
|
+
Here is a look at how you would go about loading `SignalManager` as part of the initial objects of the container:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
const containerSchema: ContainerSchema = {
|
|
14
|
+
initialObjects: {
|
|
15
|
+
signalManager: SignalManager,
|
|
16
|
+
},
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const { container, services } = await client.createContainer(containerSchema);
|
|
20
|
+
|
|
21
|
+
const signalManager = container.initialObjects.signalManager as SignalManager;
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
`signalManager` can then be directly used in your Fluid application!
|
|
25
|
+
|
|
26
|
+
For more information on using `ContainerSchema` to create objects please see [Data modeling](https://fluidframework.com/docs/build/data-modeling/).
|
|
27
|
+
|
|
28
|
+
## API
|
|
29
|
+
`SignalManager` provides a few simple methods to send signals and add/remove listeners to specific signals as well:
|
|
30
|
+
- `submitSignal(signalName: string, payload?: Jsonable)` - Sends a signal with a payload to its connected listeners
|
|
31
|
+
- `onSignal(signalName: string, listener: SignalListener)` - Adds a listener for the specified signal. Same behavior as EventEmitter's `on` method.
|
|
32
|
+
- `offSignal(signalName: string, listener: SignalListener)` - Removes a listener for the specified signal. Same behavior as EventEmitter's `off` method.
|
|
33
|
+
|
|
34
|
+
## Common Patterns
|
|
35
|
+
### Signal Request
|
|
36
|
+
When a client joins a collaboration session, they may need to receive pertinent information immediately after connecting the container. To support this, they can request a specific signal be sent to them from other connected clients within the application. For example, in the [FocusTracker](https://github.com/microsoft/FluidFramework/tree/main/examples/data-objects/focus-tracker) we define a "focusRequest" signal type that a newly joining client uses to request the focus-state of each currently connected client:
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
private static readonly focusRequestType = "focusRequest";
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
```typescript
|
|
43
|
+
container.on("connected", () => {
|
|
44
|
+
this.signalManager.submitSignal(FocusTracker.focusRequestType);
|
|
45
|
+
});
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
The connected clients are listening to this focus request signal, and they respond with their current focus state:
|
|
49
|
+
|
|
50
|
+
```typescript
|
|
51
|
+
this.signalManager.onSignal(FocusTracker.focusRequestType, () => {
|
|
52
|
+
this.sendFocusSignal(document.hasFocus());
|
|
53
|
+
});
|
|
54
|
+
```
|
|
55
|
+
When there are a lot of connected clients, usage of this request pattern can lead to high signal costs incurred from large amounts of signals being submitted all at the same time. While this pattern is helpful when a client is in need of relevant information, to limit signal costs it would be beneficial to examine whether or not the requested data will be quickly avaiable from other events being listened to within the application. Take [MouseTracker]() as an example, a newly connecting client is not required to request a signal to receive every current mouse position on the document. Since mouse movements are frequent, the newly connecting client can simply wait to recieve other users mouse positions on their mousemove events.
|
|
@@ -37,38 +37,13 @@ export interface ISignaler {
|
|
|
37
37
|
* @param listener - The callback signal handler to remove
|
|
38
38
|
* @returns This ISignaler
|
|
39
39
|
*/
|
|
40
|
-
offSignal(signalName: string, listener: SignalListener
|
|
40
|
+
offSignal(signalName: string, listener: SignalListener): ISignaler;
|
|
41
41
|
/**
|
|
42
42
|
* Send a signal with payload to its connected listeners.
|
|
43
43
|
* @param signalName - The name of the signal
|
|
44
44
|
* @param payload - The data to send with the signal
|
|
45
45
|
*/
|
|
46
46
|
submitSignal(signalName: string, payload?: Jsonable);
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Adds a listener for a broadcast request. The listener is called when a client calls
|
|
50
|
-
* `requestBroadcast` for that signal. It behaves in the same way as EventEmitter's `on`
|
|
51
|
-
* method regarding multiple registrations, callback order, etc.
|
|
52
|
-
* @param signalName - The signal for which broadcast is requested
|
|
53
|
-
* @param listener - The callback for the broadcast request to add
|
|
54
|
-
* @returns This ISignaler
|
|
55
|
-
*/
|
|
56
|
-
onBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
57
|
-
/**
|
|
58
|
-
* Remove a listener for a broadcast request. It behaves in the same way as EventEmitter's
|
|
59
|
-
* `off` method regarding multiple registrations, removal order, etc.
|
|
60
|
-
* @param signalName - The signal for which broadcast is requested
|
|
61
|
-
* @param listener - The callback for the broadcast request to remove
|
|
62
|
-
* @returns This ISignaler
|
|
63
|
-
*/
|
|
64
|
-
offBroadcastRequested(signalName: string, listener: SignalListener): ISignaler;
|
|
65
|
-
/**
|
|
66
|
-
* Request broadcast of a signal from other connected clients. Other clients must have
|
|
67
|
-
* registered to respond to broadcast requests using the `onBroadcastRequested` method.
|
|
68
|
-
* @param signalName - The signal for which broadcast is requested
|
|
69
|
-
* @param payload - A payload to send with the broadcast request
|
|
70
|
-
*/
|
|
71
|
-
requestBroadcast(signalName: string, payload?: Jsonable);
|
|
72
47
|
}
|
|
73
48
|
|
|
74
49
|
/**
|
|
@@ -127,10 +102,6 @@ export class Signaler extends TypedEventEmitter<IErrorEvent> implements ISignale
|
|
|
127
102
|
return this.managerId ? `${signalName}${this.managerId}` : signalName;
|
|
128
103
|
}
|
|
129
104
|
|
|
130
|
-
private getBroadcastSignalName(signalName: string): string {
|
|
131
|
-
return `${signalName}#req`;
|
|
132
|
-
}
|
|
133
|
-
|
|
134
105
|
// ISignaler methods
|
|
135
106
|
|
|
136
107
|
public onSignal(
|
|
@@ -160,30 +131,6 @@ export class Signaler extends TypedEventEmitter<IErrorEvent> implements ISignale
|
|
|
160
131
|
this.signaler.submitSignal(managerSignalName, payload);
|
|
161
132
|
}
|
|
162
133
|
}
|
|
163
|
-
|
|
164
|
-
public onBroadcastRequested(
|
|
165
|
-
signalName: string,
|
|
166
|
-
listener: SignalListener,
|
|
167
|
-
): ISignaler {
|
|
168
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
169
|
-
return this.onSignal(broadcastSignalName, listener);
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
public offBroadcastRequested(
|
|
173
|
-
signalName: string,
|
|
174
|
-
listener: SignalListener,
|
|
175
|
-
): ISignaler {
|
|
176
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
177
|
-
return this.offSignal(broadcastSignalName, listener);
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
public requestBroadcast(
|
|
181
|
-
signalName: string,
|
|
182
|
-
payload?: Jsonable,
|
|
183
|
-
) {
|
|
184
|
-
const broadcastSignalName = this.getBroadcastSignalName(signalName);
|
|
185
|
-
this.submitSignal(broadcastSignalName, payload);
|
|
186
|
-
}
|
|
187
134
|
}
|
|
188
135
|
|
|
189
136
|
/**
|
|
@@ -240,27 +187,4 @@ export class SignalManager extends DataObject<{ Events: IErrorEvent; }> implemen
|
|
|
240
187
|
) {
|
|
241
188
|
this.manager.submitSignal(signalName, payload);
|
|
242
189
|
}
|
|
243
|
-
|
|
244
|
-
public onBroadcastRequested(
|
|
245
|
-
signalName: string,
|
|
246
|
-
listener: SignalListener,
|
|
247
|
-
): ISignaler {
|
|
248
|
-
this.manager.onBroadcastRequested(signalName, listener);
|
|
249
|
-
return this;
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
public offBroadcastRequested(
|
|
253
|
-
signalName: string,
|
|
254
|
-
listener: SignalListener,
|
|
255
|
-
): ISignaler {
|
|
256
|
-
this.manager.offBroadcastRequested(signalName, listener);
|
|
257
|
-
return this;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
public requestBroadcast(
|
|
261
|
-
signalName: string,
|
|
262
|
-
payload?: Jsonable,
|
|
263
|
-
) {
|
|
264
|
-
this.manager.requestBroadcast(signalName, payload);
|
|
265
|
-
}
|
|
266
190
|
}
|