@fixback/expo 0.2.0 → 0.3.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.
Files changed (58) hide show
  1. package/README.md +72 -8
  2. package/dist/FeedbackModal.d.ts +10 -2
  3. package/dist/FeedbackModal.js +84 -36
  4. package/dist/FeedbackModal.js.map +1 -0
  5. package/dist/FixbackProvider.d.ts +12 -0
  6. package/dist/FixbackProvider.js +46 -23
  7. package/dist/FixbackProvider.js.map +1 -0
  8. package/dist/adapters.js +73 -23
  9. package/dist/adapters.js.map +1 -0
  10. package/dist/breadcrumbs.d.ts +21 -222
  11. package/dist/breadcrumbs.js +45 -605
  12. package/dist/breadcrumbs.js.map +1 -0
  13. package/dist/client.d.ts +65 -67
  14. package/dist/client.js +288 -151
  15. package/dist/client.js.map +1 -0
  16. package/dist/connect.d.ts +60 -0
  17. package/dist/connect.js +63 -0
  18. package/dist/connect.js.map +1 -0
  19. package/dist/error-capture.d.ts +28 -78
  20. package/dist/error-capture.js +76 -294
  21. package/dist/error-capture.js.map +1 -0
  22. package/dist/http.d.ts +10 -25
  23. package/dist/http.js +15 -12
  24. package/dist/http.js.map +1 -0
  25. package/dist/identity.d.ts +11 -11
  26. package/dist/identity.js +23 -28
  27. package/dist/identity.js.map +1 -0
  28. package/dist/index.d.ts +6 -5
  29. package/dist/index.js +22 -5
  30. package/dist/index.js.map +1 -0
  31. package/dist/origin.d.ts +21 -0
  32. package/dist/origin.js +45 -0
  33. package/dist/origin.js.map +1 -0
  34. package/dist/package.json +3 -0
  35. package/dist/report.d.ts +28 -63
  36. package/dist/report.js +33 -25
  37. package/dist/report.js.map +1 -0
  38. package/dist/reporter-session-store.d.ts +27 -0
  39. package/dist/reporter-session-store.js +53 -0
  40. package/dist/reporter-session-store.js.map +1 -0
  41. package/dist/shake.d.ts +26 -0
  42. package/dist/shake.js +32 -7
  43. package/dist/shake.js.map +1 -0
  44. package/dist/submit.d.ts +21 -12
  45. package/dist/submit.js +24 -41
  46. package/dist/submit.js.map +1 -0
  47. package/dist/tokens.js +5 -1
  48. package/dist/tokens.js.map +1 -0
  49. package/dist/version.d.ts +1 -1
  50. package/dist/version.js +5 -1
  51. package/dist/version.js.map +1 -0
  52. package/package.json +14 -7
  53. package/dist/auto-report-backoff.d.ts +0 -42
  54. package/dist/auto-report-backoff.js +0 -67
  55. package/dist/boot.d.ts +0 -65
  56. package/dist/boot.js +0 -60
  57. package/dist/scrub.d.ts +0 -55
  58. package/dist/scrub.js +0 -184
package/README.md CHANGED
@@ -1,21 +1,24 @@
1
1
  # @fixback/expo
2
2
 
