reflet-sdk 0.7.4 → 0.7.5
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 +6 -0
- package/README.md +32 -1
- 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-o1O55wu1.js} +3 -3
- package/dist/{devtools-layer-CcTmlikp.js.map → devtools-layer-o1O55wu1.js.map} +1 -1
- package/dist/devtools-next.d.ts.map +1 -1
- package/dist/devtools-next.js +1 -1
- package/dist/{devtools-styles-teRMfSzW.js → devtools-styles-TWR5Ps34.js} +24 -3
- package/dist/devtools-styles-TWR5Ps34.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 +21 -12
- 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-DJIKxRUp.js} +2 -2
- package/dist/submit-DJIKxRUp.js.map +1 -0
- package/dist/{team-layer-zLj_QPQX.js → team-layer-_It1_oSo.js} +127 -57
- package/dist/team-layer-_It1_oSo.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-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,12 @@ 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.5] - 2026-10-17
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- 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.
|
|
13
|
+
|
|
8
14
|
## [0.7.4] - 2026-10-15
|
|
9
15
|
|
|
10
16
|
### 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
|
|
|
@@ -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 shortenSourcePath, G as describeElement, M as TargetIcon, Q as resolveComponentStack, R as DEFAULT_WIDGET_LABELS, U as buildElementSelection, V as collectPageContext, X as getFiberFromNode, a as uploadBlob, f as listenOnPageAndWidget, g as isSubmitEnter, it as releaseCapture, nt as capturedFromCanvas, o as ElementPicker, p as listenToKeydown, r as deriveTitle, rt as capturedViewportSize, s as isWidgetOwned, tt as captureViewport, z as SDK_VERSION } from "./submit-
|
|
1
|
+
import { $ as shortenSourcePath, G as describeElement, M as TargetIcon, Q as resolveComponentStack, R as DEFAULT_WIDGET_LABELS, U as buildElementSelection, V as collectPageContext, X as getFiberFromNode, a as uploadBlob, f as listenOnPageAndWidget, g as isSubmitEnter, it as releaseCapture, nt as capturedFromCanvas, o as ElementPicker, p as listenToKeydown, r as deriveTitle, rt as capturedViewportSize, s as isWidgetOwned, tt as captureViewport, z as SDK_VERSION } from "./submit-DJIKxRUp.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-TWR5Ps34.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";
|
|
@@ -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-o1O55wu1.js.map
|