reflet-sdk 0.7.4 → 0.7.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/CHANGELOG.md +14 -0
- package/README.md +35 -4
- package/dist/desktop.d.ts +24 -0
- package/dist/desktop.d.ts.map +1 -0
- package/dist/desktop.js +118 -0
- package/dist/desktop.js.map +1 -0
- package/dist/{devtools-layer-CcTmlikp.js → devtools-layer-xN47FKpW.js} +5 -5
- package/dist/devtools-layer-xN47FKpW.js.map +1 -0
- package/dist/devtools-next.d.ts.map +1 -1
- package/dist/devtools-next.js +1 -1
- package/dist/{devtools-styles-teRMfSzW.js → devtools-styles-DQpiubGB.js} +26 -8
- package/dist/devtools-styles-DQpiubGB.js.map +1 -0
- package/dist/devtools-vite.js +2 -1
- package/dist/devtools-vite.js.map +1 -1
- package/dist/feedback.d.ts +7 -3
- package/dist/feedback.d.ts.map +1 -1
- package/dist/feedback.js +23 -13
- package/dist/feedback.js.map +1 -1
- package/dist/{handler-B3_PQB1q.js → handler-ndF3gZBx.js} +11 -416
- package/dist/handler-ndF3gZBx.js.map +1 -0
- package/dist/reflet-proxy-BW6q9xds.js +467 -0
- package/dist/reflet-proxy-BW6q9xds.js.map +1 -0
- package/dist/{submit-CG4LXioK.js → submit-DsJwTy3X.js} +25 -9
- package/dist/submit-DsJwTy3X.js.map +1 -0
- package/dist/{team-layer-zLj_QPQX.js → team-layer-VlQtvR5O.js} +127 -57
- package/dist/team-layer-VlQtvR5O.js.map +1 -0
- package/dist/team-tools-bridge-C51PpkUI.d.ts +31 -0
- package/dist/team-tools-bridge-C51PpkUI.d.ts.map +1 -0
- package/package.json +5 -1
- package/dist/devtools-layer-CcTmlikp.js.map +0 -1
- package/dist/devtools-styles-teRMfSzW.js.map +0 -1
- package/dist/handler-B3_PQB1q.js.map +0 -1
- package/dist/submit-CG4LXioK.js.map +0 -1
- package/dist/team-layer-zLj_QPQX.js.map +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,20 @@ All notable changes to `reflet-sdk` will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.7.6] - 2026-10-17
|
|
9
|
+
|
|
10
|
+
### Changed
|
|
11
|
+
|
|
12
|
+
- Pick: the note card's actions are smaller. Pick another and Copy are icon buttons (their names show on hover), and View code is now Code with an icon.
|
|
13
|
+
- Devtools: an empty Board says "This page" or "Whole board" above its message instead of "0 on this page" or "0 on the board".
|
|
14
|
+
- Devtools: the panel has no divider lines under its tabs or above the account footer.
|
|
15
|
+
|
|
16
|
+
## [0.7.5] - 2026-10-17
|
|
17
|
+
|
|
18
|
+
### Added
|
|
19
|
+
|
|
20
|
+
- Team tools in desktop apps: `createTeamToolsHost` from `reflet-sdk/desktop` runs them in an Electron main process, and `<RefletFeedback teamTools={bridge} />` takes the bridge it returns. Pages loaded from `file://` can now record sessions: sign-in opens the system browser and returns to a loopback listener, and the token stays in `~/.reflet/devtools/`, out of the page.
|
|
21
|
+
|
|
8
22
|
## [0.7.4] - 2026-10-15
|
|
9
23
|
|
|
10
24
|
### Changed
|
package/README.md
CHANGED
|
@@ -167,7 +167,7 @@ builds do; production builds strip React's debug data).
|
|
|
167
167
|
| `categories` | `("bug" \| "idea" \| "question")[]` | all three | Category chips to show. |
|
|
168
168
|
| `labels` | `Partial<FeedbackWidgetLabels>` | — | Override any string for i18n. |
|
|
169
169
|
| `devtools` | `boolean` | `true` | Dev-only team tools; see below. Never loaded outside `NODE_ENV=development`. |
|
|
170
|
-
| `teamTools` | `boolean` | `true` | Lets signed-in members of your Reflet organization record sessions in production; see below. |
|
|
170
|
+
| `teamTools` | `boolean \| TeamToolsBridge` | `true` | Lets signed-in members of your Reflet organization record sessions in production; see below. Desktop apps pass a bridge. |
|
|
171
171
|
| `appUrl` | `string` | `"https://www.reflet.app"` | Reflet web app origin team tools sign in on. |
|
|
172
172
|
| `onSubmit` | `(result: { feedbackId: string }) => void` | — | Fires after a successful send. |
|
|
173
173
|
|
|
@@ -192,12 +192,12 @@ builds drop it at bundle time — the devtools chunk is never shipped to your
|
|
|
192
192
|
users. Pass `devtools={false}` to turn it off.
|
|
193
193
|
|
|
194
194
|
- **Pick** — click an element to write a note on it. The note card has a
|
|
195
|
-
|
|
195
|
+
Code button, and Shift+click (or Shift+Enter) skips the note and opens
|
|
196
196
|
the source file with the JSX element highlighted, ready to jump to in your
|
|
197
197
|
editor. Locations come from React's debug stacks resolved through the dev
|
|
198
198
|
server's source maps, Server Components included. Press ⌘C (Ctrl+C) on the
|
|
199
|
-
aimed element, or
|
|
200
|
-
the clipboard for a coding agent, without saving a note.
|
|
199
|
+
aimed element, or the note card's copy button, to put the element and its
|
|
200
|
+
source on the clipboard for a coding agent, without saving a note.
|
|
201
201
|
- **Notes** — a note appears the moment you press Enter, as a numbered pin on
|
|
202
202
|
its element, Figma-style; click the pin to read, edit or delete it, and find
|
|
203
203
|
the same number on its card in the panel. Its source location and a
|
|
@@ -299,6 +299,37 @@ transcript is saved, within 24 hours at most. Pausing stops all collection;
|
|
|
299
299
|
keystrokes are never recorded, form fields appear empty in screenshots, and
|
|
300
300
|
password fields and elements marked `data-reflet-redact` are hidden from them.
|
|
301
301
|
|
|
302
|
+
##### Desktop apps (Electron)
|
|
303
|
+
|
|
304
|
+
A page loaded from `file://` has no origin Reflet can bind a sign-in to, so the
|
|
305
|
+
browser flow above can't work there. Run team tools from the app's main
|
|
306
|
+
process instead: sign-in opens the system browser and comes back to a one-shot
|
|
307
|
+
listener on `127.0.0.1`, like the devtools' Connect, and the token stays on disk
|
|
308
|
+
in `~/.reflet/devtools/`, never in the page. Members approve it on reflet.app as
|
|
309
|
+
a local connection; revoke it from Account → Devtools. The key needs no allowed
|
|
310
|
+
domain for this.
|
|
311
|
+
|
|
312
|
+
```ts
|
|
313
|
+
// main process
|
|
314
|
+
import { app, ipcMain, shell } from 'electron';
|
|
315
|
+
import { createTeamToolsHost } from 'reflet-sdk/desktop';
|
|
316
|
+
|
|
317
|
+
const teamTools = createTeamToolsHost({
|
|
318
|
+
appDataDirectory: app.getPath('userData'),
|
|
319
|
+
openExternal: (url) => shell.openExternal(url),
|
|
320
|
+
publicKey: 'fb_pub_xxx',
|
|
321
|
+
});
|
|
322
|
+
ipcMain.handle('reflet-team-tools:account', () => teamTools.account());
|
|
323
|
+
ipcMain.handle('reflet-team-tools:request', (_event, call) => teamTools.request(call));
|
|
324
|
+
ipcMain.handle('reflet-team-tools:sign-in', () => teamTools.signIn());
|
|
325
|
+
ipcMain.handle('reflet-team-tools:sign-out', () => teamTools.signOut());
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
Expose the four calls from the preload script, then pass them as the bridge:
|
|
329
|
+
`<RefletFeedback publicKey="fb_pub_xxx" teamTools={bridge} />`. Team tools show
|
|
330
|
+
at once, so only pass the bridge in builds meant for your team. `request` only
|
|
331
|
+
forwards the session and feedback endpoints the devtools use.
|
|
332
|
+
|
|
302
333
|
### 5. In-App Surveys
|
|
303
334
|
|
|
304
335
|
Create surveys in the Reflet dashboard (NPS, ratings, choices, text, statements,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { i as TeamToolsReply, n as TeamToolsBridge, r as TeamToolsCall, t as TeamToolsAccount } from "./team-tools-bridge-C51PpkUI.js";
|
|
2
|
+
//#region src/devtools/server/desktop.d.ts
|
|
3
|
+
export interface TeamToolsHostOptions {
|
|
4
|
+
/** Reflet API origin. Defaults to the hosted API. */
|
|
5
|
+
apiUrl?: string;
|
|
6
|
+
/** A directory only this app uses, such as Electron's `app.getPath("userData")`. Keeps its sign-in apart from other apps and dev servers. */
|
|
7
|
+
appDataDirectory: string;
|
|
8
|
+
/** Reflet web app origin sign-in happens on. Defaults to https://www.reflet.app. */
|
|
9
|
+
appUrl?: string;
|
|
10
|
+
/** Opens a URL in the system browser, such as Electron's `shell.openExternal`. */
|
|
11
|
+
openExternal: (url: string) => Promise<void>;
|
|
12
|
+
publicKey: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Runs team tools for a desktop app in its privileged process (Electron's
|
|
16
|
+
* main): sign-in goes through the system browser back to a one-shot loopback
|
|
17
|
+
* listener, and the token stays on disk outside the page, like the dev
|
|
18
|
+
* server's Connect. Expose the returned bridge to the page over IPC and pass it
|
|
19
|
+
* to `<RefletFeedback teamTools={bridge} />`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function createTeamToolsHost(options: TeamToolsHostOptions): TeamToolsBridge;
|
|
22
|
+
//#endregion
|
|
23
|
+
export type { TeamToolsAccount, TeamToolsBridge, TeamToolsCall, TeamToolsReply };
|
|
24
|
+
//# sourceMappingURL=desktop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.d.ts","names":[],"sources":["../src/devtools/server/desktop.ts"],"mappings":";;iBA4BiB;;EAEf;;EAEA;;EAEA;;EAEA,eAAe,gBAAgB;EAC/B;;;;;;;;;wBAsGc,oBACd,SAAS,uBACR"}
|
package/dist/desktop.js
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { a as connectCallbackUriFor, f as PENDING_CONNECT_TTL_MS, i as connectAuthorizeUrl, l as forgetConnection, m as readConnection, o as connectOutcomePage, p as htmlPage, r as resolveDevtoolsOptions, t as proxyWithBoardCredential, u as redeemConnectCode } from "./reflet-proxy-BW6q9xds.js";
|
|
2
|
+
import { createServer } from "node:http";
|
|
3
|
+
//#region src/devtools/server/desktop.ts
|
|
4
|
+
const LOOPBACK_HOST = "127.0.0.1";
|
|
5
|
+
const SIGN_IN_TIMED_OUT = "Reflet sign-in timed out. Sign in again.";
|
|
6
|
+
async function sendPage(response, page) {
|
|
7
|
+
response.writeHead(page.status, Object.fromEntries(page.headers));
|
|
8
|
+
response.end(await page.text());
|
|
9
|
+
}
|
|
10
|
+
async function listenOnLoopback(server) {
|
|
11
|
+
await new Promise((resolve, reject) => {
|
|
12
|
+
server.once("error", reject);
|
|
13
|
+
server.listen(0, LOOPBACK_HOST, resolve);
|
|
14
|
+
});
|
|
15
|
+
const address = server.address();
|
|
16
|
+
if (address === null || typeof address === "string") throw new Error("The Reflet sign-in listener has no port.");
|
|
17
|
+
return address.port;
|
|
18
|
+
}
|
|
19
|
+
/** Settles on the first callback carrying this sign-in's state; anything else gets a 404 and changes nothing. */
|
|
20
|
+
function awaitConnectCallback(server, pending) {
|
|
21
|
+
const callbackPath = new URL(pending.redirectUri).pathname;
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
const timeout = setTimeout(() => reject(/* @__PURE__ */ new Error(SIGN_IN_TIMED_OUT)), PENDING_CONNECT_TTL_MS);
|
|
24
|
+
let isRedeeming = false;
|
|
25
|
+
const redeem = async (url, response) => {
|
|
26
|
+
const outcome = await redeemConnectCode(pending.settings, {
|
|
27
|
+
code: url.searchParams.get("code"),
|
|
28
|
+
redirectUri: pending.redirectUri,
|
|
29
|
+
state: pending.state
|
|
30
|
+
});
|
|
31
|
+
await sendPage(response, connectOutcomePage(outcome));
|
|
32
|
+
if (!outcome.ok) throw new Error(outcome.message);
|
|
33
|
+
return { organizationName: outcome.organizationName };
|
|
34
|
+
};
|
|
35
|
+
server.on("request", (request, response) => {
|
|
36
|
+
const url = new URL(request.url ?? "/", pending.redirectUri);
|
|
37
|
+
const isThisSignIn = request.method === "GET" && url.pathname === callbackPath && url.searchParams.get("state") === pending.state;
|
|
38
|
+
if (isRedeeming || !isThisSignIn) {
|
|
39
|
+
sendPage(response, htmlPage("Not found", "Nothing here answers this link.", 404)).catch(() => void 0);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
isRedeeming = true;
|
|
43
|
+
clearTimeout(timeout);
|
|
44
|
+
redeem(url, response).then(resolve, reject);
|
|
45
|
+
});
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
async function startBrowserSignIn(settings, publicKey) {
|
|
49
|
+
const server = createServer();
|
|
50
|
+
const port = await listenOnLoopback(server);
|
|
51
|
+
const redirectUri = connectCallbackUriFor(`http://${LOOPBACK_HOST}:${port}`);
|
|
52
|
+
const { authorizeUrl, state } = connectAuthorizeUrl(settings, {
|
|
53
|
+
publicKey,
|
|
54
|
+
redirectUri
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
account: awaitConnectCallback(server, {
|
|
58
|
+
redirectUri,
|
|
59
|
+
settings,
|
|
60
|
+
state
|
|
61
|
+
}).finally(() => server.close()),
|
|
62
|
+
authorizeUrl
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Runs team tools for a desktop app in its privileged process (Electron's
|
|
67
|
+
* main): sign-in goes through the system browser back to a one-shot loopback
|
|
68
|
+
* listener, and the token stays on disk outside the page, like the dev
|
|
69
|
+
* server's Connect. Expose the returned bridge to the page over IPC and pass it
|
|
70
|
+
* to `<RefletFeedback teamTools={bridge} />`.
|
|
71
|
+
*/
|
|
72
|
+
function createTeamToolsHost(options) {
|
|
73
|
+
const settings = resolveDevtoolsOptions({
|
|
74
|
+
apiUrl: options.apiUrl,
|
|
75
|
+
appUrl: options.appUrl,
|
|
76
|
+
root: options.appDataDirectory
|
|
77
|
+
}, {});
|
|
78
|
+
let pendingSignIn = null;
|
|
79
|
+
const currentSignIn = () => {
|
|
80
|
+
if (pendingSignIn) return pendingSignIn;
|
|
81
|
+
const started = startBrowserSignIn(settings, options.publicKey);
|
|
82
|
+
pendingSignIn = started;
|
|
83
|
+
const release = () => {
|
|
84
|
+
if (pendingSignIn === started) pendingSignIn = null;
|
|
85
|
+
};
|
|
86
|
+
started.then((signIn) => signIn.account).then(release, release);
|
|
87
|
+
return started;
|
|
88
|
+
};
|
|
89
|
+
return {
|
|
90
|
+
account: async () => {
|
|
91
|
+
const connection = await readConnection(settings.root, settings.apiUrl);
|
|
92
|
+
return connection && { organizationName: connection.organizationName };
|
|
93
|
+
},
|
|
94
|
+
request: async (call) => {
|
|
95
|
+
const search = call.query ? `?${new URLSearchParams(call.query)}` : "";
|
|
96
|
+
const response = await proxyWithBoardCredential(new Request(`${settings.apiUrl}/${search}`, {
|
|
97
|
+
body: call.method === "POST" ? call.body : void 0,
|
|
98
|
+
method: call.method
|
|
99
|
+
}), call.path, settings);
|
|
100
|
+
return {
|
|
101
|
+
body: await response.text(),
|
|
102
|
+
status: response.status
|
|
103
|
+
};
|
|
104
|
+
},
|
|
105
|
+
signIn: async () => {
|
|
106
|
+
const signIn = await currentSignIn();
|
|
107
|
+
await options.openExternal(signIn.authorizeUrl);
|
|
108
|
+
return await signIn.account;
|
|
109
|
+
},
|
|
110
|
+
signOut: async () => {
|
|
111
|
+
await forgetConnection(settings);
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
//#endregion
|
|
116
|
+
export { createTeamToolsHost };
|
|
117
|
+
|
|
118
|
+
//# sourceMappingURL=desktop.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desktop.js","names":[],"sources":["../src/devtools/server/desktop.ts"],"sourcesContent":["import { createServer, type Server, type ServerResponse } from \"node:http\";\nimport type {\n TeamToolsAccount,\n TeamToolsBridge,\n} from \"../../sessions/team/team-tools-bridge\";\nimport {\n connectAuthorizeUrl,\n connectCallbackUriFor,\n connectOutcomePage,\n forgetConnection,\n redeemConnectCode,\n} from \"./connect/connect-routes\";\nimport { readConnection } from \"./connect/connection-store\";\nimport { htmlPage } from \"./connect/html-page\";\nimport { PENDING_CONNECT_TTL_MS } from \"./connect/pending-connects\";\nimport {\n type ResolvedDevtoolsOptions,\n resolveDevtoolsOptions,\n} from \"./options\";\nimport { proxyWithBoardCredential } from \"./reflet-proxy\";\n\nexport type {\n TeamToolsAccount,\n TeamToolsBridge,\n TeamToolsCall,\n TeamToolsReply,\n} from \"../../sessions/team/team-tools-bridge\";\n\nexport interface TeamToolsHostOptions {\n /** Reflet API origin. Defaults to the hosted API. */\n apiUrl?: string;\n /** A directory only this app uses, such as Electron's `app.getPath(\"userData\")`. Keeps its sign-in apart from other apps and dev servers. */\n appDataDirectory: string;\n /** Reflet web app origin sign-in happens on. Defaults to https://www.reflet.app. */\n appUrl?: string;\n /** Opens a URL in the system browser, such as Electron's `shell.openExternal`. */\n openExternal: (url: string) => Promise<void>;\n publicKey: string;\n}\n\ninterface BrowserSignIn {\n account: Promise<TeamToolsAccount>;\n authorizeUrl: string;\n}\n\nconst LOOPBACK_HOST = \"127.0.0.1\";\nconst SIGN_IN_TIMED_OUT = \"Reflet sign-in timed out. Sign in again.\";\n\nasync function sendPage(response: ServerResponse, page: Response) {\n response.writeHead(page.status, Object.fromEntries(page.headers));\n response.end(await page.text());\n}\n\nasync function listenOnLoopback(server: Server): Promise<number> {\n await new Promise<void>((resolve, reject) => {\n server.once(\"error\", reject);\n server.listen(0, LOOPBACK_HOST, resolve);\n });\n const address = server.address();\n if (address === null || typeof address === \"string\") {\n throw new Error(\"The Reflet sign-in listener has no port.\");\n }\n return address.port;\n}\n\n/** Settles on the first callback carrying this sign-in's state; anything else gets a 404 and changes nothing. */\nfunction awaitConnectCallback(\n server: Server,\n pending: {\n redirectUri: string;\n settings: ResolvedDevtoolsOptions;\n state: string;\n }\n): Promise<TeamToolsAccount> {\n const callbackPath = new URL(pending.redirectUri).pathname;\n return new Promise((resolve, reject) => {\n const timeout = setTimeout(\n () => reject(new Error(SIGN_IN_TIMED_OUT)),\n PENDING_CONNECT_TTL_MS\n );\n let isRedeeming = false;\n const redeem = async (url: URL, response: ServerResponse) => {\n const outcome = await redeemConnectCode(pending.settings, {\n code: url.searchParams.get(\"code\"),\n redirectUri: pending.redirectUri,\n state: pending.state,\n });\n await sendPage(response, connectOutcomePage(outcome));\n if (!outcome.ok) {\n throw new Error(outcome.message);\n }\n return { organizationName: outcome.organizationName };\n };\n server.on(\"request\", (request, response) => {\n const url = new URL(request.url ?? \"/\", pending.redirectUri);\n const isThisSignIn =\n request.method === \"GET\" &&\n url.pathname === callbackPath &&\n url.searchParams.get(\"state\") === pending.state;\n if (isRedeeming || !isThisSignIn) {\n sendPage(\n response,\n htmlPage(\"Not found\", \"Nothing here answers this link.\", 404)\n ).catch(() => undefined);\n return;\n }\n isRedeeming = true;\n clearTimeout(timeout);\n redeem(url, response).then(resolve, reject);\n });\n });\n}\n\nasync function startBrowserSignIn(\n settings: ResolvedDevtoolsOptions,\n publicKey: string\n): Promise<BrowserSignIn> {\n const server = createServer();\n const port = await listenOnLoopback(server);\n const redirectUri = connectCallbackUriFor(`http://${LOOPBACK_HOST}:${port}`);\n const { authorizeUrl, state } = connectAuthorizeUrl(settings, {\n publicKey,\n redirectUri,\n });\n const account = awaitConnectCallback(server, {\n redirectUri,\n settings,\n state,\n }).finally(() => server.close());\n return { account, authorizeUrl };\n}\n\n/**\n * Runs team tools for a desktop app in its privileged process (Electron's\n * main): sign-in goes through the system browser back to a one-shot loopback\n * listener, and the token stays on disk outside the page, like the dev\n * server's Connect. Expose the returned bridge to the page over IPC and pass it\n * to `<RefletFeedback teamTools={bridge} />`.\n */\nexport function createTeamToolsHost(\n options: TeamToolsHostOptions\n): TeamToolsBridge {\n const settings = resolveDevtoolsOptions(\n {\n apiUrl: options.apiUrl,\n appUrl: options.appUrl,\n root: options.appDataDirectory,\n },\n {}\n );\n let pendingSignIn: Promise<BrowserSignIn> | null = null;\n\n const currentSignIn = (): Promise<BrowserSignIn> => {\n if (pendingSignIn) {\n return pendingSignIn;\n }\n const started = startBrowserSignIn(settings, options.publicKey);\n pendingSignIn = started;\n const release = () => {\n if (pendingSignIn === started) {\n pendingSignIn = null;\n }\n };\n started.then((signIn) => signIn.account).then(release, release);\n return started;\n };\n\n return {\n account: async () => {\n const connection = await readConnection(settings.root, settings.apiUrl);\n return connection && { organizationName: connection.organizationName };\n },\n request: async (call) => {\n const search = call.query ? `?${new URLSearchParams(call.query)}` : \"\";\n const response = await proxyWithBoardCredential(\n new Request(`${settings.apiUrl}/${search}`, {\n body: call.method === \"POST\" ? call.body : undefined,\n method: call.method,\n }),\n call.path,\n settings\n );\n return { body: await response.text(), status: response.status };\n },\n signIn: async () => {\n const signIn = await currentSignIn();\n await options.openExternal(signIn.authorizeUrl);\n return await signIn.account;\n },\n signOut: async () => {\n await forgetConnection(settings);\n },\n };\n}\n"],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { $ as
|
|
1
|
+
import { $ as resolveComponentStack, B as SDK_VERSION, H as collectPageContext, K as describeElement, N as TargetIcon, W as buildElementSelection, Z as getFiberFromNode, a as uploadBlob, at as releaseCapture, et as shortenSourcePath, f as listenOnPageAndWidget, g as isSubmitEnter, it as capturedViewportSize, nt as captureViewport, o as ElementPicker, p as listenToKeydown, r as deriveTitle, rt as capturedFromCanvas, s as isWidgetOwned, z as DEFAULT_WIDGET_LABELS } from "./submit-DsJwTy3X.js";
|
|
2
2
|
import { t as SelectionOutline } from "./selection-outline-NzAAAZXR.js";
|
|
3
|
-
import { A as
|
|
3
|
+
import { A as probeDevRoute, B as reportFailure, D as disconnectBoard, E as callReflet, F as openDatabase, I as settle, M as startBoardConnect, N as committed, O as fetchBoardFeedback, P as describeStorageFailure, R as Notices, _ as RecordingLayer, a as SHEET_TABS, c as AccountNote, d as sessionSheetPlace, f as useSessionNavigation, g as copyToClipboard, h as ViewOptionsIcon, i as DevtoolsBarButtons, j as searchCode, k as fetchSourceFile, l as SESSIONS_STYLES, m as RefreshIcon, n as DevtoolsSheet, p as Menu, r as DevtoolsBar, s as AccountFooter, t as DEVTOOLS_STYLES, u as SessionsPanel, v as countLabel, w as devtoolsTransport, x as useWorkspaceLoader, y as SessionWorkspaceProvider, z as announce } from "./devtools-styles-DQpiubGB.js";
|
|
4
4
|
import * as G$1 from "react";
|
|
5
5
|
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -448,7 +448,7 @@ function InboxToolbar({ onRefresh, onSelectScope, scope, state }) {
|
|
|
448
448
|
children: [
|
|
449
449
|
/* @__PURE__ */ jsx("span", {
|
|
450
450
|
className: "dt-status",
|
|
451
|
-
children: state.kind === "ready" ? `${state.page.total} ${SCOPE_PLACES[scope]}` : SCOPE_LABELS[scope]
|
|
451
|
+
children: state.kind === "ready" && state.page.total > 0 ? `${state.page.total} ${SCOPE_PLACES[scope]}` : SCOPE_LABELS[scope]
|
|
452
452
|
}),
|
|
453
453
|
/* @__PURE__ */ jsx(Menu, {
|
|
454
454
|
items: INBOX_SCOPES.map((option) => ({
|
|
@@ -3719,7 +3719,7 @@ function DevtoolsLayer({ isWidgetOpen, position, publicKey }) {
|
|
|
3719
3719
|
return element !== null;
|
|
3720
3720
|
}, []);
|
|
3721
3721
|
const inspect = useMemo(() => ({
|
|
3722
|
-
label: "
|
|
3722
|
+
label: "Code",
|
|
3723
3723
|
onInspect: (element) => {
|
|
3724
3724
|
setIsPicking(false);
|
|
3725
3725
|
inspectElement(element);
|
|
@@ -3815,4 +3815,4 @@ function DevtoolsLayer({ isWidgetOpen, position, publicKey }) {
|
|
|
3815
3815
|
//#endregion
|
|
3816
3816
|
export { DevtoolsLayer };
|
|
3817
3817
|
|
|
3818
|
-
//# sourceMappingURL=devtools-layer-
|
|
3818
|
+
//# sourceMappingURL=devtools-layer-xN47FKpW.js.map
|