signal-bridge 1.0.4 โ 1.0.6
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/README.md +249 -0
- package/dist/index.d.mts +7 -1
- package/dist/index.d.ts +7 -1
- package/dist/index.global.js +11 -6
- package/dist/index.global.js.map +1 -1
- package/dist/index.js +12 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +11 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/readme.md +0 -1
package/README.md
ADDED
|
@@ -0,0 +1,249 @@
|
|
|
1
|
+
# ๐ Signal Bridge
|
|
2
|
+
|
|
3
|
+
Lightweight communication bridge berbasis `window.postMessage` untuk komunikasi **Host โ Iframe (Remote App)** dengan fitur:
|
|
4
|
+
|
|
5
|
+
* ๐ Optional encryption (AES)
|
|
6
|
+
* ๐ก๏ธ Origin validation (security)
|
|
7
|
+
* ๐ Listener & emitter sederhana
|
|
8
|
+
* โป๏ธ Singleton instance (init hanya sekali)
|
|
9
|
+
* ๐ Support UMD (browser global) + npm package
|
|
10
|
+
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
## ๐ฆ Installation
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install signal-bridge
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
atau via CDN (UMD):
|
|
20
|
+
|
|
21
|
+
```html
|
|
22
|
+
<script src="signal-bridge.umd.js"></script>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## โ๏ธ Konsep Dasar
|
|
28
|
+
|
|
29
|
+
Bridge ini digunakan untuk komunikasi antara:
|
|
30
|
+
|
|
31
|
+
* **Host App** (parent window)
|
|
32
|
+
* **Remote App** (iframe)
|
|
33
|
+
|
|
34
|
+
โ ๏ธ Library ini **hanya berjalan di dalam iframe (remote)**.
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## ๐ง API Overview
|
|
39
|
+
|
|
40
|
+
### 1. Create Bridge (Singleton)
|
|
41
|
+
|
|
42
|
+
```ts
|
|
43
|
+
import { createBridge } from "signal-bridge";
|
|
44
|
+
|
|
45
|
+
const bridge = createBridge("my-app-id", {
|
|
46
|
+
allowedHostOrigins: ["https://host.com"],
|
|
47
|
+
cryptoKey: "SECRET_KEY", // optional
|
|
48
|
+
debug: true
|
|
49
|
+
});
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
> Hanya akan dibuat **1x (singleton)**. Jika dipanggil ulang, akan reuse instance lama.
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
### 2. Init Bridge
|
|
57
|
+
|
|
58
|
+
```ts
|
|
59
|
+
bridge.init();
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Mengirim sinyal `"ready"` ke host.
|
|
63
|
+
|
|
64
|
+
---
|
|
65
|
+
|
|
66
|
+
### 3. Emit Event ke Host
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
bridge.emit("login", {
|
|
70
|
+
userId: 123,
|
|
71
|
+
token: "abc"
|
|
72
|
+
});
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### 4. Listen Event dari Host
|
|
78
|
+
|
|
79
|
+
```ts
|
|
80
|
+
bridge.listen((message) => {
|
|
81
|
+
console.log("Received:", message);
|
|
82
|
+
|
|
83
|
+
if (message.type === "logout") {
|
|
84
|
+
// handle logout
|
|
85
|
+
}
|
|
86
|
+
});
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---
|
|
90
|
+
|
|
91
|
+
### 5. Akses Global Instance
|
|
92
|
+
|
|
93
|
+
Jika ingin akses dari mana saja:
|
|
94
|
+
|
|
95
|
+
```ts
|
|
96
|
+
import { signalBridge } from "signal-bridge";
|
|
97
|
+
|
|
98
|
+
signalBridge().emit("ping", {});
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
โ ๏ธ Pastikan sudah `createBridge().init()` sebelumnya.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
### 6. Reset Bridge
|
|
106
|
+
|
|
107
|
+
```ts
|
|
108
|
+
import { resetBridge } from "signal-bridge";
|
|
109
|
+
|
|
110
|
+
resetBridge();
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## ๐ Security Features
|
|
116
|
+
|
|
117
|
+
### โ
Origin Validation
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
allowedHostOrigins: ["https://host.com"]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Hanya origin ini yang bisa kirim message ke iframe.
|
|
124
|
+
|
|
125
|
+
---
|
|
126
|
+
|
|
127
|
+
### โ
Encryption (Optional)
|
|
128
|
+
|
|
129
|
+
```ts
|
|
130
|
+
cryptoKey: "SECRET_KEY"
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Payload akan otomatis:
|
|
134
|
+
|
|
135
|
+
* Encrypt saat `emit`
|
|
136
|
+
* Decrypt saat `receive`
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## ๐ก Message Format
|
|
141
|
+
|
|
142
|
+
```ts
|
|
143
|
+
type BridgeMessage = {
|
|
144
|
+
type: string;
|
|
145
|
+
payload: any;
|
|
146
|
+
txn: string;
|
|
147
|
+
__source: "host" | "remote";
|
|
148
|
+
__origin?: string;
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
---
|
|
153
|
+
|
|
154
|
+
## ๐ Browser (UMD) Usage
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<script>
|
|
158
|
+
const bridge = window.SignalBridge.createBridge("app-id", {
|
|
159
|
+
allowedHostOrigins: ["https://host.com"]
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
bridge.init();
|
|
163
|
+
|
|
164
|
+
bridge.listen((msg) => {
|
|
165
|
+
console.log(msg);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
bridge.emit("hello", { foo: "bar" });
|
|
169
|
+
</script>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
---
|
|
173
|
+
|
|
174
|
+
## ๐งช Example Flow
|
|
175
|
+
|
|
176
|
+
### Remote (Iframe)
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const bridge = createBridge("child-app", {
|
|
180
|
+
allowedHostOrigins: ["https://parent.com"]
|
|
181
|
+
});
|
|
182
|
+
|
|
183
|
+
bridge.init();
|
|
184
|
+
|
|
185
|
+
bridge.listen((msg) => {
|
|
186
|
+
if (msg.type === "user-data") {
|
|
187
|
+
console.log("User:", msg.payload);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
|
|
191
|
+
bridge.emit("ready", { status: "ok" });
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## โ ๏ธ Important Notes
|
|
197
|
+
|
|
198
|
+
* โ Harus dijalankan di dalam iframe
|
|
199
|
+
* โ `init()` hanya akan trigger sekali (anti duplicate)
|
|
200
|
+
* โ Pastikan origin host sesuai (tidak akan menerima jika tidak match)
|
|
201
|
+
* โ Encryption hanya aktif jika `cryptoKey` di-set
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## ๐ ๏ธ Available Exports
|
|
206
|
+
|
|
207
|
+
```ts
|
|
208
|
+
createBridge
|
|
209
|
+
signalBridge
|
|
210
|
+
resetBridge
|
|
211
|
+
encrypt
|
|
212
|
+
decrypt
|
|
213
|
+
generateKey
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
---
|
|
217
|
+
|
|
218
|
+
## ๐งฉ Internal Behavior
|
|
219
|
+
|
|
220
|
+
* Singleton global instance (`globalBridge`)
|
|
221
|
+
* Anti loop message (`__source` check)
|
|
222
|
+
* Auto ignore invalid message
|
|
223
|
+
* Optional debug logger
|
|
224
|
+
|
|
225
|
+
---
|
|
226
|
+
|
|
227
|
+
## ๐ Source
|
|
228
|
+
|
|
229
|
+
Implementasi utama bisa dilihat di file:
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
---
|
|
234
|
+
|
|
235
|
+
## ๐งโ๐ป Author Notes
|
|
236
|
+
|
|
237
|
+
Dirancang untuk kebutuhan komunikasi microfrontend / iframe integration dengan fokus:
|
|
238
|
+
|
|
239
|
+
* Simple API
|
|
240
|
+
* Secure by default
|
|
241
|
+
* Minimal dependency
|
|
242
|
+
|
|
243
|
+
---
|
|
244
|
+
|
|
245
|
+
## ๐ License
|
|
246
|
+
|
|
247
|
+
MIT License ยฉ 2026 - EkaHersada
|
|
248
|
+
|
|
249
|
+
---
|
package/dist/index.d.mts
CHANGED
|
@@ -37,5 +37,11 @@ declare function setupBridge(appId: string, options: BridgeOptions): {
|
|
|
37
37
|
emit(type: string, payload: any): void;
|
|
38
38
|
destroy(): void;
|
|
39
39
|
};
|
|
40
|
+
declare function initBridge(appId: string, options: BridgeOptions): {
|
|
41
|
+
init(): void;
|
|
42
|
+
listen(handler: Listener): void;
|
|
43
|
+
emit(type: string, payload: any): void;
|
|
44
|
+
destroy(): void;
|
|
45
|
+
};
|
|
40
46
|
|
|
41
|
-
export { base64UrlDecode, base64UrlEncode, createBridge, decrypt, encrypt, generateKey, resetBridge, setupBridge, signalBridge };
|
|
47
|
+
export { base64UrlDecode, base64UrlEncode, createBridge, decrypt, encrypt, generateKey, initBridge, resetBridge, setupBridge, signalBridge };
|
package/dist/index.d.ts
CHANGED
|
@@ -37,5 +37,11 @@ declare function setupBridge(appId: string, options: BridgeOptions): {
|
|
|
37
37
|
emit(type: string, payload: any): void;
|
|
38
38
|
destroy(): void;
|
|
39
39
|
};
|
|
40
|
+
declare function initBridge(appId: string, options: BridgeOptions): {
|
|
41
|
+
init(): void;
|
|
42
|
+
listen(handler: Listener): void;
|
|
43
|
+
emit(type: string, payload: any): void;
|
|
44
|
+
destroy(): void;
|
|
45
|
+
};
|
|
40
46
|
|
|
41
|
-
export { base64UrlDecode, base64UrlEncode, createBridge, decrypt, encrypt, generateKey, resetBridge, setupBridge, signalBridge };
|
|
47
|
+
export { base64UrlDecode, base64UrlEncode, createBridge, decrypt, encrypt, generateKey, initBridge, resetBridge, setupBridge, signalBridge };
|
package/dist/index.global.js
CHANGED
|
@@ -6633,6 +6633,7 @@ var signalBridge = (() => {
|
|
|
6633
6633
|
decrypt: () => decrypt,
|
|
6634
6634
|
encrypt: () => encrypt,
|
|
6635
6635
|
generateKey: () => generateKey,
|
|
6636
|
+
initBridge: () => initBridge,
|
|
6636
6637
|
resetBridge: () => resetBridge,
|
|
6637
6638
|
setupBridge: () => setupBridge,
|
|
6638
6639
|
signalBridge: () => signalBridge
|
|
@@ -6779,17 +6780,21 @@ var signalBridge = (() => {
|
|
|
6779
6780
|
}
|
|
6780
6781
|
};
|
|
6781
6782
|
}
|
|
6783
|
+
function initBridge(appId, options) {
|
|
6784
|
+
const instance = createBridge(appId, options);
|
|
6785
|
+
instance.init();
|
|
6786
|
+
return instance;
|
|
6787
|
+
}
|
|
6782
6788
|
if (typeof window !== "undefined") {
|
|
6783
|
-
window.
|
|
6784
|
-
|
|
6789
|
+
window.signalBridge = Object.assign(signalBridge, {
|
|
6790
|
+
init: initBridge,
|
|
6791
|
+
// ๐ pakai ini (auto init)
|
|
6785
6792
|
createBridge,
|
|
6786
|
-
|
|
6787
|
-
signalBridge,
|
|
6788
|
-
// ๐ NEW
|
|
6793
|
+
reset: resetBridge,
|
|
6789
6794
|
encrypt,
|
|
6790
6795
|
decrypt,
|
|
6791
6796
|
generateKey
|
|
6792
|
-
};
|
|
6797
|
+
});
|
|
6793
6798
|
}
|
|
6794
6799
|
return __toCommonJS(index_exports);
|
|
6795
6800
|
})();
|