UNPKG

3.58 kBJavaScriptView Raw
1import { fromEvent, Subscription } from 'rxjs';
2import { filter, map } from 'rxjs/operators';
3import { createMessageConnection } from 'sourcegraph/module/jsonrpc2/connection';
4import { AbstractMessageReader, AbstractMessageWriter, } from 'sourcegraph/module/jsonrpc2/transport';
5class SubscribableMessageReader extends AbstractMessageReader {
6 constructor(subscribable) {
7 super();
8 this.pending = [];
9 this.callback = null;
10 this.subscription = new Subscription();
11 this.subscription.add(subscribable.subscribe(message => {
12 try {
13 if (this.callback) {
14 this.callback(message);
15 }
16 else {
17 this.pending.push(message);
18 }
19 }
20 catch (err) {
21 this.fireError(err);
22 }
23 }));
24 }
25 listen(callback) {
26 if (this.callback) {
27 throw new Error('callback is already set');
28 }
29 this.callback = callback;
30 while (this.pending.length !== 0) {
31 callback(this.pending.pop());
32 }
33 }
34 unsubscribe() {
35 super.unsubscribe();
36 this.subscription.unsubscribe();
37 }
38}
39class CallbackMessageWriter extends AbstractMessageWriter {
40 constructor(callback) {
41 super();
42 this.callback = callback;
43 }
44 write(message) {
45 this.callback(message);
46 }
47 unsubscribe() {
48 super.unsubscribe();
49 }
50}
51/**
52 * Connects the Sourcegraph extension registry page to a client (such as a browser extension) or vice versa.
53 */
54function connectAs(source) {
55 const messageConnection = createMessageConnection({
56 reader: new SubscribableMessageReader(fromEvent(window, 'message').pipe(
57 // Filter to relevant messages, ignoring our own
58 filter(m => m.data && m.data.source && m.data.source !== source && m.data.message), map(m => m.data.message))),
59 writer: new CallbackMessageWriter(message => {
60 window.postMessage({ source, message }, '*');
61 }),
62 });
63 messageConnection.listen();
64 return new Promise(resolve => {
65 messageConnection.onNotification('Ping', () => {
66 messageConnection.sendNotification('Pong');
67 resolve(messageConnection);
68 });
69 messageConnection.onNotification('Pong', () => {
70 resolve(messageConnection);
71 });
72 messageConnection.sendNotification('Ping');
73 });
74}
75/**
76 * Connects the client (such as a browser extension) to a Sourcegraph extension registry page.
77 */
78export function connectAsClient() {
79 return connectAs('Client').then(connection => ({
80 onEditSetting: callback => {
81 connection.onRequest('EditSetting', callback);
82 },
83 onGetSettings: callback => {
84 connection.onRequest('GetSettings', callback);
85 },
86 sendSettings: settings => {
87 connection.sendNotification('Settings', settings);
88 },
89 rawConnection: connection,
90 }));
91}
92/**
93 * Connects the Sourcegraph extension registry page to a client (such as a browser extension).
94 */
95export function connectAsPage() {
96 return connectAs('Page').then(connection => ({
97 onSettings: callback => {
98 connection.onNotification('Settings', callback);
99 },
100 editSetting: callback => connection.sendRequest('EditSetting', callback),
101 getSettings: () => connection.sendRequest('GetSettings'),
102 rawConnection: connection,
103 }));
104}
105//# sourceMappingURL=messaging.js.map
\No newline at end of file