@birdie-so/snippet 1.1.0 → 1.1.1
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 +3 -0
- package/package.json +1 -1
- package/src/index.d.ts +39 -1
- package/src/index.js +52 -5
package/README.md
CHANGED
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -17,11 +17,49 @@ export interface BirdieSettings {
|
|
|
17
17
|
* Callback when Birdie is fully loaded and available as `window.birdie`.
|
|
18
18
|
*/
|
|
19
19
|
onReady?: (birdie: BirdieAPI) => void;
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* If true (default), guarantees at most one active handler per event.
|
|
23
|
+
* Re-registering the same event replaces the previous handler (prevents double fires on remount/HMR).
|
|
24
|
+
*/
|
|
25
|
+
singleHandlerPerEvent?: boolean;
|
|
20
26
|
}
|
|
21
27
|
|
|
28
|
+
// export interface BirdieAPI {
|
|
29
|
+
// metadata: BirdieMetadata;
|
|
30
|
+
// on(event: 'start' | 'stop' | 'captureStarted' | 'captureStopped' | 'pause' | 'restart' | 'resume' | 'recorderClose' | 'recorderOpen' | 'recordingSent' | 'error', callback: (data: any) => void): void;
|
|
31
|
+
// }
|
|
32
|
+
|
|
22
33
|
export interface BirdieAPI {
|
|
23
34
|
metadata: BirdieMetadata;
|
|
24
|
-
|
|
35
|
+
|
|
36
|
+
on(
|
|
37
|
+
event:
|
|
38
|
+
| 'start' | 'stop' | 'captureStarted' | 'captureStopped'
|
|
39
|
+
| 'pause' | 'restart' | 'resume'
|
|
40
|
+
| 'recorderClose' | 'recorderOpen'
|
|
41
|
+
| 'recordingSent' | 'error',
|
|
42
|
+
callback: (data: any) => void
|
|
43
|
+
): void;
|
|
44
|
+
|
|
45
|
+
off(
|
|
46
|
+
event:
|
|
47
|
+
| 'start' | 'stop' | 'captureStarted' | 'captureStopped'
|
|
48
|
+
| 'pause' | 'restart' | 'resume'
|
|
49
|
+
| 'recorderClose' | 'recorderOpen'
|
|
50
|
+
| 'recordingSent' | 'error',
|
|
51
|
+
callback: (data: any) => void
|
|
52
|
+
): void;
|
|
53
|
+
|
|
54
|
+
/** Auto-unsubscribes after the first event emission. */
|
|
55
|
+
onOnce(
|
|
56
|
+
event:
|
|
57
|
+
| 'start' | 'stop' | 'captureStarted' | 'captureStopped'
|
|
58
|
+
| 'pause' | 'restart' | 'resume'
|
|
59
|
+
| 'recorderClose' | 'recorderOpen'
|
|
60
|
+
| 'recordingSent' | 'error',
|
|
61
|
+
callback: (data: any) => void
|
|
62
|
+
): void;
|
|
25
63
|
}
|
|
26
64
|
|
|
27
65
|
/**
|
package/src/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
let _readyCallbacks = [];
|
|
2
2
|
|
|
3
|
-
export function initBirdie({ clientId, metadata, onReady, ...otherSettings }) {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
export function initBirdie({ clientId, metadata, onReady, singleHandlerPerEvent = true, ...otherSettings }) {
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
|
|
7
7
|
if (!clientId) {
|
|
8
8
|
console.error('[Birdie] Missing required clientId in initBirdie()');
|
|
9
9
|
return;
|
|
@@ -21,7 +21,12 @@ export function initBirdie({ clientId, metadata, onReady, ...otherSettings }) {
|
|
|
21
21
|
Object.assign(window.birdieSettings, otherSettings);
|
|
22
22
|
|
|
23
23
|
window.birdieSettings.onBirdieReady = () => {
|
|
24
|
-
|
|
24
|
+
try {
|
|
25
|
+
installBirdieGuards({ singleHandlerPerEvent });
|
|
26
|
+
} catch (e) {
|
|
27
|
+
console.error('[Birdie] guard install error', e);
|
|
28
|
+
}
|
|
29
|
+
_readyCallbacks.forEach(cb => { try { cb(window.birdie); } catch (e) { console.error('[Birdie] onReady error', e); } });
|
|
25
30
|
_readyCallbacks = [];
|
|
26
31
|
};
|
|
27
32
|
|
|
@@ -66,3 +71,45 @@ export function getBirdieInstance(onReady) {
|
|
|
66
71
|
return null;
|
|
67
72
|
}
|
|
68
73
|
}
|
|
74
|
+
|
|
75
|
+
// ---- guards & helpers ----
|
|
76
|
+
function installBirdieGuards({ singleHandlerPerEvent }) {
|
|
77
|
+
const b = window.birdie;
|
|
78
|
+
if (!b || b.__pkgGuardsInstalled) return;
|
|
79
|
+
|
|
80
|
+
// Keep originals
|
|
81
|
+
const originalOn = b.on?.bind(b);
|
|
82
|
+
const originalOff = b.off?.bind(b);
|
|
83
|
+
|
|
84
|
+
// Registry of the single active handler per event (for dedupe)
|
|
85
|
+
const singletons = new Map();
|
|
86
|
+
|
|
87
|
+
// Add onOnce
|
|
88
|
+
b.onOnce = (event, cb) => {
|
|
89
|
+
const wrapper = (data) => {
|
|
90
|
+
try { cb(data); } finally { b.off?.(event, wrapper); }
|
|
91
|
+
};
|
|
92
|
+
b.on(event, wrapper);
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
if (singleHandlerPerEvent && originalOn && originalOff) {
|
|
96
|
+
b.on = (event, cb) => {
|
|
97
|
+
// If there was a previous handler for this event installed via this layer, remove it
|
|
98
|
+
const prev = singletons.get(event);
|
|
99
|
+
if (prev) {
|
|
100
|
+
try { originalOff(event, prev); } catch { }
|
|
101
|
+
}
|
|
102
|
+
singletons.set(event, cb);
|
|
103
|
+
return originalOn(event, cb);
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
b.off = (event, cb) => {
|
|
107
|
+
// Clean our registry if the same cb is removed
|
|
108
|
+
const prev = singletons.get(event);
|
|
109
|
+
if (prev === cb) singletons.delete(event);
|
|
110
|
+
return originalOff(event, cb);
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
b.__pkgGuardsInstalled = true;
|
|
115
|
+
}
|