feat: update devtools almost real time using signals

Signed-off-by: Heikki Hellgren <heikki.hellgren@op.fi>
This commit is contained in:
Heikki Hellgren
2023-12-05 15:35:36 +02:00
parent db84649e81
commit 59a4508efe
28 changed files with 114 additions and 84 deletions
+3 -3
View File
@@ -7,17 +7,17 @@ import { BackstagePlugin } from '@backstage/core-plugin-api';
import { DiscoveryApi } from '@backstage/core-plugin-api';
import { IdentityApi } from '@backstage/core-plugin-api';
import { JsonObject } from '@backstage/types';
import { SignalsApi } from '@backstage/plugin-signals-react';
import { SignalApi } from '@backstage/plugin-signals-react';
// @public (undocumented)
export class SignalsClient implements SignalsApi {
export class SignalClient implements SignalApi {
// (undocumented)
static create(options: {
identity: IdentityApi;
discoveryApi: DiscoveryApi;
connectTimeout?: number;
reconnectTimeout?: number;
}): SignalsClient;
}): SignalClient;
// (undocumented)
static readonly DEFAULT_CONNECT_TIMEOUT_MS: number;
// (undocumented)
@@ -13,24 +13,21 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { SignalsApi } from '@backstage/plugin-signals-react';
import { SignalApi } from '@backstage/plugin-signals-react';
import { JsonObject } from '@backstage/types';
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
import { v4 as uuid } from 'uuid';
/** @internal */
type Subscription = {
topic: string;
callback: (message: JsonObject) => void;
};
/** @internal */
const WS_CLOSE_NORMAL = 1000;
/** @internal */
const WS_CLOSE_GOING_AWAY = 1001;
/** @public */
export class SignalsClient implements SignalsApi {
export class SignalClient implements SignalApi {
static readonly DEFAULT_CONNECT_TIMEOUT_MS: number = 1000;
static readonly DEFAULT_RECONNECT_TIMEOUT_MS: number = 5000;
private ws: WebSocket | null = null;
@@ -47,10 +44,10 @@ export class SignalsClient implements SignalsApi {
const {
identity,
discoveryApi,
connectTimeout = SignalsClient.DEFAULT_CONNECT_TIMEOUT_MS,
reconnectTimeout = SignalsClient.DEFAULT_RECONNECT_TIMEOUT_MS,
connectTimeout = SignalClient.DEFAULT_CONNECT_TIMEOUT_MS,
reconnectTimeout = SignalClient.DEFAULT_RECONNECT_TIMEOUT_MS,
} = options;
return new SignalsClient(
return new SignalClient(
identity,
discoveryApi,
connectTimeout,
@@ -16,7 +16,7 @@
import { DiscoveryApi, IdentityApi } from '@backstage/core-plugin-api';
import WS from 'jest-websocket-mock';
import { SignalsClient } from './SignalsClient';
import { SignalClient } from './SignalClient';
describe('SignalsClient', () => {
const tokenFunction = jest.fn();
@@ -43,7 +43,7 @@ describe('SignalsClient', () => {
it('should handle single subscription correctly', async () => {
const messageMock = jest.fn();
const client = SignalsClient.create({ discoveryApi, identity });
const client = SignalClient.create({ discoveryApi, identity });
const sub = client.subscribe('topic', messageMock);
await server.connected;
@@ -64,8 +64,8 @@ describe('SignalsClient', () => {
it('should handle multiple subscription correctly', async () => {
const messageMock1 = jest.fn();
const messageMock2 = jest.fn();
const client1 = SignalsClient.create({ discoveryApi, identity });
const client2 = SignalsClient.create({ discoveryApi, identity });
const client1 = SignalClient.create({ discoveryApi, identity });
const client2 = SignalClient.create({ discoveryApi, identity });
const sub1 = client1.subscribe('topic', messageMock1);
const sub2 = client2.subscribe('topic', messageMock2);
@@ -94,7 +94,7 @@ describe('SignalsClient', () => {
it('should reconnect on error', async () => {
const messageMock = jest.fn();
const client = SignalsClient.create({
const client = SignalClient.create({
discoveryApi,
identity,
reconnectTimeout: 10,
+1 -1
View File
@@ -13,4 +13,4 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './SignalsClient';
export * from './SignalClient';
+4 -4
View File
@@ -19,21 +19,21 @@ import {
discoveryApiRef,
identityApiRef,
} from '@backstage/core-plugin-api';
import { signalsApiRef } from '@backstage/plugin-signals-react';
import { SignalsClient } from './api/SignalsClient';
import { signalApiRef } from '@backstage/plugin-signals-react';
import { SignalClient } from './api/SignalClient';
/** @public */
export const signalsPlugin = createPlugin({
id: 'signals',
apis: [
createApiFactory({
api: signalsApiRef,
api: signalApiRef,
deps: {
identity: identityApiRef,
discoveryApi: discoveryApiRef,
},
factory: ({ identity, discoveryApi }) =>
SignalsClient.create({
SignalClient.create({
identity,
discoveryApi,
}),