@everframe/react-native 1.5.0 → 1.6.0
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/EverframeRN.podspec +1 -1
- package/README.md +136 -17
- package/android/build.gradle.kts +12 -19
- package/android/src/main/java/dev/everframe/rn/EverframeModule.kt +16 -962
- package/dist/NativeEverframe.d.ts +7 -67
- package/dist/index.d.ts +63 -178
- package/dist/index.js +23 -23
- package/dist/index.web.d.ts +2 -2
- package/dist/{launch-C8wbMunK.d.ts → launch-aXtOOfNU.d.ts} +1 -2
- package/ios/Sources/EverframeBridge.swift +16 -456
- package/ios/Sources/EverframeEventEmitter.swift +9 -126
- package/ios/Sources/EverframeModule.mm +2 -52
- package/package.json +4 -4
- package/src/NativeEverframe.ts +11 -107
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
// SPDX-License-Identifier: MIT
|
|
2
2
|
// SPDX-FileCopyrightText: 2026 ScriptX
|
|
3
3
|
//
|
|
4
|
-
//
|
|
4
|
+
// RCTEventEmitter subclass for the bridge's native → JS events (today: the
|
|
5
|
+
// extra-resolver ask, spec 2026-09-17).
|
|
5
6
|
//
|
|
6
7
|
// iOS RN event emission requires an `RCTEventEmitter` subclass (one per
|
|
7
8
|
// module — the base class enforces a single supportedEvents() list). We
|
|
@@ -23,63 +24,20 @@
|
|
|
23
24
|
// Objective-C base.
|
|
24
25
|
//
|
|
25
26
|
// Threading: `sendEvent(withName:body:)` is thread-safe across the RN core
|
|
26
|
-
// (the internal bridge enqueues the event on the JS thread)
|
|
27
|
-
//
|
|
28
|
-
// we forward straight to the emitter without a main-thread hop.
|
|
27
|
+
// (the internal bridge enqueues the event on the JS thread); we forward
|
|
28
|
+
// straight to the emitter without a main-thread hop.
|
|
29
29
|
//
|
|
30
|
-
// Event names — duplicated in JS facade `src/
|
|
30
|
+
// Event names — duplicated in the JS facade (`src/runtime.ts`). Keep in
|
|
31
|
+
// lock-step.
|
|
31
32
|
import Foundation
|
|
32
33
|
import React
|
|
33
34
|
|
|
34
35
|
@objc(EverframeEventEmitter)
|
|
35
36
|
public final class EverframeEventEmitter: RCTEventEmitter {
|
|
36
37
|
|
|
37
|
-
/// Event name forwarded as `everframe.companion.state`.
|
|
38
|
-
/// Payload: String — one of "unpaired" | "paired" | "report_in_progress" | "phone_disconnected".
|
|
39
|
-
public static let stateEvent = "everframe.companion.state"
|
|
40
|
-
|
|
41
|
-
/// Event name forwarded as `everframe.companion.pairUrl`.
|
|
42
|
-
/// Payload: String | NSNull (NSNull crosses to JS as `null`).
|
|
43
|
-
public static let pairUrlEvent = "everframe.companion.pairUrl"
|
|
44
|
-
|
|
45
|
-
/// Event name forwarded as `everframe.companion.code`.
|
|
46
|
-
/// The short display code returned by `/api/companion/announce`
|
|
47
|
-
/// (spec 2026-08-07) — hosts render it beside the QR so a team member
|
|
48
|
-
/// reading the TV screen can pick this device out of the dashboard list.
|
|
49
|
-
/// Payload: String | NSNull (NSNull crosses to JS as `null`).
|
|
50
|
-
public static let codeEvent = "everframe.companion.code"
|
|
51
|
-
|
|
52
|
-
/// Event name forwarded as `everframe.companion.attachedUserName`.
|
|
53
|
-
/// The dashboard member who attached to this device; nil on an ordinary
|
|
54
|
-
/// QR bond. Payload: String | NSNull (NSNull crosses to JS as `null`).
|
|
55
|
-
public static let attachedUserNameEvent = "everframe.companion.attachedUserName"
|
|
56
|
-
|
|
57
|
-
/// Event name forwarded as `everframe.companion.resolvedName` (naming spec
|
|
58
|
-
/// 2026-08-24). The server-resolved device display name for THIS device
|
|
59
|
-
/// (e.g. an org-configured friendly name), or nil before the first
|
|
60
|
-
/// successful announce / when discovery never ran. Payload: String |
|
|
61
|
-
/// NSNull (NSNull crosses to JS as `null`).
|
|
62
|
-
public static let resolvedNameEvent = "everframe.companion.resolvedName"
|
|
63
|
-
|
|
64
|
-
/// Event name forwarded as `everframe.companion.attachChallenge` (spec
|
|
65
|
-
/// 2026-08-19). The pending dashboard-initiated attach-PIN challenge, or
|
|
66
|
-
/// nil when none is outstanding. Forwarded in every `attachPinUi` mode,
|
|
67
|
-
/// including `'builtin'` (which renders the PIN natively AND still
|
|
68
|
-
/// fires this event) — it's only NEEDED by hosts configured with
|
|
69
|
-
/// `'custom'`, which must read it to build their own surface.
|
|
70
|
-
/// Payload: `{ code, requestedByName, ttlMs }` | NSNull.
|
|
71
|
-
public static let attachChallengeEvent = "everframe.companion.attachChallenge"
|
|
72
|
-
|
|
73
|
-
/// Fired when a `report.request` arrives from the paired phone. The event
|
|
74
|
-
/// and the bridge's brief wait are the companion's JS-ready handshake
|
|
75
|
-
/// (see CompanionCaptureBridge.awaitJsReactTreeAttach).
|
|
76
|
-
/// Payload: String — the correlation_id of the inbound request.
|
|
77
|
-
public static let reportRequestedEvent = "everframe.companion.reportRequested"
|
|
78
|
-
|
|
79
38
|
/// Fired right before native drains pending attachments for ANY report
|
|
80
|
-
/// (spec 2026-09-17 setExtra-resolver)
|
|
81
|
-
///
|
|
82
|
-
/// too, since both funnel through `Everframe.shared.report.open()` →
|
|
39
|
+
/// (spec 2026-09-17 setExtra-resolver): the plain in-app `openReporter()`
|
|
40
|
+
/// and native shake both trigger this, since both funnel through `Everframe.shared.report.open()` →
|
|
83
41
|
/// `__consumePendingAttachments()`. Only fires when JS has a resolver
|
|
84
42
|
/// CURRENTLY registered (`EverframeBridge.setExtraResolverActive`) — see
|
|
85
43
|
/// `EverframeBridge.awaitJsExtraResolve`. Payload: String — the
|
|
@@ -111,89 +69,14 @@ public final class EverframeEventEmitter: RCTEventEmitter {
|
|
|
111
69
|
/// adding it here is the exact failure this comment exists to prevent.
|
|
112
70
|
public override func supportedEvents() -> [String] {
|
|
113
71
|
return [
|
|
114
|
-
Self.stateEvent,
|
|
115
|
-
Self.pairUrlEvent,
|
|
116
|
-
Self.codeEvent,
|
|
117
|
-
Self.attachedUserNameEvent,
|
|
118
|
-
Self.resolvedNameEvent,
|
|
119
|
-
Self.attachChallengeEvent,
|
|
120
|
-
Self.reportRequestedEvent,
|
|
121
72
|
Self.extraResolveRequestedEvent,
|
|
122
73
|
]
|
|
123
74
|
}
|
|
124
75
|
|
|
125
76
|
// MARK: - Static helpers used by EverframeBridge
|
|
126
77
|
|
|
127
|
-
/// Forward a companion-state change to JS. Silently dropped if no
|
|
128
|
-
/// emitter instance is alive (e.g. before any listeners attached). The
|
|
129
|
-
/// RN base class also warns when `sendEvent` fires with zero listeners,
|
|
130
|
-
/// which is the documented behavior — our JS facade attaches listeners
|
|
131
|
-
/// inside `useCompanion()`, so the warning surfaces only when no React
|
|
132
|
-
/// subtree is rendering the companion screen.
|
|
133
|
-
@objc public static func sendState(_ state: String) {
|
|
134
|
-
shared?.sendEvent(withName: stateEvent, body: state)
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
/// Forward a pairUrl change to JS. `nil` is passed across the bridge as
|
|
138
|
-
/// `NSNull()` so the JS handler receives an actual `null`. Note: pairUrl is
|
|
139
|
-
/// now nulled only on socket close, so this `nil` branch fires rarely —
|
|
140
|
-
/// hosts drive QR teardown off `state`, the reliably-delivered signal.
|
|
141
|
-
@objc public static func sendPairUrl(_ url: String?) {
|
|
142
|
-
if let url = url {
|
|
143
|
-
shared?.sendEvent(withName: pairUrlEvent, body: url)
|
|
144
|
-
} else {
|
|
145
|
-
shared?.sendEvent(withName: pairUrlEvent, body: NSNull())
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/// Forward an announce display-code change to JS. `nil` crosses as
|
|
150
|
-
/// `NSNull()` so the JS handler receives an actual `null` — that happens
|
|
151
|
-
/// when companion discovery was never attempted (no SDK key configured),
|
|
152
|
-
/// when the announce failed, or when the relay socket closed terminally.
|
|
153
|
-
@objc public static func sendCode(_ code: String?) {
|
|
154
|
-
if let code = code {
|
|
155
|
-
shared?.sendEvent(withName: codeEvent, body: code)
|
|
156
|
-
} else {
|
|
157
|
-
shared?.sendEvent(withName: codeEvent, body: NSNull())
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
/// Forward an attached-dashboard-user change to JS. `nil` crosses as
|
|
162
|
-
/// `NSNull()` — an ordinary QR bond carries no `companion_user` block, so
|
|
163
|
-
/// the nil branch is the common case here (unlike `sendPairUrl`).
|
|
164
|
-
@objc public static func sendAttachedUserName(_ name: String?) {
|
|
165
|
-
if let name = name {
|
|
166
|
-
shared?.sendEvent(withName: attachedUserNameEvent, body: name)
|
|
167
|
-
} else {
|
|
168
|
-
shared?.sendEvent(withName: attachedUserNameEvent, body: NSNull())
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
/// Forward a resolved device display-name change to JS (naming spec
|
|
173
|
-
/// 2026-08-24). `nil` crosses as `NSNull()` — before the first successful
|
|
174
|
-
/// announce, or when discovery never ran, this is the common case.
|
|
175
|
-
@objc public static func sendResolvedName(_ name: String?) {
|
|
176
|
-
if let name = name {
|
|
177
|
-
shared?.sendEvent(withName: resolvedNameEvent, body: name)
|
|
178
|
-
} else {
|
|
179
|
-
shared?.sendEvent(withName: resolvedNameEvent, body: NSNull())
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/// Forward a `report.request` correlation id to JS. JS signals the
|
|
184
|
-
/// bridge back via `signalCompanionReportRequestReady` when it is
|
|
185
|
-
/// ready for capture to proceed.
|
|
186
|
-
@objc public static func sendReportRequested(_ correlationId: String) {
|
|
187
|
-
shared?.sendEvent(withName: reportRequestedEvent, body: correlationId)
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
/// Forward an attach-PIN challenge to JS. nil crosses as NSNull() → JS null.
|
|
191
|
-
@objc public static func sendAttachChallenge(_ payload: [String: Any]?) {
|
|
192
|
-
shared?.sendEvent(withName: attachChallengeEvent, body: payload ?? NSNull())
|
|
193
|
-
}
|
|
194
|
-
|
|
195
78
|
/// Forward an extra-resolver ask correlation id to JS (spec 2026-09-17
|
|
196
|
-
/// setExtra-resolver).
|
|
79
|
+
/// setExtra-resolver). JS signals
|
|
197
80
|
/// the bridge back via `signalExtraResolverReady` when it has pushed a
|
|
198
81
|
/// freshly resolved value (or given up) for this correlation id.
|
|
199
82
|
@objc public static func sendExtraResolveRequested(_ correlationId: String) {
|
|
@@ -187,33 +187,11 @@ RCT_EXPORT_MODULE(Everframe)
|
|
|
187
187
|
BOOL installIdentifierDisabled = opts.installIdentifierDisabled().value_or(false);
|
|
188
188
|
// `crashReportingDisabled` — same `std::optional<bool>` shape. Absent keeps capture on.
|
|
189
189
|
BOOL crashReportingDisabled = opts.crashReportingDisabled().value_or(false);
|
|
190
|
-
// `attachPinUi` (spec 2026-08-19) is a plain optional STRING field —
|
|
191
|
-
// `opts.attachPinUi()` returns a nullable NSString*, same shape as
|
|
192
|
-
// `opts.sdkKey()` above, NOT the `std::optional<bool>` shape
|
|
193
|
-
// `networkBodiesDisabled()` uses. `EverframeBridge.configure` coerces a
|
|
194
|
-
// nil/unrecognised value to `.builtin`.
|
|
195
|
-
NSString *attachPinUi = opts.attachPinUi();
|
|
196
|
-
// `companionDeviceId` (naming spec 2026-08-24) is a plain optional STRING
|
|
197
|
-
// field — same nullable-NSString* shape as `attachPinUi` above, not the
|
|
198
|
-
// `std::optional<bool>` shape `networkBodiesDisabled()` uses.
|
|
199
|
-
NSString *companionDeviceId = opts.companionDeviceId();
|
|
200
|
-
// `companionBadgeEnabled`/`companionBadgePosition` (naming spec
|
|
201
|
-
// 2026-08-24, controller ruling / Task 6b) — flat fields on ConfigOpts;
|
|
202
|
-
// RN codegen cannot express the nested `{enabled, position}` shape the JS
|
|
203
|
-
// facade's `RuntimeConfig.companionBadge` uses, so `extractBridgeConfig`
|
|
204
|
-
// flattens it before it crosses. `companionBadgeEnabled()` is
|
|
205
|
-
// `std::optional<bool>`, same shape as `networkBodiesDisabled()` above;
|
|
206
|
-
// absent defaults to `true` (badge shown), matching
|
|
207
|
-
// `CompanionBadgeOptions.enabled`'s own default. `companionBadgePosition()`
|
|
208
|
-
// is a nullable NSString*, same shape as `attachPinUi`/`companionDeviceId`
|
|
209
|
-
// above; `EverframeBridge` coerces nil/unrecognised to `.bottomRight`.
|
|
210
|
-
BOOL companionBadgeEnabled = opts.companionBadgeEnabled().value_or(true);
|
|
211
190
|
BOOL shakeToReportEnabled = opts.shakeToReportEnabled().value_or(true);
|
|
212
191
|
BOOL quickCaptureEnabled = opts.quickCaptureEnabled().value_or(true);
|
|
213
192
|
// Crash-only session switch (spec 2026-10-12) — `std::optional<bool>`, same shape as
|
|
214
193
|
// `networkBodiesDisabled()`. Absent means a normal report session.
|
|
215
194
|
BOOL reporterDisabled = opts.reporterDisabled().value_or(false);
|
|
216
|
-
NSString *companionBadgePosition = opts.companionBadgePosition();
|
|
217
195
|
// Inline reporter theme (reporter branding spec 2026-08-25, RN slice) —
|
|
218
196
|
// 8 flat optional STRING fields on ConfigOpts (RN codegen cannot express
|
|
219
197
|
// the nested `theme: { … }` shape the JS facade's `RuntimeConfig.theme`
|
|
@@ -254,12 +232,8 @@ RCT_EXPORT_MODULE(Everframe)
|
|
|
254
232
|
networkBodiesDisabled:networkBodiesDisabled
|
|
255
233
|
installIdentifierDisabled:installIdentifierDisabled
|
|
256
234
|
crashReportingDisabled:crashReportingDisabled
|
|
257
|
-
attachPinUi:attachPinUi
|
|
258
|
-
companionDeviceId:companionDeviceId
|
|
259
|
-
companionBadgeEnabled:companionBadgeEnabled
|
|
260
235
|
shakeToReportEnabled:shakeToReportEnabled
|
|
261
236
|
quickCaptureEnabled:quickCaptureEnabled
|
|
262
|
-
companionBadgePosition:companionBadgePosition
|
|
263
237
|
theme:(theme.count > 0 ? theme : nil)
|
|
264
238
|
vitalsEnabled:vitalsEnabled
|
|
265
239
|
vitalsSampleRate:vitalsSampleRate
|
|
@@ -391,8 +365,7 @@ RCT_EXPORT_MODULE(Everframe)
|
|
|
391
365
|
[EverframeBridge setExtraResolverActive:active];
|
|
392
366
|
}
|
|
393
367
|
|
|
394
|
-
// JS handshake ack
|
|
395
|
-
// exactly. Releases `EverframeBridge.awaitJsExtraResolve`'s bounded wait for
|
|
368
|
+
// JS handshake ack. Releases `EverframeBridge.awaitJsExtraResolve`'s bounded wait for
|
|
396
369
|
// this correlation id.
|
|
397
370
|
- (void)signalExtraResolverReady:(NSString *)correlationId {
|
|
398
371
|
[EverframeBridge signalExtraResolverReady:(correlationId ?: @"")];
|
|
@@ -562,33 +535,10 @@ RCT_EXPORT_MODULE(Everframe)
|
|
|
562
535
|
return @([EverframeBridge captureHandledException:(crashJson ?: @"")]);
|
|
563
536
|
}
|
|
564
537
|
|
|
565
|
-
// MARK: - startCompanion / stopCompanion (Plan 06.2-11)
|
|
566
|
-
|
|
567
|
-
// Opens a relay WS connection against the build-time-baked ingest URL
|
|
568
|
-
// (sdk-ios IngestEndpoint.url) and starts forwarding `Everframe.shared
|
|
569
|
-
// .companion` signals (state + pairUrl) to JS via the
|
|
570
|
-
// `EverframeEventEmitter` RCTEventEmitter subclass.
|
|
571
|
-
- (void)startCompanion {
|
|
572
|
-
[EverframeBridge startCompanion:@""];
|
|
573
|
-
}
|
|
574
|
-
|
|
575
|
-
- (void)stopCompanion {
|
|
576
|
-
[EverframeBridge stopCompanion];
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
// MARK: - signalCompanionReportRequestReady(correlationId)
|
|
580
|
-
|
|
581
|
-
// Companion handshake: JS calls this when it is ready for capture to
|
|
582
|
-
// proceed, releasing the native bridge's bounded wait
|
|
583
|
-
// (CompanionCaptureBridge.awaitJsReactTreeAttach).
|
|
584
|
-
- (void)signalCompanionReportRequestReady:(NSString *)correlationId {
|
|
585
|
-
[EverframeBridge signalCompanionReportRequestReady:(correlationId ?: @"")];
|
|
586
|
-
}
|
|
587
|
-
|
|
588
538
|
// MARK: - addListener / removeListeners (RN NativeEventEmitter contract)
|
|
589
539
|
//
|
|
590
540
|
// These are intentional no-ops on `EverframeModule` — the JS facade
|
|
591
|
-
// (`src/
|
|
541
|
+
// (`src/events.ts`) constructs `NativeEventEmitter(NativeModules
|
|
592
542
|
// .EverframeEventEmitter)`, NOT NativeModules.Everframe, so the real
|
|
593
543
|
// addListener/removeListeners traffic flows to the `EverframeEventEmitter`
|
|
594
544
|
// subclass via RCTEventEmitter's built-in implementations. We still need
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@everframe/react-native",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "React Native SDK for Everframe — AI-ready in-app bug reporting, bridging the native iOS and Android reporter to your RN app. Supports phone, Apple TV, and Android TV.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Scriptx, UAB",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"dependencies": {
|
|
101
101
|
"bippy": "^0.5.39",
|
|
102
102
|
"zod": "^4.3.0",
|
|
103
|
-
"@everframe/react": "^1.
|
|
103
|
+
"@everframe/react": "^1.6.0"
|
|
104
104
|
},
|
|
105
105
|
"devDependencies": {
|
|
106
106
|
"@arethetypeswrong/cli": "^0.18.0",
|
|
@@ -113,8 +113,8 @@
|
|
|
113
113
|
"react-native-url-polyfill": "4.0.0",
|
|
114
114
|
"tsup": "^8.0.0",
|
|
115
115
|
"vitest": "^4.0.0",
|
|
116
|
-
"@everframe/sdk-core": "0.6.
|
|
117
|
-
"@everframe/protocol": "0.10.
|
|
116
|
+
"@everframe/sdk-core": "0.6.3",
|
|
117
|
+
"@everframe/protocol": "0.10.1"
|
|
118
118
|
},
|
|
119
119
|
"codegenConfig": {
|
|
120
120
|
"name": "EverframeSpec",
|
package/src/NativeEverframe.ts
CHANGED
|
@@ -14,8 +14,7 @@
|
|
|
14
14
|
// It is imported from our structural compatibility alias because React
|
|
15
15
|
// Native 0.87 hides the old deep-import declaration by default.)
|
|
16
16
|
// - The 4 report methods below (configure/openReporter/registerSensitiveRect/
|
|
17
|
-
// setExtra)
|
|
18
|
-
// COMPLETE surface — adding another report method requires a phase
|
|
17
|
+
// setExtra) were the COMPLETE surface — adding another report method requires a phase
|
|
19
18
|
// D-decision (Plan 02/03 native impls inherit codegen headers).
|
|
20
19
|
// `addBreadcrumb` (Plan 4 / Task 14) IS that new D-decision: a manual
|
|
21
20
|
// breadcrumb escape hatch forwarding to the native singleton's coercion
|
|
@@ -50,24 +49,6 @@
|
|
|
50
49
|
// `UnsafeObject`, same split `addBreadcrumb`'s `data` already uses.
|
|
51
50
|
// `T | null` stays forbidden; CLEARING is expressed by calling with no
|
|
52
51
|
// argument.
|
|
53
|
-
// `ConfigOpts.attachPinUi` (spec 2026-08-19) is the next D-decision after
|
|
54
|
-
// that — a flat optional STRING, not `'builtin' | 'custom' | 'off'`: RN
|
|
55
|
-
// codegen cannot express a string-literal union in a struct field any more
|
|
56
|
-
// than `setUser`'s D-decision above could express one as a bridge method
|
|
57
|
-
// parameter type — same codegen ceiling, different call site (a
|
|
58
|
-
// `ConfigOpts` field here, rather than a whole method's parameter there).
|
|
59
|
-
// Unlike `setUser`'s escape hatch, this one needs no `UnsafeObject`
|
|
60
|
-
// widening: it's a plain `string`, which codegen already handles natively
|
|
61
|
-
// in a struct field — the union is only lost at the TYPE level, not the
|
|
62
|
-
// VALUE level. Each native side re-parses the string into its own
|
|
63
|
-
// `AttachPinUi` enum (`enum AttachPinUi: String` on iOS, `enum class
|
|
64
|
-
// AttachPinUi` on Android) and coerces anything unrecognised — including
|
|
65
|
-
// an absent field, which decodes as `undefined` and never reaches native
|
|
66
|
-
// at all — to `.builtin`/`BUILTIN`. This rides `configureSync()`, not a new
|
|
67
|
-
// bridge method: the flag is a startup-time preference, not a per-call
|
|
68
|
-
// argument, so it belongs beside `sdkKey`/`networkBodiesDisabled` on
|
|
69
|
-
// `ConfigOpts` — see `companion.ts`'s `everframe.companion.attachChallenge`
|
|
70
|
-
// event, the JS-facing half of this same D-decision.
|
|
71
52
|
// Session Vitals (spec 2026-09-06) is the next D-decision after that —
|
|
72
53
|
// FIVE methods (trackPlayer/detachPlayer/recordPlayerEvent/
|
|
73
54
|
// updatePlayerStats/trackVitals) and three flat ConfigOpts fields
|
|
@@ -81,10 +62,8 @@
|
|
|
81
62
|
// `setExtraResolverActive`/`signalExtraResolverReady` (spec 2026-09-17
|
|
82
63
|
// setExtra-resolver) is the next D-decision after that — RN parity for
|
|
83
64
|
// the resolver form of `setExtra` core/web already have. Native asks JS
|
|
84
|
-
// for a fresh value right before draining pending attachments
|
|
85
|
-
//
|
|
86
|
-
// handshake below exactly), bounded and fail-open; see both methods' own
|
|
87
|
-
// doc comments.
|
|
65
|
+
// for a fresh value right before draining pending attachments, bounded
|
|
66
|
+
// and fail-open; see both methods' own doc comments.
|
|
88
67
|
import type { TurboModule } from 'react-native';
|
|
89
68
|
import { TurboModuleRegistry } from 'react-native';
|
|
90
69
|
import type { UnsafeObject } from './codegen-types';
|
|
@@ -141,67 +120,21 @@ export type ConfigOpts = {
|
|
|
141
120
|
* Absent means capture stays on.
|
|
142
121
|
*/
|
|
143
122
|
crashReportingDisabled?: boolean;
|
|
144
|
-
/**
|
|
145
|
-
* Built-in attach-PIN surface mode (spec 2026-08-19): 'builtin' (default —
|
|
146
|
-
* the native SDK presents the code itself), 'custom' (host renders it from
|
|
147
|
-
* onAttachChallenge; the device still announces the capability), 'off'
|
|
148
|
-
* (legacy one-click dashboard attach, no PIN). Flat string, not a union —
|
|
149
|
-
* codegen cannot express string-literal unions; the natives coerce unknown
|
|
150
|
-
* values to 'builtin'.
|
|
151
|
-
*/
|
|
152
|
-
attachPinUi?: string;
|
|
153
|
-
/**
|
|
154
|
-
* Explicit companion device-identity override (naming spec 2026-08-24) —
|
|
155
|
-
* an MDM id or provisioning serial the host already trusts. Hashed
|
|
156
|
-
* (SHA-256 → UUID shape) natively before it ever reaches the announce
|
|
157
|
-
* `device` block — see `CompanionDeviceId.resolve` (iOS) /
|
|
158
|
-
* `CompanionDeviceId.resolve` (Android). Flat optional string, same
|
|
159
|
-
* codegen shape as `attachPinUi` above. `undefined`/absent falls through
|
|
160
|
-
* to each native side's own Keychain/SSAID-then-stored-UUID chain.
|
|
161
|
-
*/
|
|
162
|
-
companionDeviceId?: string;
|
|
163
|
-
/**
|
|
164
|
-
* Companion on-screen name-badge visibility (naming spec 2026-08-24,
|
|
165
|
-
* controller ruling / Task 6b) — "a production app that finds it
|
|
166
|
-
* intrusive turns it off in one line". `undefined`/absent defaults to
|
|
167
|
-
* `true` (badge shown) on both natives, matching
|
|
168
|
-
* `CompanionBadgeOptions.enabled`'s own default. Flat because RN codegen
|
|
169
|
-
* rejects nested objects, same constraint `networkBodiesDisabled` above
|
|
170
|
-
* documents — the host-facing nested `companionBadge: { enabled }` is
|
|
171
|
-
* flattened here by `extractBridgeConfig`.
|
|
172
|
-
*/
|
|
173
|
-
companionBadgeEnabled?: boolean;
|
|
174
|
-
/** Local veto for native mobile shake-to-report. Absent defaults to enabled. */
|
|
123
|
+
/** Local veto for shake opening the reporter (not for shake quick capture). Absent defaults to enabled. */
|
|
175
124
|
shakeToReportEnabled?: boolean;
|
|
176
|
-
/** Local veto for
|
|
125
|
+
/** Local veto for quick capture (simulators, emulators and real phones) and device linking. Absent defaults to enabled. */
|
|
177
126
|
quickCaptureEnabled?: boolean;
|
|
178
127
|
/**
|
|
179
128
|
* Crash-only session switch. `true` turns off every on-device way to open the reporter, keeps
|
|
180
|
-
* network bodies off and samples replay with the server's crash-only rate
|
|
181
|
-
* bond upgrades the session. Flattened by `extractBridgeConfig` from `reporter: { disabled }`.
|
|
129
|
+
* network bodies off and samples replay with the server's crash-only rate. Flattened by `extractBridgeConfig` from `reporter: { disabled }`.
|
|
182
130
|
* Absent means a normal report session.
|
|
183
131
|
*/
|
|
184
132
|
reporterDisabled?: boolean;
|
|
185
|
-
/**
|
|
186
|
-
* Companion on-screen name-badge corner (naming spec 2026-08-24,
|
|
187
|
-
* controller ruling / Task 6b). Flat optional STRING, not a literal
|
|
188
|
-
* union — same codegen ceiling as `attachPinUi` above (RN codegen cannot
|
|
189
|
-
* express a string-literal union in a struct field): the host-facing
|
|
190
|
-
* `RuntimeConfig.companionBadge.position` narrows to the real
|
|
191
|
-
* `'bottom-right' | 'bottom-left' | 'top-right' | 'top-left'` union and
|
|
192
|
-
* `extractBridgeConfig` passes it through unchanged onto this wire field.
|
|
193
|
-
* Each native side re-parses the string into its own
|
|
194
|
-
* `CompanionBadgePosition` enum, coercing `undefined`/an unrecognised
|
|
195
|
-
* value to `.bottomRight`/`BOTTOM_RIGHT` — the same default
|
|
196
|
-
* `CompanionBadgeOptions.position` already uses.
|
|
197
|
-
*/
|
|
198
|
-
companionBadgePosition?: string;
|
|
199
133
|
/**
|
|
200
134
|
* Inline reporter theme (reporter branding spec 2026-08-25, RN slice) —
|
|
201
135
|
* 8 optional `#rrggbb` role strings, flattened from the host-facing nested
|
|
202
136
|
* `RuntimeConfig.theme` by `extractBridgeConfig` (RN codegen cannot express
|
|
203
|
-
* a nested object in a struct field
|
|
204
|
-
* above). Pure passthrough: NO hex validation happens on the RN side; each
|
|
137
|
+
* a nested object in a struct field). Pure passthrough: NO hex validation happens on the RN side; each
|
|
205
138
|
* native ThemeResolver revalidates per-field and ignores invalid values.
|
|
206
139
|
* The theme only ever renders once the server entitles it (server
|
|
207
140
|
* `watermark: false`) — the entitlement gate lives natively and cannot be
|
|
@@ -218,7 +151,7 @@ export type ConfigOpts = {
|
|
|
218
151
|
/**
|
|
219
152
|
* Session Vitals local config (spec 2026-09-06, RN). Three FLAT fields
|
|
220
153
|
* flattened from the host-facing nested `RuntimeConfig.vitals` by
|
|
221
|
-
* `extractBridgeConfig` —
|
|
154
|
+
* `extractBridgeConfig` — RN codegen rejects nested objects.
|
|
222
155
|
* `vitalsEnabled`: absent = follow the dashboard toggle; `false` = opt out
|
|
223
156
|
* locally; `true` never forces it on. `vitalsSampleRate`: [0, 1], min()'d
|
|
224
157
|
* with the server rate, clamped natively; absent = server rate.
|
|
@@ -331,8 +264,7 @@ export interface Spec extends TurboModule {
|
|
|
331
264
|
*/
|
|
332
265
|
setExtraResolverActive(active: boolean): void;
|
|
333
266
|
/**
|
|
334
|
-
*
|
|
335
|
-
* below exactly): called by the JS-side `everframe.extra.resolveRequested`
|
|
267
|
+
* Ack: called by the JS-side `everframe.extra.resolveRequested`
|
|
336
268
|
* listener once it has — IF a resolver is currently registered — invoked
|
|
337
269
|
* it, budgeted the result exactly like `@everframe/sdk-core`'s
|
|
338
270
|
* `resolveClientExtra`, and pushed it through the existing `setExtra`
|
|
@@ -436,39 +368,11 @@ export interface Spec extends TurboModule {
|
|
|
436
368
|
*/
|
|
437
369
|
captureHandledException(crashJson: string): boolean;
|
|
438
370
|
|
|
439
|
-
// ----------------
|
|
440
|
-
//
|
|
441
|
-
// Opens a TV-side RelayWSClient against the build-time-baked ingest URL
|
|
442
|
-
// (IngestEndpoint.url on each native SDK) and forwards
|
|
443
|
-
// `Everframe.shared.companion` state + pairUrl signals to JS via the
|
|
444
|
-
// platform's RN event-emitter (RCTDeviceEventEmitter on Android, a
|
|
445
|
-
// dedicated RCTEventEmitter subclass on iOS). The bridge owns at most ONE
|
|
446
|
-
// RelayWSClient per process.
|
|
447
|
-
//
|
|
448
|
-
// Emitted events (both platforms — see `src/companion.ts`):
|
|
449
|
-
// • `everframe.companion.state` → 'unpaired' | 'paired' | 'report_in_progress' | 'phone_disconnected'
|
|
450
|
-
// • `everframe.companion.pairUrl` → string | null
|
|
451
|
-
// • `everframe.companion.code` → string | null
|
|
452
|
-
// • `everframe.companion.attachedUserName` → string | null
|
|
453
|
-
// • `everframe.companion.resolvedName` → string | null (naming spec 2026-08-24)
|
|
454
|
-
// • `everframe.companion.attachChallenge` → { code, requestedByName, ttlMs } | null (spec 2026-08-19)
|
|
455
|
-
startCompanion(): void;
|
|
456
|
-
stopCompanion(): void;
|
|
457
|
-
/**
|
|
458
|
-
* Companion handshake: called by the JS-side `onReportRequested` listener
|
|
459
|
-
* once it is ready for native capture to proceed. (It used to walk the
|
|
460
|
-
* React fiber tree and attach it via `attachReactTree` first; both are
|
|
461
|
-
* gone — spec 2026-08-29.) Releases the native bridge's bounded wait.
|
|
462
|
-
*
|
|
463
|
-
* Bounded: if JS never calls back, the native side times out after
|
|
464
|
-
* ~250ms and captures anyway.
|
|
465
|
-
*/
|
|
466
|
-
signalCompanionReportRequestReady(correlationId: string): void;
|
|
371
|
+
// ---------------- Native event emitter ----------------
|
|
467
372
|
/**
|
|
468
373
|
* RN's `NativeEventEmitter` contract requires `addListener` /
|
|
469
374
|
* `removeListeners` to exist on the underlying native module — RN warns
|
|
470
|
-
* loudly otherwise. Both are intentional no-ops at the spec level
|
|
471
|
-
* native event-emitter subscriptions are installed by `startCompanion`.
|
|
375
|
+
* loudly otherwise. Both are intentional no-ops at the spec level.
|
|
472
376
|
*/
|
|
473
377
|
addListener(eventName: string): void;
|
|
474
378
|
removeListeners(count: number): void;
|