3
- The [Fixback](https://github.com/wemuda/fixback) capture SDK for **Expo / React
3
+ The [Fixback](https://fixback.dev) capture SDK for **Expo / React
4
4
  Native apps**: shake the device to open a feedback composer, and every report
5
5
  ships with trace Evidence — console output, network metadata, screen changes —
6
6
  plus an optional screenshot. Uncaught JS errors report themselves
7
7
  (`source: auto`), exactly like the web SDK.
8
8
 
9
+ > 📖 **Full documentation: [docs.fixback.dev/sdk/expo](https://docs.fixback.dev/sdk/expo)** — guides, concepts, and the complete API reference.
10
+
9
11
  ## Install
10
12
 
11
13
  ```bash
12
14
  npm install @fixback/expo
13
- npx expo install expo-sensors react-native-view-shot @react-native-async-storage/async-storage
15
+ npx expo install expo-sensors react-native-view-shot @react-native-async-storage/async-storage expo-web-browser expo-secure-store
14
16
  ```
15
17
 
16
- The three Expo-ecosystem packages are peer dependencies (they carry the native
17
- modules for the accelerometer, screenshots, and id persistence). All of them
18
- work in Expo Go.
18
+ The five Expo-ecosystem packages are peer dependencies (they carry the native
19
+ modules for the accelerometer, screenshots, anonymous-id persistence, the in-app
20
+ auth session that powers Connect, and the secure store the Reporter session lives
21
+ in). All of them work in Expo Go.
19
22
 
20
23
  ## Quick start
21
24
 
@@ -78,6 +81,55 @@ trackScreen(routeName);
78
81
  Each change records a `navigation` trace crumb, and the active screen names
79
82
  the report's URL (`<origin>/<screen>`).
80
83
 
84
+ ## Connect — reporting as an account
85
+
86
+ A Reporter is a Fixback **Account** ([ADR-0032](https://github.com/wemuda/fixback/blob/master/docs/adr/0032-reporters-are-accounts-that-connect-through-the-platform.md)).
87
+ The composer's identity row shows **"Anonymous · Sign in"**; tapping it opens an
88
+ **in-app auth session** to Fixback's connect page — the same doors as the web:
89
+ Google, GitHub, Sign in with Apple, and magic link — and returns to your app
90
+ through the `returnUrl` you declare in `init`. The SDK exchanges the returned code
91
+ for a **Reporter session** stored in **SecureStore**, and the composer then shows
92
+ the Account's name and tier. A Member of the owning Org reports at the `internal`
93
+ tier.
94
+
95
+ ```tsx
96
+ <FixbackProvider
97
+ options={{
98
+ key: "pk_…",
99
+ origin: "https://com.acme.myapp",
100
+ // A scheme or universal link your app handles; its origin must be on the
101
+ // Project's allowed origins. Register the scheme in app.json (`scheme`).
102
+ returnUrl: "myapp://fixback-connect",
103
+ }}
104
+ >
105
+ ```
106
+
107
+ `signIn` / `signOut` / `identity` are on the `useFixback()` handle and the
108
+ module-level `Fixback`, so you can put them on your own settings screen:
109
+
110
+ ```tsx
111
+ import { Fixback } from "@fixback/expo";
112
+
113
+ await Fixback.signIn(); // opens the connect page, binds the Account
114
+ Fixback.identity(); // { status: "anonymous" } | { status: "connected", name, email, tier }
115
+ await Fixback.signOut(); // revokes the session and clears SecureStore
116
+ ```
117
+
118
+ On an **Invited-** or **Internal-gated** Project the shake gesture stays disarmed
119
+ until a Connect makes the Account eligible — so a private beta shows nothing to a
120
+ signed-out visitor. Enter it by calling `Fixback.signIn()` from your own UI.
121
+
122
+ ### Sign in with Apple
123
+
124
+ Because Connect offers **Google** sign-in inside an iOS app, Apple's App Store
125
+ Review Guideline 4.8 requires an equivalent **Sign in with Apple** option for apps
126
+ distributed on the App Store. Fixback's connect page **offers Sign in with Apple**
127
+ alongside Google, GitHub, and the magic link ([ADR-0037](https://github.com/wemuda/fixback/blob/master/docs/adr/0037-sign-in-with-apple-as-a-connect-door.md)),
128
+ so an iOS app that uses Connect satisfies Guideline 4.8. Nothing is required of
129
+ your app — the door is on the platform's connect page, which the SDK already
130
+ opens. Choosing Apple's **Hide My Email** signs the person in under a private
131
+ relay address, which becomes its own Fixback Account.
132
+
81
133
  ## Options
82
134
 
83
135
  | Option | Default | What it does |
@@ -85,7 +137,7 @@ the report's URL (`<origin>/<screen>`).
85
137
  | `key` | — | The Project's publishable key (required). |
86
138
  | `origin` | — | The origin sent on every request (required in practice — see above). |
87
139
  | `apiUrl` | `https://api.fixback.dev` | Self-hosted Fixback API base. |
88
- | `signedIdentity` | — | A server-minted identity JWT (`internal` tier). |
140
+ | `hostIdentity` | — | A server-minted identity JWT (`internal` tier). |
89
141
  | `reporterName` / `reporterEmail` | — | Display-only reporter fields. |
90
142
  | `capture` | server config | `{ console?, network? }` per-stream trace toggles. |
91
143
  | `autoCapture` | `true` | Automatic uncaught-error reports. |
@@ -94,6 +146,9 @@ the report's URL (`<origin>/<screen>`).
94
146
  | `scrub` | `true` | The built-in URL/PII scrubbers. |
95
147
  | `beforeBreadcrumb` | — | Filter/edit trace entries at the source. |
96
148
  | `shake` | on | `{ enabled?, thresholdG?, minPeaks?, windowMs?, minGapMs?, cooldownMs?, sampleIntervalMs? }`. |
149
+ | `enabled` | `true` | Master gate — `false` keeps the SDK completely dormant (no boot call, nothing instrumented). |
150
+ | `release` | — | The build identifier captured errors symbolicate against; set it to the value `fixback sourcemaps upload --release` used. |
151
+ | `environment` | — | The deploy environment (`production` / `staging` / …). |
97
152
 
98
153
  ## Privacy
99
154
 
@@ -110,8 +165,17 @@ remains the programmatic choke point.
110
165
  ## What's not here (yet)
111
166
 
112
167
  Invite redemption (deep links), element annotation/drawing, session replay,
113
- unhandled-promise-rejection and native-crash capture. See the repo's
114
- `docs/specs/0004-expo-reporter-sdk.md` and ADR-0021 for the full contract.
168
+ unhandled-promise-rejection and native-crash capture. See the
169
+ [Expo SDK reference](https://docs.fixback.dev/reference/expo-sdk) for the full
170
+ contract.
171
+
172
+ ## Packaging
173
+
174
+ The published build is **CommonJS** (`dist/`, with a nested `{"type":"commonjs"}`
175
+ manifest), exactly like `@fixback/node` and `@fixback/sdk-core`. Metro resolves
176
+ CommonJS natively, and so do Node-based tools — Jest, an Expo config plugin, a
177
+ script that `require()`s the package — which the previous extensionless-ESM
178
+ output could not.
115
179
 
116
180
  ## License
117
181
 
@@ -1,13 +1,15 @@
1
1
  /**
2
2
  * The feedback **composer** — the mobile counterpart of the web overlay's
3
3
  * report panel (spec 0004 §C), styled in the Signal language from the vendored
4
- * token slice. Opens on shake (or `present()`), collects Kind + comment, shows
4
+ * token slice. Opens on shake (or `present()`); carries the identity row (Connect,
5
+ * ADR-0032) and collects a comment (no Kind — analysis classifies, ADR-0023), shows
5
6
  * the exact screenshot that will ship (removable — the mobile privacy stance,
6
7
  * ADR-0021), and submits through the client the provider hands in.
7
8
  *
8
9
  * Deliberately thin: every decision beyond local UI state lives in
9
10
  * `client.ts`, which is where the behaviour is unit-tested.
10
11
  */
12
+ import type { ReporterIdentity } from "@fixback/sdk-core";
11
13
  import type { ComposerDraft } from "./client";
12
14
  import type { ScreenshotFile, SubmitResult } from "./submit";
13
15
  /** What the provider wires into the composer. */
@@ -15,9 +17,15 @@ export interface FeedbackModalProps {
15
17
  readonly visible: boolean;
16
18
  /** The screenshot captured as the composer opened, if any. */
17
19
  readonly screenshot: ScreenshotFile | null;
20
+ /** The Reporter identity shown in the composer's identity row (ADR-0032). */
21
+ readonly identity: ReporterIdentity;
22
+ /** Start a Connect from the identity row's "Sign in" (ADR-0032). */
23
+ readonly onSignIn: () => void;
24
+ /** Clear the Reporter session from the identity row's "Sign out". */
25
+ readonly onSignOut: () => void;
18
26
  readonly onDismiss: () => void;
19
27
  readonly onSubmit: (draft: ComposerDraft) => Promise<SubmitResult>;
20
28
  /** Release a screenshot the Reporter removed or abandoned (spec 0004 §C). */
21
29
  readonly onDiscardScreenshot?: (screenshot: ScreenshotFile) => void;
22
30
  }
23
- export declare function FeedbackModal({ visible, screenshot, onDismiss, onSubmit, onDiscardScreenshot, }: FeedbackModalProps): import("react").JSX.Element;
31
+ export declare function FeedbackModal({ visible, screenshot, identity, onSignIn, onSignOut, onDismiss, onSubmit, onDiscardScreenshot, }: FeedbackModalProps): import("react").JSX.Element;
@@ -1,27 +1,31 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FeedbackModal = FeedbackModal;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
2
5
  /**
3
6
  * The feedback **composer** — the mobile counterpart of the web overlay's
4
7
  * report panel (spec 0004 §C), styled in the Signal language from the vendored
5
- * token slice. Opens on shake (or `present()`), collects Kind + comment, shows
8
+ * token slice. Opens on shake (or `present()`); carries the identity row (Connect,
9
+ * ADR-0032) and collects a comment (no Kind — analysis classifies, ADR-0023), shows
6
10
  * the exact screenshot that will ship (removable — the mobile privacy stance,
7
11
  * ADR-0021), and submits through the client the provider hands in.
8
12
  *
9
13
  * Deliberately thin: every decision beyond local UI state lives in
10
14
  * `client.ts`, which is where the behaviour is unit-tested.
11
15
  */
12
- import { useEffect, useRef, useState } from "react";
13
- import { ActivityIndicator, Image, KeyboardAvoidingView, Modal, Platform, Pressable, StyleSheet, Text, TextInput, View, } from "react-native";
14
- import { signal } from "./tokens";
15
- const MONO_FONT = Platform.select({ ios: "Menlo", default: "monospace" });
16
+ const react_1 = require("react");
17
+ const react_native_1 = require("react-native");
18
+ const tokens_1 = require("./tokens");
19
+ const MONO_FONT = react_native_1.Platform.select({ ios: "Menlo", default: "monospace" });
16
20
  /** How long the "Sent" confirmation lingers before the composer closes. */
17
21
  const SENT_DISMISS_MS = 900;
18
- export function FeedbackModal({ visible, screenshot, onDismiss, onSubmit, onDiscardScreenshot, }) {
19
- const [comment, setComment] = useState("");
20
- const [includeScreenshot, setIncludeScreenshot] = useState(true);
21
- const [phase, setPhase] = useState("compose");
22
- const dismissTimer = useRef(null);
22
+ function FeedbackModal({ visible, screenshot, identity, onSignIn, onSignOut, onDismiss, onSubmit, onDiscardScreenshot, }) {
23
+ const [comment, setComment] = (0, react_1.useState)("");
24
+ const [includeScreenshot, setIncludeScreenshot] = (0, react_1.useState)(true);
25
+ const [phase, setPhase] = (0, react_1.useState)("compose");
26
+ const dismissTimer = (0, react_1.useRef)(null);
23
27
  // A fresh open starts a fresh draft.
24
- useEffect(() => {
28
+ (0, react_1.useEffect)(() => {
25
29
  if (visible) {
26
30
  setComment("");
27
31
  setIncludeScreenshot(true);
@@ -71,22 +75,22 @@ export function FeedbackModal({ visible, screenshot, onDismiss, onSubmit, onDisc
71
75
  onDiscardScreenshot?.(screenshot);
72
76
  setIncludeScreenshot(false);
73
77
  }
74
- return (_jsx(Modal, { visible: visible, transparent: true, animationType: "slide", onRequestClose: dismiss, children: _jsxs(View, { style: styles.backdrop, children: [_jsx(Pressable, { style: styles.backdropTouch, accessibilityLabel: "Dismiss feedback", onPress: dismiss }), _jsx(KeyboardAvoidingView, { behavior: Platform.OS === "ios" ? "padding" : undefined, children: _jsxs(View, { style: styles.sheet, children: [_jsx(Text, { style: styles.overline, children: "FIXBACK \u00B7 REPORT" }), _jsx(Text, { style: styles.title, children: "Send feedback" }), _jsx(TextInput, { style: styles.comment, multiline: true, editable: !busy, placeholder: "What happened? What did you expect?", placeholderTextColor: signal.textGhost, value: comment, onChangeText: setComment, accessibilityLabel: "Feedback comment" }), screenshot && includeScreenshot ? (_jsxs(View, { style: styles.screenshotRow, children: [_jsx(Image, { source: { uri: screenshot.uri }, style: styles.screenshotThumb, resizeMode: "cover", accessibilityLabel: "Screenshot preview" }), _jsxs(View, { style: styles.screenshotMeta, children: [_jsx(Text, { style: styles.screenshotLabel, children: "Screenshot attached" }), _jsx(Text, { style: styles.screenshotHint, children: "Exactly this image is sent \u2014 remove it if it shows something private." })] }), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Remove screenshot", disabled: busy, onPress: removeScreenshot, children: _jsx(Text, { style: styles.removeLabel, children: "Remove" }) })] })) : null, phase === "failed" ? (_jsx(Text, { style: styles.failed, children: "Couldn't send \u2014 check your connection and try again." })) : null, phase === "sent" ? (_jsx(Text, { style: styles.sent, children: "Sent \u2014 thank you." })) : null, _jsxs(View, { style: styles.footer, children: [_jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Cancel", onPress: dismiss, style: styles.cancelButton, children: _jsx(Text, { style: styles.cancelLabel, children: "Cancel" }) }), _jsx(Pressable, { accessibilityRole: "button", accessibilityLabel: "Send feedback", disabled: busy, onPress: () => void send(), style: [styles.sendButton, busy && styles.sendButtonBusy], children: phase === "sending" ? (_jsx(ActivityIndicator, { size: "small", color: signal.onEmphasis })) : (_jsx(Text, { style: styles.sendLabel, children: "Send" })) })] })] }) })] }) }));
78
+ return ((0, jsx_runtime_1.jsx)(react_native_1.Modal, { visible: visible, transparent: true, animationType: "slide", onRequestClose: dismiss, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.backdrop, children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { style: styles.backdropTouch, accessibilityLabel: "Dismiss feedback", onPress: dismiss }), (0, jsx_runtime_1.jsx)(react_native_1.KeyboardAvoidingView, { behavior: react_native_1.Platform.OS === "ios" ? "padding" : undefined, children: (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.sheet, children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.overline, children: "FIXBACK \u00B7 REPORT" }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.title, children: "Send feedback" }), (0, jsx_runtime_1.jsx)(react_native_1.View, { style: styles.identityRow, children: identity.status === "connected" ? ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.identityWho, children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.identityName, numberOfLines: 1, children: identity.name || identity.email }), identity.tier ? ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.identityTier, children: identity.tier })) : null] }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { accessibilityRole: "button", accessibilityLabel: "Sign out", disabled: busy, onPress: onSignOut, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.identityAction, children: "Sign out" }) })] })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.identityAnon, children: "Anonymous" }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { accessibilityRole: "button", accessibilityLabel: "Sign in", disabled: busy, onPress: onSignIn, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.identityAction, children: "Sign in" }) })] })) }), (0, jsx_runtime_1.jsx)(react_native_1.TextInput, { style: styles.comment, multiline: true, editable: !busy, placeholder: "What happened? What did you expect?", placeholderTextColor: tokens_1.signal.textGhost, value: comment, onChangeText: setComment, accessibilityLabel: "Feedback comment" }), screenshot && includeScreenshot ? ((0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.screenshotRow, children: [(0, jsx_runtime_1.jsx)(react_native_1.Image, { source: { uri: screenshot.uri }, style: styles.screenshotThumb, resizeMode: "cover", accessibilityLabel: "Screenshot preview" }), (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.screenshotMeta, children: [(0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.screenshotLabel, children: "Screenshot attached" }), (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.screenshotHint, children: "Exactly this image is sent \u2014 remove it if it shows something private." })] }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { accessibilityRole: "button", accessibilityLabel: "Remove screenshot", disabled: busy, onPress: removeScreenshot, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.removeLabel, children: "Remove" }) })] })) : null, phase === "failed" ? ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.failed, children: "Couldn't send \u2014 check your connection and try again." })) : null, phase === "sent" ? ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.sent, children: "Sent \u2014 thank you." })) : null, (0, jsx_runtime_1.jsxs)(react_native_1.View, { style: styles.footer, children: [(0, jsx_runtime_1.jsx)(react_native_1.Pressable, { accessibilityRole: "button", accessibilityLabel: "Cancel", onPress: dismiss, style: styles.cancelButton, children: (0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.cancelLabel, children: "Cancel" }) }), (0, jsx_runtime_1.jsx)(react_native_1.Pressable, { accessibilityRole: "button", accessibilityLabel: "Send feedback", disabled: busy, onPress: () => void send(), style: [styles.sendButton, busy && styles.sendButtonBusy], children: phase === "sending" ? ((0, jsx_runtime_1.jsx)(react_native_1.ActivityIndicator, { size: "small", color: tokens_1.signal.onEmphasis })) : ((0, jsx_runtime_1.jsx)(react_native_1.Text, { style: styles.sendLabel, children: "Send" })) })] })] }) })] }) }));
75
79
  }
