yaver-feedback-react-native 0.8.8 → 0.8.9
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/dist/YaverFeedback.js +131 -14
- package/package.json +1 -1
- package/src/YaverFeedback.ts +128 -14
package/dist/YaverFeedback.js
CHANGED
|
@@ -13,10 +13,13 @@ const preferences_1 = require("./preferences");
|
|
|
13
13
|
// (mobile/ios/Yaver/YaverInfo.{swift,m} + Android counterpart); a
|
|
14
14
|
// standalone app bundled by its own developer has no such module.
|
|
15
15
|
// When the SDK is loaded through Yaver's Hermes-push guest runtime we
|
|
16
|
-
//
|
|
17
|
-
//
|
|
18
|
-
//
|
|
19
|
-
// the
|
|
16
|
+
// run in HOST MODE: dormant by default (no shake detector, no auto
|
|
17
|
+
// BlackBox, no QuickActionIcon — Yaver's host shell owns those), but
|
|
18
|
+
// we DO register a DeviceEventEmitter listener so Yaver's overlay can
|
|
19
|
+
// flip the SDK live at runtime. When the user shakes inside the guest
|
|
20
|
+
// app and taps "Feedback" on the Yaver overlay, AppDelegate dispatches
|
|
21
|
+
// `yaverFeedback:startReport` into this bridge; the listener wakes the
|
|
22
|
+
// SDK and opens the modal in-place over the running guest UI.
|
|
20
23
|
function isRunningInsideYaverHost() {
|
|
21
24
|
try {
|
|
22
25
|
return !!react_native_1.NativeModules?.YaverInfo;
|
|
@@ -25,11 +28,108 @@ function isRunningInsideYaverHost() {
|
|
|
25
28
|
return false;
|
|
26
29
|
}
|
|
27
30
|
}
|
|
28
|
-
//
|
|
29
|
-
//
|
|
30
|
-
// by
|
|
31
|
-
//
|
|
32
|
-
|
|
31
|
+
// Two distinct compile-time modes for a guest app like sfmg / talos:
|
|
32
|
+
//
|
|
33
|
+
// YAVER_HOST_MODE — bundled by Yaver's agent (/dev/build-native) for
|
|
34
|
+
// loading inside Yaver mobile. SDK code is in the
|
|
35
|
+
// bundle but boots PASSIVE: no shake detector, no
|
|
36
|
+
// auto-BlackBox, no container UI. Yaver's host
|
|
37
|
+
// overlay owns the shake gesture; when the user
|
|
38
|
+
// taps "Feedback" on Yaver's overlay, AppDelegate
|
|
39
|
+
// dispatches yaverFeedback:hostActivate into this
|
|
40
|
+
// bridge and the SDK runtime-flips active for a
|
|
41
|
+
// single feedback session.
|
|
42
|
+
//
|
|
43
|
+
// YAVER_SDK_MODE — sfmg's own standalone TestFlight / Play Store
|
|
44
|
+
// build, with the Yaver SDK embedded. SDK boots
|
|
45
|
+
// active: shake → modal directly, no Yaver host
|
|
46
|
+
// involved. Default for normal `expo build`.
|
|
47
|
+
//
|
|
48
|
+
// Both can be forced at build time via process.env. When neither is
|
|
49
|
+
// set, fall back to runtime detection: if the YaverInfo native module
|
|
50
|
+
// exists (we're inside Yaver), assume HOST_MODE; else SDK_MODE. This
|
|
51
|
+
// keeps older bundles (built before the agent learned to set the env)
|
|
52
|
+
// working unchanged.
|
|
53
|
+
const YAVER_HOST_MODE_BUILD = (() => {
|
|
54
|
+
try {
|
|
55
|
+
const v = process.env?.YAVER_HOST_MODE;
|
|
56
|
+
return v === 'true' || v === '1' || v === true || v === 1;
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
})();
|
|
62
|
+
const YAVER_SDK_MODE_BUILD = (() => {
|
|
63
|
+
try {
|
|
64
|
+
const v = process.env?.YAVER_SDK_MODE;
|
|
65
|
+
return v === 'true' || v === '1' || v === true || v === 1;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return false;
|
|
69
|
+
}
|
|
70
|
+
})();
|
|
71
|
+
// Effective mode after considering build flags AND runtime detection.
|
|
72
|
+
const IS_HOST_MODE = YAVER_HOST_MODE_BUILD ||
|
|
73
|
+
(!YAVER_SDK_MODE_BUILD && isRunningInsideYaverHost());
|
|
74
|
+
// Tracks whether we've been runtime-activated by the host (sfmg-in-Yaver
|
|
75
|
+
// case). Independent of `enabled` so we can tell "host turned us on for
|
|
76
|
+
// one shot" apart from "developer toggled enabled programmatically".
|
|
77
|
+
let hostActivated = false;
|
|
78
|
+
// Host-activation listener. Always registered when in HOST mode so a
|
|
79
|
+
// Yaver overlay tap can wake the SDK even before the guest's
|
|
80
|
+
// YaverFeedback.init() runs. AppDelegate (mobile/ios/Yaver/AppDelegate.
|
|
81
|
+
// swift::handleFeedbackTap) sends `yaverFeedback:startReport` into the
|
|
82
|
+
// guest bridge when the user picks Feedback on the shake overlay.
|
|
83
|
+
//
|
|
84
|
+
// Activation flow:
|
|
85
|
+
// 1. Try Yaver's existing bearer (NativeModules.YaverInfo.
|
|
86
|
+
// inheritedAuthToken, populated by Yaver mobile's auth.ts on
|
|
87
|
+
// sign-in). Validate against /auth/validate before trusting.
|
|
88
|
+
// 2. If valid: setAuthToken + open feedback modal in-place (the
|
|
89
|
+
// modal already supports hot reload, screenshot, vibing chat).
|
|
90
|
+
// 3. If missing or invalid: open the SDK's own login screen.
|
|
91
|
+
if (IS_HOST_MODE) {
|
|
92
|
+
try {
|
|
93
|
+
const { DeviceEventEmitter } = require('react-native');
|
|
94
|
+
DeviceEventEmitter.addListener('yaverFeedback:startReport', () => {
|
|
95
|
+
hostActivated = true;
|
|
96
|
+
enabled = true;
|
|
97
|
+
void (async () => {
|
|
98
|
+
const yi = react_native_1.NativeModules?.YaverInfo;
|
|
99
|
+
const inheritedToken = String(yi?.inheritedAuthToken || '').trim();
|
|
100
|
+
const inheritedAgent = String(yi?.inheritedAgentUrl || '').trim();
|
|
101
|
+
const inheritedDevice = String(yi?.inheritedDeviceId || '').trim();
|
|
102
|
+
if (inheritedToken) {
|
|
103
|
+
// Lazy-import auth.ts so module load doesn't drag the auth
|
|
104
|
+
// network code into the active set when the SDK is dormant.
|
|
105
|
+
const { validateToken } = require('./auth');
|
|
106
|
+
const user = await validateToken(inheritedToken).catch(() => null);
|
|
107
|
+
if (user) {
|
|
108
|
+
// Seed config + connect the SDK to the host's auth.
|
|
109
|
+
if (!config) {
|
|
110
|
+
YaverFeedback.init({
|
|
111
|
+
authToken: inheritedToken,
|
|
112
|
+
agentUrl: inheritedAgent || undefined,
|
|
113
|
+
preferredDeviceId: inheritedDevice || undefined,
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
await YaverFeedback.setAuthToken(inheritedToken);
|
|
117
|
+
await YaverFeedback.startReport();
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// No token, or token invalid — fall through to the SDK's own
|
|
122
|
+
// login screen. The user picks an OAuth provider; on success
|
|
123
|
+
// the modal continues with the new token.
|
|
124
|
+
if (!config) {
|
|
125
|
+
YaverFeedback.init({});
|
|
126
|
+
}
|
|
127
|
+
YaverFeedback.showLogin();
|
|
128
|
+
})();
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
catch { /* react-native unavailable in jsdom unit tests */ }
|
|
132
|
+
}
|
|
33
133
|
let config = null;
|
|
34
134
|
let enabled = false;
|
|
35
135
|
let p2pClient = null;
|
|
@@ -102,17 +202,34 @@ class YaverFeedback {
|
|
|
102
202
|
* via `YaverDiscovery` on the first `startReport()` call.
|
|
103
203
|
*/
|
|
104
204
|
static init(cfg) {
|
|
105
|
-
if (YAVER_HOST_SUPPRESS) {
|
|
106
|
-
// Running inside Yaver's super-host — yield to Yaver's native UX.
|
|
107
|
-
enabled = false;
|
|
108
|
-
return;
|
|
109
|
-
}
|
|
110
205
|
config = {
|
|
111
206
|
trigger: 'shake',
|
|
112
207
|
maxRecordingDuration: 120,
|
|
113
208
|
autoLogin: true,
|
|
114
209
|
...cfg,
|
|
115
210
|
};
|
|
211
|
+
if (IS_HOST_MODE) {
|
|
212
|
+
// sfmg / talos / etc. running inside Yaver mobile (compile-time
|
|
213
|
+
// YAVER_HOST_MODE or runtime-detected). Store config so a later
|
|
214
|
+
// host activation (yaverFeedback:startReport from AppDelegate)
|
|
215
|
+
// can open the modal — but skip the side effects Yaver's host
|
|
216
|
+
// shell owns: shake detector, auto-BlackBox, QuickActionIcon.
|
|
217
|
+
enabled = false;
|
|
218
|
+
// Configure auth endpoints + strict-native-auth even in passive
|
|
219
|
+
// mode so a host-activated session uses the same login routing
|
|
220
|
+
// the standalone path would.
|
|
221
|
+
(0, auth_1.configureAuthEndpoints)({
|
|
222
|
+
convexSiteUrl: cfg.authConvexSiteUrl,
|
|
223
|
+
webBaseUrl: cfg.authWebBaseUrl,
|
|
224
|
+
});
|
|
225
|
+
(0, auth_1.setStrictNativeAuth)(cfg.strictNativeAuth === true);
|
|
226
|
+
if (!config.convexUrl) {
|
|
227
|
+
config.convexUrl = cfg.authConvexSiteUrl ?? auth_1.DEFAULT_CONVEX_SITE_URL;
|
|
228
|
+
}
|
|
229
|
+
maxErrors = cfg.maxCapturedErrors ?? 5;
|
|
230
|
+
errorBuffer = [];
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
116
233
|
if (config.disableShakeGesture && (!config.quickIcon || config.quickIcon === 'auto')) {
|
|
117
234
|
config.quickIcon = 'always';
|
|
118
235
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "yaver-feedback-react-native",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.9",
|
|
4
4
|
"description": "Visual feedback SDK for Yaver \u2014 bug reports, screen recording, voice annotations, and local-first developer workflows",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
package/src/YaverFeedback.ts
CHANGED
|
@@ -28,10 +28,13 @@ import {
|
|
|
28
28
|
// (mobile/ios/Yaver/YaverInfo.{swift,m} + Android counterpart); a
|
|
29
29
|
// standalone app bundled by its own developer has no such module.
|
|
30
30
|
// When the SDK is loaded through Yaver's Hermes-push guest runtime we
|
|
31
|
-
//
|
|
32
|
-
//
|
|
33
|
-
//
|
|
34
|
-
// the
|
|
31
|
+
// run in HOST MODE: dormant by default (no shake detector, no auto
|
|
32
|
+
// BlackBox, no QuickActionIcon — Yaver's host shell owns those), but
|
|
33
|
+
// we DO register a DeviceEventEmitter listener so Yaver's overlay can
|
|
34
|
+
// flip the SDK live at runtime. When the user shakes inside the guest
|
|
35
|
+
// app and taps "Feedback" on the Yaver overlay, AppDelegate dispatches
|
|
36
|
+
// `yaverFeedback:startReport` into this bridge; the listener wakes the
|
|
37
|
+
// SDK and opens the modal in-place over the running guest UI.
|
|
35
38
|
function isRunningInsideYaverHost(): boolean {
|
|
36
39
|
try {
|
|
37
40
|
return !!(NativeModules as any)?.YaverInfo;
|
|
@@ -40,11 +43,105 @@ function isRunningInsideYaverHost(): boolean {
|
|
|
40
43
|
}
|
|
41
44
|
}
|
|
42
45
|
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
// by
|
|
46
|
-
//
|
|
47
|
-
|
|
46
|
+
// Two distinct compile-time modes for a guest app like sfmg / talos:
|
|
47
|
+
//
|
|
48
|
+
// YAVER_HOST_MODE — bundled by Yaver's agent (/dev/build-native) for
|
|
49
|
+
// loading inside Yaver mobile. SDK code is in the
|
|
50
|
+
// bundle but boots PASSIVE: no shake detector, no
|
|
51
|
+
// auto-BlackBox, no container UI. Yaver's host
|
|
52
|
+
// overlay owns the shake gesture; when the user
|
|
53
|
+
// taps "Feedback" on Yaver's overlay, AppDelegate
|
|
54
|
+
// dispatches yaverFeedback:hostActivate into this
|
|
55
|
+
// bridge and the SDK runtime-flips active for a
|
|
56
|
+
// single feedback session.
|
|
57
|
+
//
|
|
58
|
+
// YAVER_SDK_MODE — sfmg's own standalone TestFlight / Play Store
|
|
59
|
+
// build, with the Yaver SDK embedded. SDK boots
|
|
60
|
+
// active: shake → modal directly, no Yaver host
|
|
61
|
+
// involved. Default for normal `expo build`.
|
|
62
|
+
//
|
|
63
|
+
// Both can be forced at build time via process.env. When neither is
|
|
64
|
+
// set, fall back to runtime detection: if the YaverInfo native module
|
|
65
|
+
// exists (we're inside Yaver), assume HOST_MODE; else SDK_MODE. This
|
|
66
|
+
// keeps older bundles (built before the agent learned to set the env)
|
|
67
|
+
// working unchanged.
|
|
68
|
+
const YAVER_HOST_MODE_BUILD = (() => {
|
|
69
|
+
try {
|
|
70
|
+
const v = (process.env as any)?.YAVER_HOST_MODE;
|
|
71
|
+
return v === 'true' || v === '1' || v === true || v === 1;
|
|
72
|
+
} catch { return false; }
|
|
73
|
+
})();
|
|
74
|
+
const YAVER_SDK_MODE_BUILD = (() => {
|
|
75
|
+
try {
|
|
76
|
+
const v = (process.env as any)?.YAVER_SDK_MODE;
|
|
77
|
+
return v === 'true' || v === '1' || v === true || v === 1;
|
|
78
|
+
} catch { return false; }
|
|
79
|
+
})();
|
|
80
|
+
|
|
81
|
+
// Effective mode after considering build flags AND runtime detection.
|
|
82
|
+
const IS_HOST_MODE =
|
|
83
|
+
YAVER_HOST_MODE_BUILD ||
|
|
84
|
+
(!YAVER_SDK_MODE_BUILD && isRunningInsideYaverHost());
|
|
85
|
+
|
|
86
|
+
// Tracks whether we've been runtime-activated by the host (sfmg-in-Yaver
|
|
87
|
+
// case). Independent of `enabled` so we can tell "host turned us on for
|
|
88
|
+
// one shot" apart from "developer toggled enabled programmatically".
|
|
89
|
+
let hostActivated = false;
|
|
90
|
+
|
|
91
|
+
// Host-activation listener. Always registered when in HOST mode so a
|
|
92
|
+
// Yaver overlay tap can wake the SDK even before the guest's
|
|
93
|
+
// YaverFeedback.init() runs. AppDelegate (mobile/ios/Yaver/AppDelegate.
|
|
94
|
+
// swift::handleFeedbackTap) sends `yaverFeedback:startReport` into the
|
|
95
|
+
// guest bridge when the user picks Feedback on the shake overlay.
|
|
96
|
+
//
|
|
97
|
+
// Activation flow:
|
|
98
|
+
// 1. Try Yaver's existing bearer (NativeModules.YaverInfo.
|
|
99
|
+
// inheritedAuthToken, populated by Yaver mobile's auth.ts on
|
|
100
|
+
// sign-in). Validate against /auth/validate before trusting.
|
|
101
|
+
// 2. If valid: setAuthToken + open feedback modal in-place (the
|
|
102
|
+
// modal already supports hot reload, screenshot, vibing chat).
|
|
103
|
+
// 3. If missing or invalid: open the SDK's own login screen.
|
|
104
|
+
if (IS_HOST_MODE) {
|
|
105
|
+
try {
|
|
106
|
+
const { DeviceEventEmitter } = require('react-native');
|
|
107
|
+
DeviceEventEmitter.addListener('yaverFeedback:startReport', () => {
|
|
108
|
+
hostActivated = true;
|
|
109
|
+
enabled = true;
|
|
110
|
+
void (async () => {
|
|
111
|
+
const yi = (NativeModules as any)?.YaverInfo;
|
|
112
|
+
const inheritedToken = String(yi?.inheritedAuthToken || '').trim();
|
|
113
|
+
const inheritedAgent = String(yi?.inheritedAgentUrl || '').trim();
|
|
114
|
+
const inheritedDevice = String(yi?.inheritedDeviceId || '').trim();
|
|
115
|
+
if (inheritedToken) {
|
|
116
|
+
// Lazy-import auth.ts so module load doesn't drag the auth
|
|
117
|
+
// network code into the active set when the SDK is dormant.
|
|
118
|
+
const { validateToken } = require('./auth');
|
|
119
|
+
const user = await validateToken(inheritedToken).catch(() => null);
|
|
120
|
+
if (user) {
|
|
121
|
+
// Seed config + connect the SDK to the host's auth.
|
|
122
|
+
if (!config) {
|
|
123
|
+
YaverFeedback.init({
|
|
124
|
+
authToken: inheritedToken,
|
|
125
|
+
agentUrl: inheritedAgent || undefined,
|
|
126
|
+
preferredDeviceId: inheritedDevice || undefined,
|
|
127
|
+
} as FeedbackConfig);
|
|
128
|
+
}
|
|
129
|
+
await YaverFeedback.setAuthToken(inheritedToken);
|
|
130
|
+
await YaverFeedback.startReport();
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
// No token, or token invalid — fall through to the SDK's own
|
|
135
|
+
// login screen. The user picks an OAuth provider; on success
|
|
136
|
+
// the modal continues with the new token.
|
|
137
|
+
if (!config) {
|
|
138
|
+
YaverFeedback.init({} as FeedbackConfig);
|
|
139
|
+
}
|
|
140
|
+
YaverFeedback.showLogin();
|
|
141
|
+
})();
|
|
142
|
+
});
|
|
143
|
+
} catch { /* react-native unavailable in jsdom unit tests */ }
|
|
144
|
+
}
|
|
48
145
|
|
|
49
146
|
let config: FeedbackConfig | null = null;
|
|
50
147
|
let enabled = false;
|
|
@@ -126,17 +223,34 @@ export class YaverFeedback {
|
|
|
126
223
|
* via `YaverDiscovery` on the first `startReport()` call.
|
|
127
224
|
*/
|
|
128
225
|
static init(cfg: FeedbackConfig): void {
|
|
129
|
-
if (YAVER_HOST_SUPPRESS) {
|
|
130
|
-
// Running inside Yaver's super-host — yield to Yaver's native UX.
|
|
131
|
-
enabled = false;
|
|
132
|
-
return;
|
|
133
|
-
}
|
|
134
226
|
config = {
|
|
135
227
|
trigger: 'shake',
|
|
136
228
|
maxRecordingDuration: 120,
|
|
137
229
|
autoLogin: true,
|
|
138
230
|
...cfg,
|
|
139
231
|
};
|
|
232
|
+
if (IS_HOST_MODE) {
|
|
233
|
+
// sfmg / talos / etc. running inside Yaver mobile (compile-time
|
|
234
|
+
// YAVER_HOST_MODE or runtime-detected). Store config so a later
|
|
235
|
+
// host activation (yaverFeedback:startReport from AppDelegate)
|
|
236
|
+
// can open the modal — but skip the side effects Yaver's host
|
|
237
|
+
// shell owns: shake detector, auto-BlackBox, QuickActionIcon.
|
|
238
|
+
enabled = false;
|
|
239
|
+
// Configure auth endpoints + strict-native-auth even in passive
|
|
240
|
+
// mode so a host-activated session uses the same login routing
|
|
241
|
+
// the standalone path would.
|
|
242
|
+
configureAuthEndpoints({
|
|
243
|
+
convexSiteUrl: cfg.authConvexSiteUrl,
|
|
244
|
+
webBaseUrl: cfg.authWebBaseUrl,
|
|
245
|
+
});
|
|
246
|
+
setStrictNativeAuth(cfg.strictNativeAuth === true);
|
|
247
|
+
if (!config.convexUrl) {
|
|
248
|
+
config.convexUrl = cfg.authConvexSiteUrl ?? DEFAULT_CONVEX_SITE_URL;
|
|
249
|
+
}
|
|
250
|
+
maxErrors = cfg.maxCapturedErrors ?? 5;
|
|
251
|
+
errorBuffer = [];
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
140
254
|
if (config.disableShakeGesture && (!config.quickIcon || config.quickIcon === 'auto')) {
|
|
141
255
|
config.quickIcon = 'always';
|
|
142
256
|
}
|