@bit.rhplus/signal 0.0.2

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.
@@ -0,0 +1,81 @@
1
+ import * as React from "react";
2
+ import { HubConnectionBuilder } from "@microsoft/signalr";
3
+ import { useEventEmitter } from "./useEventEmitter";
4
+
5
+ export const SignalContext = React.createContext(null);
6
+
7
+ export function SignalProvider({
8
+ children,
9
+ authority,
10
+ endpoint,
11
+ accessToken,
12
+ requiredAccessToken,
13
+ logLevel,
14
+ consoleLogs = false
15
+ }) {
16
+ const {emit, on} = useEventEmitter();
17
+
18
+ const connection = React.useMemo(() => {
19
+ if (requiredAccessToken && !accessToken) {
20
+ return null;
21
+ }
22
+
23
+ const options = accessToken ? { accessTokenFactory: () => accessToken } : {};
24
+ const url = `${authority}${endpoint || "/hubs/userinterface"}`;
25
+ return new HubConnectionBuilder()
26
+ .withUrl(url, options)
27
+ .withAutomaticReconnect()
28
+ .configureLogging(logLevel)
29
+ .build();
30
+ }, [authority, endpoint, accessToken, requiredAccessToken, logLevel]);
31
+
32
+ React.useEffect(() => {
33
+ if (!connection) return;
34
+
35
+ const startConnection = async () => {
36
+ try {
37
+ await connection.start();
38
+ connection.on("Signal", message => {
39
+ if (consoleLogs) {
40
+ // eslint-disable-next-line no-console
41
+ console.log("signal => ", message);
42
+ }
43
+ emit("Signal", message);
44
+ } );
45
+ } catch (e) {
46
+ // eslint-disable-next-line no-console
47
+ console.error("Connection failed: ", e);
48
+ }
49
+ };
50
+
51
+ startConnection();
52
+
53
+ /* eslint-disable consistent-return */
54
+ return () => {
55
+ connection.stop().catch(e => {
56
+ // eslint-disable-next-line no-console
57
+ console.error("Disconnect failed: ", e)
58
+ });
59
+ };
60
+ }, [connection, emit]);
61
+
62
+ const signal = async (eventName, message) => {
63
+ if (connection) {
64
+ try {
65
+ await connection.invoke("Signal", {
66
+ eventName,
67
+ message
68
+ });
69
+ } catch (err) {
70
+ // eslint-disable-next-line no-console
71
+ console.error(err);
72
+ }
73
+ } else {
74
+ throw new Error("No connection");
75
+ }
76
+ };
77
+
78
+ return (
79
+ <SignalContext.Provider value={{signal, on}}>{children}</SignalContext.Provider>
80
+ );
81
+ }
@@ -0,0 +1,11 @@
1
+ export function SignalProvider({ children, authority, endpoint, accessToken, requiredAccessToken, logLevel, consoleLogs }: {
2
+ children: any;
3
+ authority: any;
4
+ endpoint: any;
5
+ accessToken: any;
6
+ requiredAccessToken: any;
7
+ logLevel: any;
8
+ consoleLogs?: boolean | undefined;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ export const SignalContext: React.Context<null>;
11
+ import * as React from "react";
@@ -0,0 +1,67 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from "react";
3
+ import { HubConnectionBuilder } from "@microsoft/signalr";
4
+ import { useEventEmitter } from "./useEventEmitter";
5
+ export const SignalContext = React.createContext(null);
6
+ export function SignalProvider({ children, authority, endpoint, accessToken, requiredAccessToken, logLevel, consoleLogs = false }) {
7
+ const { emit, on } = useEventEmitter();
8
+ const connection = React.useMemo(() => {
9
+ if (requiredAccessToken && !accessToken) {
10
+ return null;
11
+ }
12
+ const options = accessToken ? { accessTokenFactory: () => accessToken } : {};
13
+ const url = `${authority}${endpoint || "/hubs/userinterface"}`;
14
+ return new HubConnectionBuilder()
15
+ .withUrl(url, options)
16
+ .withAutomaticReconnect()
17
+ .configureLogging(logLevel)
18
+ .build();
19
+ }, [authority, endpoint, accessToken, requiredAccessToken, logLevel]);
20
+ React.useEffect(() => {
21
+ if (!connection)
22
+ return;
23
+ const startConnection = async () => {
24
+ try {
25
+ await connection.start();
26
+ connection.on("Signal", message => {
27
+ if (consoleLogs) {
28
+ // eslint-disable-next-line no-console
29
+ console.log("signal => ", message);
30
+ }
31
+ emit("Signal", message);
32
+ });
33
+ }
34
+ catch (e) {
35
+ // eslint-disable-next-line no-console
36
+ console.error("Connection failed: ", e);
37
+ }
38
+ };
39
+ startConnection();
40
+ /* eslint-disable consistent-return */
41
+ return () => {
42
+ connection.stop().catch(e => {
43
+ // eslint-disable-next-line no-console
44
+ console.error("Disconnect failed: ", e);
45
+ });
46
+ };
47
+ }, [connection, emit]);
48
+ const signal = async (eventName, message) => {
49
+ if (connection) {
50
+ try {
51
+ await connection.invoke("Signal", {
52
+ eventName,
53
+ message
54
+ });
55
+ }
56
+ catch (err) {
57
+ // eslint-disable-next-line no-console
58
+ console.error(err);
59
+ }
60
+ }
61
+ else {
62
+ throw new Error("No connection");
63
+ }
64
+ };
65
+ return (_jsx(SignalContext.Provider, { value: { signal, on }, children: children }));
66
+ }
67
+ //# sourceMappingURL=SignalProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"SignalProvider.js","sourceRoot":"","sources":["../SignalProvider.jsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export * from "./SignalProvider";
2
+ export * from "./useSignal";
3
+ export * from "./useSignalListener";
package/dist/index.js ADDED
@@ -0,0 +1,4 @@
1
+ export * from "./SignalProvider";
2
+ export * from './useSignal';
3
+ export * from './useSignalListener';
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.js"],"names":[],"mappings":"AAAA,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC;AAC5B,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,7 @@
1
+ ;
2
+ ;
3
+
4
+ export const compositions = [];
5
+ export const overview = [];
6
+
7
+ export const compositions_metadata = {"compositions":[]};
@@ -0,0 +1,4 @@
1
+ export function useEventEmitter(): {
2
+ emit: (event: any, data: any) => void;
3
+ on: Function;
4
+ };
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ export function useEventEmitter() {
3
+ const listeners = React.useRef(new Map());
4
+ const emit = React.useCallback((event, data) => {
5
+ const eventListenersToEmit = listeners.current.get(event) || [];
6
+ eventListenersToEmit.forEach(listener => listener(data));
7
+ }, []);
8
+ const on = React.useCallback((event, listener) => {
9
+ const eventListeners = listeners.current.get(event) || [];
10
+ listeners.current.set(event, [...eventListeners, listener]);
11
+ return () => {
12
+ const eventListenersToRemove = listeners.current.get(event) || [];
13
+ listeners.current.set(event, eventListenersToRemove.filter(l => l !== listener));
14
+ };
15
+ });
16
+ return { emit, on };
17
+ }
18
+ //# sourceMappingURL=useEventEmitter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useEventEmitter.js","sourceRoot":"","sources":["../useEventEmitter.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,MAAM,UAAU,eAAe;IAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC;IAE1C,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;QAC7C,MAAM,oBAAoB,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChE,oBAAoB,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IAC3D,CAAC,EAAE,EAAE,CAAC,CAAA;IAEN,MAAM,EAAE,GAAG,KAAK,CAAC,WAAW,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE;QAC/C,MAAM,cAAc,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1D,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,GAAG,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;QAC5D,OAAO,GAAG,EAAE;YACV,MAAM,sBAAsB,GAAG,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAClE,SAAS,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,sBAAsB,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC,CAAC;QACnF,CAAC,CAAA;IACH,CAAC,CAAC,CAAA;IAEF,OAAO,EAAC,IAAI,EAAE,EAAE,EAAC,CAAC;AACpB,CAAC"}
@@ -0,0 +1 @@
1
+ export function useSignal(): null;
@@ -0,0 +1,10 @@
1
+ import * as React from 'react';
2
+ import { SignalContext } from './SignalProvider';
3
+ export function useSignal() {
4
+ const context = React.useContext(SignalContext);
5
+ if (context === undefined) {
6
+ throw new Error('useSignal must be used within a SignalProvider');
7
+ }
8
+ return context;
9
+ }
10
+ //# sourceMappingURL=useSignal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSignal.js","sourceRoot":"","sources":["../useSignal.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAC,aAAa,EAAC,MAAM,kBAAkB,CAAC;AAE/C,MAAM,UAAU,SAAS;IAEvB,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAEhD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,gDAAgD,CAAC,CAAC;IACpE,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,2 @@
1
+ export function useSignalListeners(eventNames: any, callback: any): void;
2
+ export function useSignalListener(eventName: any, callback: any): void;
@@ -0,0 +1,30 @@
1
+ import * as React from "react";
2
+ import { SignalContext } from "./SignalProvider";
3
+ // Hook pro poslech na více signálů (pole eventNames)
4
+ export function useSignalListeners(eventNames, callback) {
5
+ // Uložíme callback do refu, aby se aktualizoval při každé změně
6
+ const listenerCallback = React.useRef(callback);
7
+ const { on } = React.useContext(SignalContext);
8
+ // Přihlášení a odhlášení od signálů
9
+ React.useEffect(() => {
10
+ // Ujistíme se, že ref se aktualizuje kdykoli se změní callback
11
+ listenerCallback.current = callback;
12
+ // Funkce, která se spustí, když přijde signál
13
+ const onSignal = (data) => {
14
+ if (eventNames.includes(data.eventName)) {
15
+ listenerCallback.current(data);
16
+ }
17
+ };
18
+ const unsubscribe = on("Signal", onSignal);
19
+ // Při unmountu komponenty se odhlásíme od poslechu na signál
20
+ return () => {
21
+ unsubscribe();
22
+ };
23
+ }, [eventNames, callback, on]); // Přidáme eventNames jako závislost
24
+ }
25
+ // Hook pro poslech na jeden signál
26
+ export function useSignalListener(eventName, callback) {
27
+ // Voláme rozšířenou funkci s jedním eventName zabaleným do pole
28
+ useSignalListeners([eventName], callback);
29
+ }
30
+ //# sourceMappingURL=useSignalListener.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSignalListener.js","sourceRoot":"","sources":["../useSignalListener.js"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAC/B,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AAEjD,qDAAqD;AACrD,MAAM,UAAU,kBAAkB,CAAC,UAAU,EAAE,QAAQ;IACrD,gEAAgE;IAChE,MAAM,gBAAgB,GAAG,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,EAAE,EAAE,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC;IAE/C,oCAAoC;IACpC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,+DAA+D;QAC/D,gBAAgB,CAAC,OAAO,GAAG,QAAQ,CAAC;QAEpC,8CAA8C;QAC9C,MAAM,QAAQ,GAAG,CAAC,IAAI,EAAE,EAAE;YACxB,IAAI,UAAU,CAAC,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACxC,gBAAgB,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YACjC,CAAC;QACH,CAAC,CAAC;QAEF,MAAM,WAAW,GAAG,EAAE,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAE3C,6DAA6D;QAC7D,OAAO,GAAG,EAAE;YACV,WAAW,EAAE,CAAC;QAChB,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,UAAU,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,oCAAoC;AACtE,CAAC;AAED,mCAAmC;AACnC,MAAM,UAAU,iBAAiB,CAAC,SAAS,EAAE,QAAQ;IACnD,gEAAgE;IAChE,kBAAkB,CAAC,CAAC,SAAS,CAAC,EAAE,QAAQ,CAAC,CAAC;AAC5C,CAAC"}
package/index.js ADDED
@@ -0,0 +1,3 @@
1
+ export * from "./SignalProvider";
2
+ export * from './useSignal';
3
+ export * from './useSignalListener';
package/package.json ADDED
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "@bit.rhplus/signal",
3
+ "version": "0.0.2",
4
+ "homepage": "https://bit.cloud/remote-scope/signal",
5
+ "main": "dist/index.js",
6
+ "componentId": {
7
+ "scope": "remote-scope",
8
+ "name": "signal",
9
+ "version": "0.0.2"
10
+ },
11
+ "dependencies": {
12
+ "@microsoft/signalr": "8.0.0"
13
+ },
14
+ "devDependencies": {
15
+ "@teambit/react.react-env": "1.0.98"
16
+ },
17
+ "peerDependencies": {
18
+ "react": "^17.0.0 || ^18.0.0"
19
+ },
20
+ "license": "SEE LICENSE IN UNLICENSED",
21
+ "optionalDependencies": {},
22
+ "peerDependenciesMeta": {},
23
+ "private": false,
24
+ "publishConfig": {
25
+ "scope": "@bit.rhplus",
26
+ "registry": "https://registry.npmjs.org/"
27
+ }
28
+ }
@@ -0,0 +1,43 @@
1
+ declare module '*.png' {
2
+ const value: any;
3
+ export = value;
4
+ }
5
+ declare module '*.svg' {
6
+ import type { FunctionComponent, SVGProps } from 'react';
7
+
8
+ export const ReactComponent: FunctionComponent<
9
+ SVGProps<SVGSVGElement> & { title?: string }
10
+ >;
11
+ const src: string;
12
+ export default src;
13
+ }
14
+
15
+ // @TODO Gilad
16
+ declare module '*.jpg' {
17
+ const value: any;
18
+ export = value;
19
+ }
20
+ declare module '*.jpeg' {
21
+ const value: any;
22
+ export = value;
23
+ }
24
+ declare module '*.gif' {
25
+ const value: any;
26
+ export = value;
27
+ }
28
+ declare module '*.bmp' {
29
+ const value: any;
30
+ export = value;
31
+ }
32
+ declare module '*.otf' {
33
+ const value: any;
34
+ export = value;
35
+ }
36
+ declare module '*.woff' {
37
+ const value: any;
38
+ export = value;
39
+ }
40
+ declare module '*.woff2' {
41
+ const value: any;
42
+ export = value;
43
+ }
@@ -0,0 +1,42 @@
1
+ declare module '*.module.css' {
2
+ const classes: { readonly [key: string]: string };
3
+ export default classes;
4
+ }
5
+ declare module '*.module.scss' {
6
+ const classes: { readonly [key: string]: string };
7
+ export default classes;
8
+ }
9
+ declare module '*.module.sass' {
10
+ const classes: { readonly [key: string]: string };
11
+ export default classes;
12
+ }
13
+
14
+ declare module '*.module.less' {
15
+ const classes: { readonly [key: string]: string };
16
+ export default classes;
17
+ }
18
+
19
+ declare module '*.less' {
20
+ const classes: { readonly [key: string]: string };
21
+ export default classes;
22
+ }
23
+
24
+ declare module '*.css' {
25
+ const classes: { readonly [key: string]: string };
26
+ export default classes;
27
+ }
28
+
29
+ declare module '*.sass' {
30
+ const classes: { readonly [key: string]: string };
31
+ export default classes;
32
+ }
33
+
34
+ declare module '*.scss' {
35
+ const classes: { readonly [key: string]: string };
36
+ export default classes;
37
+ }
38
+
39
+ declare module '*.mdx' {
40
+ const component: any;
41
+ export default component;
42
+ }
@@ -0,0 +1,21 @@
1
+ import * as React from 'react';
2
+
3
+ export function useEventEmitter() {
4
+ const listeners = React.useRef(new Map());
5
+
6
+ const emit = React.useCallback((event, data) => {
7
+ const eventListenersToEmit = listeners.current.get(event) || [];
8
+ eventListenersToEmit.forEach(listener => listener(data));
9
+ }, [])
10
+
11
+ const on = React.useCallback((event, listener) => {
12
+ const eventListeners = listeners.current.get(event) || [];
13
+ listeners.current.set(event, [...eventListeners, listener]);
14
+ return () => {
15
+ const eventListenersToRemove = listeners.current.get(event) || [];
16
+ listeners.current.set(event, eventListenersToRemove.filter(l => l !== listener));
17
+ }
18
+ })
19
+
20
+ return {emit, on};
21
+ }
package/useSignal.js ADDED
@@ -0,0 +1,13 @@
1
+ import * as React from 'react';
2
+ import {SignalContext} from './SignalProvider';
3
+
4
+ export function useSignal() {
5
+
6
+ const context = React.useContext(SignalContext);
7
+
8
+ if (context === undefined) {
9
+ throw new Error('useSignal must be used within a SignalProvider');
10
+ }
11
+
12
+ return context;
13
+ }
@@ -0,0 +1,35 @@
1
+ import * as React from "react";
2
+ import { SignalContext } from "./SignalProvider";
3
+
4
+ // Hook pro poslech na více signálů (pole eventNames)
5
+ export function useSignalListeners(eventNames, callback) {
6
+ // Uložíme callback do refu, aby se aktualizoval při každé změně
7
+ const listenerCallback = React.useRef(callback);
8
+ const { on } = React.useContext(SignalContext);
9
+
10
+ // Přihlášení a odhlášení od signálů
11
+ React.useEffect(() => {
12
+ // Ujistíme se, že ref se aktualizuje kdykoli se změní callback
13
+ listenerCallback.current = callback;
14
+
15
+ // Funkce, která se spustí, když přijde signál
16
+ const onSignal = (data) => {
17
+ if (eventNames.includes(data.eventName)) {
18
+ listenerCallback.current(data);
19
+ }
20
+ };
21
+
22
+ const unsubscribe = on("Signal", onSignal);
23
+
24
+ // Při unmountu komponenty se odhlásíme od poslechu na signál
25
+ return () => {
26
+ unsubscribe();
27
+ };
28
+ }, [eventNames, callback, on]); // Přidáme eventNames jako závislost
29
+ }
30
+
31
+ // Hook pro poslech na jeden signál
32
+ export function useSignalListener(eventName, callback) {
33
+ // Voláme rozšířenou funkci s jedním eventName zabaleným do pole
34
+ useSignalListeners([eventName], callback);
35
+ }