hermes-io 2.2.32 → 2.2.35
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/lib/constants.js +9 -1
- package/lib/context/context.js +101 -1
- package/lib/hooks/index.js +1 -1
- package/lib/hooks/useObserver.js +26 -1
- package/lib/index.js +3 -1
- package/lib/observer/observer.js +16 -1
- package/lib/setupTests.js +26 -1
- package/package.json +1 -1
- package/lib/context/context.test.js +0 -1
- package/lib/hooks/useObserver.test.js +0 -1
- package/lib/observer/observer.test.js +0 -1
package/lib/constants.js
CHANGED
|
@@ -1 +1,9 @@
|
|
|
1
|
-
export default{
|
|
1
|
+
export default {
|
|
2
|
+
CHROME_EXTENSION: "hermes-io-devtools",
|
|
3
|
+
CONTEXT_SNAPSHOT: "CONTEXT_SNAPSHOT",
|
|
4
|
+
START_RECORDING: "START_RECORDING",
|
|
5
|
+
STOP_RECORDING: "STOP_RECORDING",
|
|
6
|
+
SET_CONTEXT: "SET_CONTEXT",
|
|
7
|
+
LOAD_RECORDING: "LOAD_RECORDING",
|
|
8
|
+
RESET_RECORDING: "RESET_RECORDING"
|
|
9
|
+
};
|
package/lib/context/context.js
CHANGED
|
@@ -1 +1,101 @@
|
|
|
1
|
-
import
|
|
1
|
+
import t from "../constants";
|
|
2
|
+
let e = false;
|
|
3
|
+
let s = [];
|
|
4
|
+
export const listenersMap = new Map();
|
|
5
|
+
function n() {
|
|
6
|
+
e = true;
|
|
7
|
+
}
|
|
8
|
+
function i() {
|
|
9
|
+
e = false;
|
|
10
|
+
}
|
|
11
|
+
function a() {
|
|
12
|
+
s = [];
|
|
13
|
+
e = false;
|
|
14
|
+
}
|
|
15
|
+
function r({ id: e = "" }) {
|
|
16
|
+
const n = s.find((t)=>t._internalId === e);
|
|
17
|
+
if (n) {
|
|
18
|
+
if (n.isFromExternalRecording) {
|
|
19
|
+
const t = listenersMap.get(n.listener);
|
|
20
|
+
return t?.({
|
|
21
|
+
value: JSON.parse(n.value)
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
return n.listener(n.value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function l(e) {
|
|
28
|
+
s = e.recording.map((t = {})=>({
|
|
29
|
+
...t,
|
|
30
|
+
isFromExternalRecording: true,
|
|
31
|
+
_internalId: t.id
|
|
32
|
+
}));
|
|
33
|
+
}
|
|
34
|
+
const o = {
|
|
35
|
+
[t.START_RECORDING]: n,
|
|
36
|
+
[t.STOP_RECORDING]: i,
|
|
37
|
+
[t.RESET_RECORDING]: a,
|
|
38
|
+
[t.SET_CONTEXT]: r,
|
|
39
|
+
[t.LOAD_RECORDING]: l
|
|
40
|
+
};
|
|
41
|
+
const c = (e)=>{
|
|
42
|
+
try {
|
|
43
|
+
const { source: s, payload: n } = e.data;
|
|
44
|
+
if (s === t.CHROME_EXTENSION) {
|
|
45
|
+
if (n?.type) return o[n.type](n);
|
|
46
|
+
o[n]();
|
|
47
|
+
}
|
|
48
|
+
} catch (t) {
|
|
49
|
+
console.error(t);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
window.addEventListener("message", c);
|
|
53
|
+
export class Context {
|
|
54
|
+
constructor(n){
|
|
55
|
+
this.id = null;
|
|
56
|
+
this._internalId = null;
|
|
57
|
+
this.date = null;
|
|
58
|
+
this.value = null;
|
|
59
|
+
this.listener = null;
|
|
60
|
+
this.stackTrace = null;
|
|
61
|
+
this.update = ({ value: t, listener: s })=>{
|
|
62
|
+
this.date = new Date();
|
|
63
|
+
this.value = t;
|
|
64
|
+
this.stackTrace = this.getStackTrace();
|
|
65
|
+
this.listener = s;
|
|
66
|
+
if (e) {
|
|
67
|
+
this.sendSnapshot();
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
this.sendSnapshot = ()=>{
|
|
71
|
+
const e = this.takeSnapshot();
|
|
72
|
+
const { listener: n, stackTrace: i, value: a, date: r, _internalId: l } = e;
|
|
73
|
+
s.push(e);
|
|
74
|
+
window.postMessage({
|
|
75
|
+
type: t.CONTEXT_SNAPSHOT,
|
|
76
|
+
payload: {
|
|
77
|
+
value: JSON.stringify(a.value),
|
|
78
|
+
listener: n.name,
|
|
79
|
+
stackTrace: i,
|
|
80
|
+
date: r,
|
|
81
|
+
id: l
|
|
82
|
+
},
|
|
83
|
+
source: "hermes-io"
|
|
84
|
+
}, "*");
|
|
85
|
+
};
|
|
86
|
+
this.takeSnapshot = ()=>{
|
|
87
|
+
return {
|
|
88
|
+
_internalId: crypto.randomUUID(),
|
|
89
|
+
value: this.value,
|
|
90
|
+
date: this.date,
|
|
91
|
+
listener: this.listener,
|
|
92
|
+
stackTrace: this.stackTrace
|
|
93
|
+
};
|
|
94
|
+
};
|
|
95
|
+
this.getStackTrace = ()=>{
|
|
96
|
+
const t = new Error();
|
|
97
|
+
return t.stack;
|
|
98
|
+
};
|
|
99
|
+
this.id = Symbol(n);
|
|
100
|
+
}
|
|
101
|
+
}
|
package/lib/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export*from
|
|
1
|
+
export * from './useObserver';
|
package/lib/hooks/useObserver.js
CHANGED
|
@@ -1 +1,26 @@
|
|
|
1
|
-
import
|
|
1
|
+
import e, { useEffect as t } from "react";
|
|
2
|
+
import { listenersMap as n } from "../context/context";
|
|
3
|
+
export const useObserver = (r)=>{
|
|
4
|
+
t(()=>{
|
|
5
|
+
const { observer: e, listener: t, contexts: o = [] } = r || {};
|
|
6
|
+
function s(e, n) {
|
|
7
|
+
const r = o.length !== 0;
|
|
8
|
+
const s = r && o.find((t)=>t.id === e?.context?.id);
|
|
9
|
+
if (s) {
|
|
10
|
+
e?.context?.update({
|
|
11
|
+
value: e,
|
|
12
|
+
listener: t
|
|
13
|
+
});
|
|
14
|
+
t?.(e, n);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
e?.subscribe?.(s);
|
|
18
|
+
n.set(r.listener.name, r.listener);
|
|
19
|
+
return ()=>{
|
|
20
|
+
n.delete(r.listener.name);
|
|
21
|
+
e?.unsubscribe?.(s);
|
|
22
|
+
};
|
|
23
|
+
}, [
|
|
24
|
+
r
|
|
25
|
+
]);
|
|
26
|
+
};
|
package/lib/index.js
CHANGED
package/lib/observer/observer.js
CHANGED
|
@@ -1 +1,16 @@
|
|
|
1
|
-
export class Observer
|
|
1
|
+
export class Observer {
|
|
2
|
+
subscribe(s) {
|
|
3
|
+
this.subscriptors.push(s);
|
|
4
|
+
}
|
|
5
|
+
unsubscribe(s) {
|
|
6
|
+
this.subscriptors.splice(this.subscriptors.findIndex((r)=>r === s), 1);
|
|
7
|
+
}
|
|
8
|
+
notify(s = {}) {
|
|
9
|
+
return new Promise((r)=>{
|
|
10
|
+
this.subscriptors.forEach((i)=>i(s, r));
|
|
11
|
+
});
|
|
12
|
+
}
|
|
13
|
+
constructor(){
|
|
14
|
+
this.subscriptors = [];
|
|
15
|
+
}
|
|
16
|
+
}
|
package/lib/setupTests.js
CHANGED
|
@@ -1 +1,26 @@
|
|
|
1
|
-
require("@testing-library/jest-dom");
|
|
1
|
+
require("@testing-library/jest-dom");
|
|
2
|
+
jest.setTimeout(6000 * 10);
|
|
3
|
+
Object.defineProperty(globalThis, "crypto", {
|
|
4
|
+
value: {
|
|
5
|
+
randomUUID: ()=>{
|
|
6
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(e) {
|
|
7
|
+
var x = Math.random() * 16 | 0, t = e === "x" ? x : x & 0x3 | 0x8;
|
|
8
|
+
return t.toString(16);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
});
|
|
13
|
+
window.SVGPathElement = jest.fn();
|
|
14
|
+
global.navigator = {
|
|
15
|
+
userAgent: "node"
|
|
16
|
+
};
|
|
17
|
+
window.navigator = {
|
|
18
|
+
userAgent: "node"
|
|
19
|
+
};
|
|
20
|
+
window.matchMedia = window.matchMedia || function() {
|
|
21
|
+
return {
|
|
22
|
+
matches: false,
|
|
23
|
+
addListener: function() {},
|
|
24
|
+
removeListener: function() {}
|
|
25
|
+
};
|
|
26
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hermes-io",
|
|
3
|
-
"version": "2.2.
|
|
3
|
+
"version": "2.2.35",
|
|
4
4
|
"description": "A lightweight javascript library that allows communication between Reactjs components by using the observer pattern and the hook api",
|
|
5
5
|
"main": "./lib/index.js",
|
|
6
6
|
"module": "./lib/index.js",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Context}from"./Context";describe("Context",()=>{let context;beforeEach(()=>{context=new Context("Test Description")});afterEach(()=>{context=null});test("update method updates context properties",()=>{const value="test value";const listener=jest.fn();context.update({value,listener});expect(context.date).toBeInstanceOf(Date);expect(context.value).toBe(value);expect(context.listener).toBe(listener);expect(context.stackTrace).toEqual(expect.any(String))});test("takeSnapshot method returns a snapshot object",()=>{const snapshot=context.takeSnapshot();expect(snapshot._internalId).toEqual(expect.any(String));expect(snapshot.value).toBe(context.value);expect(snapshot.date).toBe(context.date);expect(snapshot.listener).toBe(context.listener);expect(snapshot.stackTrace).toBe(context.stackTrace)});test("getStackTrace method returns stack trace",()=>{const stackTrace=context.getStackTrace();expect(stackTrace).toEqual(expect.any(String))})});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import React from"react";import{renderHook,act}from"@testing-library/react-hooks/dom";import{Context}from"../context/context";import{useObserver}from"./useObserver";import{listenersMap}from"../context/context";const mockObserver={subscribe:jest.fn(),unsubscribe:jest.fn()};describe("useObserver",()=>{let context;beforeEach(()=>{context=new Context("Test")});afterEach(()=>{listenersMap.clear();jest.clearAllMocks();context=null});it("should subscribe and unsubscribe to observer",async()=>{const observer=mockObserver;const listener=jest.fn();const contexts=[context];const props={observer,listener,contexts};let hook;await act(()=>{hook=renderHook(()=>useObserver(props))});const{unmount}=hook;expect(observer.subscribe).toHaveBeenCalledTimes(1);expect(observer.subscribe).toHaveBeenCalledWith(expect.any(Function));act(()=>{unmount()});expect(observer.unsubscribe).toHaveBeenCalledTimes(1);expect(observer.unsubscribe).toHaveBeenCalledWith(expect.any(Function))});it("should add and remove listener from listenersMap",async()=>{const observer=mockObserver;const listener=jest.fn();const props={observer,listener,contexts:[context]};await act(()=>{renderHook(()=>useObserver(props))});expect(listenersMap.get(listener.name)).toBe(listener);act(()=>{listenersMap.clear()});expect(listenersMap.size).toBe(0)});it("should call listener and context update when payload matches context id",async()=>{const observer=mockObserver;const listener=jest.fn();const context={id:"contextId",update:jest.fn()};const payload={context};const props={observer,listener,contexts:[context]};await act(()=>{renderHook(()=>useObserver(props))});const subscribeCallback=observer.subscribe.mock.calls[0][0];const resolve=jest.fn();act(()=>{subscribeCallback(payload,resolve)});expect(context.update).toHaveBeenCalledTimes(1);expect(context.update).toHaveBeenCalledWith({value:payload,listener});expect(listener).toHaveBeenCalledTimes(1);expect(listener).toHaveBeenCalledWith(payload,resolve)})});
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{Observer}from"./observer";describe("Observer",()=>{let observer;let callback1;let callback2;beforeEach(()=>{observer=new Observer;callback1=jest.fn();callback2=jest.fn()});afterEach(()=>{observer=null;callback1=null;callback2=null});it("subscribe and notify",()=>{observer.subscribe(callback1);observer.subscribe(callback2);const args={data:"test"};observer.notify(args);expect(callback1).toHaveBeenCalledWith(args,expect.any(Function));expect(callback2).toHaveBeenCalledWith(args,expect.any(Function))});it("unsubscribe",async()=>{observer.subscribe(callback1);observer.unsubscribe(callback1);expect(callback1).not.toHaveBeenCalled()})});
|