76
- const styles = StyleSheet.create({
80
+ const styles = react_native_1.StyleSheet.create({
77
81
  backdrop: {
78
82
  flex: 1,
79
83
  justifyContent: "flex-end",
80
- backgroundColor: signal.scrim,
84
+ backgroundColor: tokens_1.signal.scrim,
81
85
  },
82
86
  backdropTouch: {
83
87
  flex: 1,
84
88
  },
85
89
  sheet: {
86
- backgroundColor: signal.surface,
90
+ backgroundColor: tokens_1.signal.surface,
87
91
  borderTopLeftRadius: 14,
88
92
  borderTopRightRadius: 14,
89
- borderColor: signal.border,
93
+ borderColor: tokens_1.signal.border,
90
94
  borderWidth: 1,
91
95
  paddingHorizontal: 16,
92
96
  paddingTop: 14,
@@ -96,22 +100,65 @@ const styles = StyleSheet.create({
96
100
  fontFamily: MONO_FONT,
97
101
  fontSize: 10,
98
102
  letterSpacing: 1.2,
99
- color: signal.textFaint,
103
+ color: tokens_1.signal.textFaint,
100
104
  marginBottom: 2,
101
105
  },
102
106
  title: {
103
107
  fontSize: 15,
104
108
  fontWeight: "600",
105
- color: signal.text,
109
+ color: tokens_1.signal.text,
106
110
  marginBottom: 12,
107
111
  },
112
+ identityRow: {
113
+ flexDirection: "row",
114
+ alignItems: "center",
115
+ justifyContent: "space-between",
116
+ gap: 8,
117
+ borderWidth: 1,
118
+ borderColor: tokens_1.signal.border,
119
+ borderRadius: 8,
120
+ backgroundColor: tokens_1.signal.sunken,
121
+ paddingHorizontal: 10,
122
+ paddingVertical: 8,
123
+ marginBottom: 12,
124
+ },
125
+ identityWho: {
126
+ flex: 1,
127
+ flexDirection: "row",
128
+ alignItems: "center",
129
+ gap: 8,
130
+ },
131
+ identityName: {
132
+ flexShrink: 1,
133
+ fontSize: 12,
134
+ fontWeight: "600",
135
+ color: tokens_1.signal.textPanel,
136
+ },
137
+ identityTier: {
138
+ fontFamily: MONO_FONT,
139
+ fontSize: 10,
140
+ letterSpacing: 0.6,
141
+ color: tokens_1.signal.textFaint,
142
+ textTransform: "uppercase",
143
+ },
144
+ identityAnon: {
145
+ flex: 1,
146
+ fontSize: 12,
147
+ color: tokens_1.signal.textMuted,
148
+ },
149
+ identityAction: {
150
+ fontSize: 12,
151
+ fontWeight: "600",
152
+ color: tokens_1.signal.accent,
153
+ padding: 4,
154
+ },
108
155
  comment: {
109
156
  minHeight: 96,
110
157
  borderWidth: 1,
111
- borderColor: signal.borderControl,
158
+ borderColor: tokens_1.signal.borderControl,
112
159
  borderRadius: 8,
113
- backgroundColor: signal.canvas,
114
- color: signal.text,
160
+ backgroundColor: tokens_1.signal.canvas,
161
+ color: tokens_1.signal.text,
115
162
  fontSize: 13,
116
163
  padding: 10,
117
164
  textAlignVertical: "top",
@@ -122,9 +169,9 @@ const styles = StyleSheet.create({
122
169
  alignItems: "center",
123
170
  gap: 10,
124
171
  borderWidth: 1,
125
- borderColor: signal.border,
172
+ borderColor: tokens_1.signal.border,
126
173
  borderRadius: 8,
127
- backgroundColor: signal.sunken,
174
+ backgroundColor: tokens_1.signal.sunken,
128
175
  padding: 8,
129
176
  marginBottom: 12,
130
177
  },
@@ -133,8 +180,8 @@ const styles = StyleSheet.create({
133
180
  height: 72,
134
181
  borderRadius: 4,
135
182
  borderWidth: 1,
136
- borderColor: signal.borderStrong,
137
- backgroundColor: signal.surface,
183
+ borderColor: tokens_1.signal.borderStrong,
184
+ backgroundColor: tokens_1.signal.surface,
138
185
  },
139
186
  screenshotMeta: {
140
187
  flex: 1,
@@ -142,27 +189,27 @@ const styles = StyleSheet.create({
142
189
  screenshotLabel: {
143
190
  fontSize: 12,
144
191
  fontWeight: "600",
145
- color: signal.textPanel,
192
+ color: tokens_1.signal.textPanel,
146
193
  },
147
194
  screenshotHint: {
148
195
  fontSize: 11,
149
- color: signal.textFaint,
196
+ color: tokens_1.signal.textFaint,
150
197
  marginTop: 2,
151
198
  },
152
199
  removeLabel: {
153
200
  fontSize: 12,
154
201
  fontWeight: "600",
155
- color: signal.danger,
202
+ color: tokens_1.signal.danger,
156
203
  padding: 4,
157
204
  },
158
205
  failed: {
159
206
  fontSize: 12,
160
- color: signal.danger,
207
+ color: tokens_1.signal.danger,
161
208
  marginBottom: 10,
162
209
  },
163
210
  sent: {
164
211
  fontSize: 12,
165
- color: signal.success,
212
+ color: tokens_1.signal.success,
166
213
  marginBottom: 10,
167
214
  },
168
215
  footer: {
@@ -172,21 +219,21 @@ const styles = StyleSheet.create({
172
219
  },
173
220
  cancelButton: {
174
221
  borderWidth: 1,
175
- borderColor: signal.borderControl,
222
+ borderColor: tokens_1.signal.borderControl,
176
223
  borderRadius: 8,
177
224
  paddingHorizontal: 14,
178
225
  paddingVertical: 9,
179
- backgroundColor: signal.surface,
226
+ backgroundColor: tokens_1.signal.surface,
180
227
  },
181
228
  cancelLabel: {
182
229
  fontSize: 13,
183
- color: signal.textMuted,
230
+ color: tokens_1.signal.textMuted,
184
231
  },
185
232
  sendButton: {
186
233
  borderRadius: 8,
187
234
  paddingHorizontal: 18,
188
235
  paddingVertical: 9,
189
- backgroundColor: signal.accent,
236
+ backgroundColor: tokens_1.signal.accent,
190
237
  minWidth: 72,
191
238
  alignItems: "center",
192
239
  },
@@ -196,6 +243,7 @@ const styles = StyleSheet.create({
196
243
  sendLabel: {
197
244
  fontSize: 13,
198
245
  fontWeight: "600",
199
- color: signal.onEmphasis,
246
+ color: tokens_1.signal.onEmphasis,
200
247
  },
201
248
  });
249
+ //# sourceMappingURL=FeedbackModal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FeedbackModal.js","sourceRoot":"","sources":["../src/FeedbackModal.tsx"],"names":[],"mappings":"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"}
@@ -8,6 +8,7 @@
8
8
  * for non-React call sites) expose `present` / `dismiss` / `trackScreen`.
9
9
  */
10
10
  import { type ReactNode } from "react";
11
+ import type { ReporterIdentity } from "@fixback/sdk-core";
11
12
  import { type FixbackOptions } from "./client";
12
13
  /** What `useFixback()` returns. */
13
14
  export interface FixbackHandle {
@@ -17,6 +18,17 @@ export interface FixbackHandle {
17
18
  dismiss: () => void;
18
19
  /** Record a screen change for the trace and the report `url` (spec 0004 §D). */
19
20
  trackScreen: (name: string) => void;
21
+ /**
22
+ * Start a **Connect** (ADR-0032): open the platform's connect page in an in-app auth
23
+ * session and bind the signed-in Account to this app. The way to enter a gated Project
24
+ * (which arms nothing for a signed-out visitor) from the host app's own UI — put it on
25
+ * a settings row. Resolves to the resulting identity.
26
+ */
27
+ signIn: () => Promise<ReporterIdentity>;
28
+ /** Clear the Reporter session — revoke it server-side and forget the token. */
29
+ signOut: () => Promise<void>;
30
+ /** The current Reporter identity — anonymous, or a connected Account with its tier. */
31
+ identity: () => ReporterIdentity;
20
32
  }
21
33
  /**
22
34
  * The provider's handle, or an inert one outside a provider — the SDK never
@@ -1,4 +1,9 @@
1
- import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Fixback = void 0;
4
+ exports.useFixback = useFixback;
5
+ exports.FixbackProvider = FixbackProvider;
6
+ const jsx_runtime_1 = require("react/jsx-runtime");
2
7
  /**
3
8
  * `<FixbackProvider>` — the one component a host app mounts (spec 0004 §A).
4
9
  *
@@ -8,23 +13,27 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
13
  * the app's own tree. `useFixback()` (and the module-level `Fixback` object,
9
14
  * for non-React call sites) expose `present` / `dismiss` / `trackScreen`.
10
15
  */
11
- import { createContext, useContext, useEffect, useMemo, useRef, useState, } from "react";
12
- import { createNativeAdapters, startShakeListener } from "./adapters";
13
- import { createFixbackClient, } from "./client";
14
- import { FeedbackModal } from "./FeedbackModal";
15
- import { createShakeDetector } from "./shake";
16
+ const react_1 = require("react");
17
+ const adapters_1 = require("./adapters");
18
+ const client_1 = require("./client");
19
+ const FeedbackModal_1 = require("./FeedbackModal");
20
+ const shake_1 = require("./shake");
21
+ const ANONYMOUS = { status: "anonymous" };
16
22
  const NOOP_HANDLE = {
17
23
  present: () => { },
18
24
  dismiss: () => { },
19
25
  trackScreen: () => { },
26
+ signIn: () => Promise.resolve(ANONYMOUS),
27
+ signOut: () => Promise.resolve(),
28
+ identity: () => ANONYMOUS,
20
29
  };
21
- const FixbackContext = createContext(null);
30
+ const FixbackContext = (0, react_1.createContext)(null);
22
31
  /**
23
32
  * The provider's handle, or an inert one outside a provider — the SDK never
24
33
  * throws into the host app, hooks included.
25
34
  */
26
- export function useFixback() {
27
- return useContext(FixbackContext) ?? NOOP_HANDLE;
35
+ function useFixback() {
36
+ return (0, react_1.useContext)(FixbackContext) ?? NOOP_HANDLE;
28
37
  }
29
38
  /** The most recently mounted provider's handle, for non-React call sites. */
30
39
  let activeHandle = null;
@@ -32,28 +41,34 @@ let activeHandle = null;
32
41
  * The module-level escape hatch (spec 0004 §B): `Fixback.present()` from any
33
42
  * plain function — a settings row, a dev menu item, an error boundary.
34
43
  */
35
- export const Fixback = {
44
+ exports.Fixback = {
36
45
  present: () => activeHandle?.present(),
37
46
  dismiss: () => activeHandle?.dismiss(),
38
47
  trackScreen: (name) => activeHandle?.trackScreen(name),
48
+ signIn: () => activeHandle?.signIn() ?? Promise.resolve(ANONYMOUS),
49
+ signOut: () => activeHandle?.signOut() ?? Promise.resolve(),
50
+ identity: () => activeHandle?.identity() ?? ANONYMOUS,
39
51
  };
40
- export function FixbackProvider({ options, children }) {
52
+ function FixbackProvider({ options, children }) {
41
53
  // The client is created once per mounted provider; option changes after
42
54
  // mount are deliberately ignored (remount to reconfigure), matching the web
43
55
  // SDK's one-shot `init`.
44
- const [client] = useState(() => createFixbackClient(options, createNativeAdapters()));
45
- const [status, setStatus] = useState(client.getStatus());
46
- const [composer, setComposer] = useState(null);
47
- const composerOpenRef = useRef(false);
48
- useEffect(() => {
56
+ const [client] = (0, react_1.useState)(() => (0, client_1.createFixbackClient)(options, (0, adapters_1.createNativeAdapters)()));
57
+ const [status, setStatus] = (0, react_1.useState)(client.getStatus());
58
+ const [identity, setIdentity] = (0, react_1.useState)(() => client.identity());
59
+ const [composer, setComposer] = (0, react_1.useState)(null);
60
+ const composerOpenRef = (0, react_1.useRef)(false);
61
+ (0, react_1.useEffect)(() => {
49
62
  const unsubscribe = client.onStatus(setStatus);
63
+ const unsubscribeIdentity = client.onIdentity(setIdentity);
50
64
  void client.start();
51
65
  return () => {
52
66
  unsubscribe();
67
+ unsubscribeIdentity();
53
68
  client.destroy();
54
69
  };
55
70
  }, [client]);
56
- useEffect(() => {
71
+ (0, react_1.useEffect)(() => {
57
72
  return client.onPresent((context) => {
58
73
  if (composerOpenRef.current) {
59
74
  // The composer is already open — this capture is never shown, so
@@ -67,36 +82,44 @@ export function FixbackProvider({ options, children }) {
67
82
  }, [client]);
68
83
  // The shake gesture is armed only while the client can actually submit, so
69
84
  // a dormant SDK never keeps the accelerometer running.
70
- useEffect(() => {
85
+ (0, react_1.useEffect)(() => {
71
86
  if (status !== "ready")
72
87
  return;
73
88
  const config = client.shakeConfig();
74
89
  if (!config.enabled)
75
90
  return;
76
- const detector = createShakeDetector({
91
+ const detector = (0, shake_1.createShakeDetector)({
77
92
  ...config,
78
93
  onShake: () => {
79
94
  if (!composerOpenRef.current)
80
95
  void client.present();
81
96
  },
82
97
  });
83
- const subscription = startShakeListener((sample) => detector.sample(sample), config.sampleIntervalMs);
98
+ const subscription = (0, adapters_1.startShakeListener)((sample) => detector.sample(sample), config.sampleIntervalMs);
84
99
  return () => subscription.remove();
85
100
  }, [client, status]);
86
- const handle = useMemo(() => ({
101
+ const handle = (0, react_1.useMemo)(() => ({
87
102
  present: () => void client.present(),
88
103
  dismiss: () => {
89
104
  composerOpenRef.current = false;
90
105
  setComposer(null);
91
106
  },
92
107
  trackScreen: (name) => client.trackScreen(name),
108
+ signIn: () => client.signIn(),
109
+ signOut: () => client.signOut(),
110
+ identity: () => client.identity(),
93
111
  }), [client]);
94
- useEffect(() => {
112
+ (0, react_1.useEffect)(() => {
95
113
  activeHandle = handle;
96
114
  return () => {
97
115
  if (activeHandle === handle)
98
116
  activeHandle = null;
99
117
  };
100
118
  }, [handle]);
101
- return (_jsxs(FixbackContext.Provider, { value: handle, children: [children, _jsx(FeedbackModal, { visible: composer !== null, screenshot: composer?.screenshot ?? null, onDismiss: handle.dismiss, onSubmit: (draft) => client.submit(draft), onDiscardScreenshot: (shot) => client.discardScreenshot(shot) })] }));
119
+ return ((0, jsx_runtime_1.jsxs)(FixbackContext.Provider, { value: handle, children: [children, (0, jsx_runtime_1.jsx)(FeedbackModal_1.FeedbackModal, { visible: composer !== null, screenshot: composer?.screenshot ?? null, identity: identity, onSignIn: () => {
120
+ void client.signIn();
121
+ }, onSignOut: () => {
122
+ void client.signOut();
123
+ }, onDismiss: handle.dismiss, onSubmit: (draft) => client.submit(draft), onDiscardScreenshot: (shot) => client.discardScreenshot(shot) })] }));
102
124
  }
125
+ //# sourceMappingURL=FixbackProvider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"FixbackProvider.js","sourceRoot":"","sources":["../src/FixbackProvider.tsx"],"names":[],"mappings":"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"}