@guidelytech/electron 0.0.0-stage → 0.11.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Guidely
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,102 @@
1
- # Temporary Holding Version
1
+ # @guidelytech/electron
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Guidely guides, analytics, session replay and feature flags in Electron (and other Chromium desktop
4
+ shells). The web SDK runs in your renderer as it does in a browser; this package adds the desktop
5
+ parts:
6
+
7
+ * **Page paths that make sense.** `file:///…/Acme.app/Contents/Resources/app.asar/index.html#/settings`
8
+ becomes `file://app/settings`, and `app://bundle/index.html#/inbox` becomes `app://bundle/inbox`, so
9
+ guide URL patterns (`/settings`), Pages, Heatmaps and Funnels work the same on every machine.
10
+ * **App version and OS.** The main process reports the app version, OS, architecture and Electron
11
+ version: **App version** targeting rules, feature-flag attributes (`appVersion`), release-matched
12
+ source maps for errors, and optional desktop traits for your users.
13
+ * **Offline.** Events, guide progress and survey answers wait in `localStorage` while the machine is
14
+ offline and are delivered later (the web SDK's outbox), and guides run from the cached config.
15
+
16
+ ```bash
17
+ npm install @guidelytech/electron @guidelytech/sdk-core
18
+ ```
19
+
20
+ ## 1. Main process
21
+
22
+ ```ts
23
+ import { app, BrowserWindow, ipcMain } from "electron";
24
+ import { setupGuidelyMain } from "@guidelytech/electron/main";
25
+
26
+ app.whenReady().then(() => {
27
+ setupGuidelyMain({ app, ipcMain });
28
+ new BrowserWindow({ webPreferences: { preload: path.join(__dirname, "preload.js"), contextIsolation: true } }).loadFile("index.html");
29
+ });
30
+ ```
31
+
32
+ ## 2. Preload
33
+
34
+ ```ts
35
+ import { contextBridge, ipcRenderer } from "electron";
36
+ import { exposeGuidely } from "@guidelytech/electron/preload";
37
+
38
+ exposeGuidely({ contextBridge, ipcRenderer }); // window.guidelyElectron.getAppInfo()
39
+ ```
40
+
41
+ Sandboxed preloads (the default since Electron 20) can't `require` npm packages: bundle your preload
42
+ (esbuild, Vite, webpack) or inline the equivalent:
43
+
44
+ ```ts
45
+ contextBridge.exposeInMainWorld("guidelyElectron", { getAppInfo: () => ipcRenderer.invoke("guidely:app-info") });
46
+ ```
47
+
48
+ ## 3. Renderer
49
+
50
+ ```ts
51
+ import { createGuidelyElectron, desktopTraits } from "@guidelytech/electron";
52
+
53
+ const guidely = await createGuidelyElectron({
54
+ projectId: "pk_prod_…",
55
+ apiUrl: "https://guidelytech.com",
56
+ user: { id: me.id, traits: { plan: me.plan } }, // desktopOs, desktopArch, appVersion… are added
57
+ });
58
+ ```
59
+
60
+ Or keep your existing setup (React, Svelte, script tag) and spread the options:
61
+
62
+ ```tsx
63
+ import { electronOptions, getElectronAppInfo } from "@guidelytech/electron";
64
+ const info = await getElectronAppInfo();
65
+ <GuidelyProvider projectId="pk_prod_…" {...electronOptions(info)}>…</GuidelyProvider>
66
+ ```
67
+
68
+ | Export | Where | What |
69
+ |---|---|---|
70
+ | `setupGuidelyMain({ app, ipcMain })` | main | Answers `guidely:app-info`; returns a dispose function |
71
+ | `exposeGuidely({ contextBridge, ipcRenderer })` | preload | Exposes `window.guidelyElectron` |
72
+ | `getElectronAppInfo(timeoutMs = 1000)` | renderer | `{ appName, appVersion, platform, arch, osVersion, electronVersion, chromeVersion, locale, packaged }` or `null` |
73
+ | `electronOptions(info)` | renderer | `{ pageUrl: normalizeAppUrl, appVersion, release }` |
74
+ | `desktopTraits(info)` | renderer | `{ appVersion, desktopOs, desktopOsVersion, desktopArch, electronVersion }` |
75
+ | `createGuidelyElectron(options)` | renderer | `createGuidely` with all of the above |
76
+ | `normalizeAppUrl(href)` | anywhere | The URL mapping (also exported by `@guidelytech/sdk-core`) |
77
+
78
+ ## Page URLs
79
+
80
+ The SDK maps every non-http(s) URL (`file:`, custom protocols) with `normalizeAppUrl`, even without
81
+ this package: `<scheme>://<host or "app"><route>`, where the route is the hash route (`#/x`, `#!/x`)
82
+ when there is one, otherwise the page file (`index.html` → `/`, `settings.html` → `/settings`) or the
83
+ custom protocol's own path (`app://bundle/deals/42` → `/deals/42`). Write guide URL patterns against
84
+ the route: `/settings`, `/deals/*`. Pass your own `pageUrl: (href) => string` option to map URLs
85
+ differently (for example to keep a `?tab=` parameter out).
86
+
87
+ ## Things to know
88
+
89
+ * **Allowed origins.** Requests from `file://` pages carry `Origin: null` (or `file://`), and custom
90
+ protocols their own origin (`app://bundle`). Leave the environment's allowed origins empty, or add
91
+ that origin, in Settings → Environments.
92
+ * **Custom protocols** need `protocol.registerSchemesAsPrivileged([{ scheme: "app", privileges: {
93
+ standard: true, secure: true, supportFetchAPI: true, corsEnabled: true } }])` before `app` is ready,
94
+ or `localStorage` (identity, offline queue) and `fetch` won't work on them.
95
+ * **CSP.** If your renderer sets a Content-Security-Policy, allow the Guidely API in `connect-src`
96
+ (and `img-src` for guide images), and `script-src` for the session-replay recorder chunk if you use
97
+ replay (or self-host the SDK files, see [docs/sdk-versioning.md](../../docs/sdk-versioning.md)).
98
+ * The **in-app element picker** opens the target URL in a browser window, which a packaged desktop app
99
+ can't receive: author against your app's web build or a dev server (`http://localhost:…`), or use
100
+ manual selectors.
101
+ * Guides use the **Web** platform (tick *Web* under Trigger → Platforms). Device type is `desktop`;
102
+ the browser is reported as `electron` and the OS from the user agent.
@@ -0,0 +1,16 @@
1
+ // src/types.ts
2
+ var APP_INFO_CHANNEL = "guidely:app-info";
3
+ var BRIDGE_KEY = "guidelyElectron";
4
+ function osName(platform) {
5
+ if (platform === "darwin") return "macos";
6
+ if (platform === "win32") return "windows";
7
+ if (platform === "linux") return "linux";
8
+ return platform;
9
+ }
10
+
11
+ export {
12
+ APP_INFO_CHANNEL,
13
+ BRIDGE_KEY,
14
+ osName
15
+ };
16
+ //# sourceMappingURL=chunk-AGZOVF3N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["/** What the main process knows about the desktop app, sent to the renderer over IPC. */\nexport interface ElectronAppInfo {\n /** `app.getName()`. */\n appName: string;\n /** `app.getVersion()` (from package.json). */\n appVersion: string;\n /** `process.platform`: `darwin`, `win32`, `linux`. */\n platform: string;\n /** `process.arch`: `x64`, `arm64`, … */\n arch: string;\n /** `os.release()` / `process.getSystemVersion()`, when available. */\n osVersion?: string;\n electronVersion?: string;\n chromeVersion?: string;\n /** `app.getLocale()`. */\n locale?: string;\n /** `app.isPackaged`: false while running from source (`electron .`). */\n packaged?: boolean;\n}\n\n/** The API the preload script exposes on `window.guidelyElectron`. */\nexport interface GuidelyElectronBridge {\n getAppInfo(): Promise<ElectronAppInfo>;\n}\n\n/** IPC channel used between the main-process handler and the preload bridge. */\nexport const APP_INFO_CHANNEL = \"guidely:app-info\";\n/** Global the preload bridge is exposed as (`contextBridge.exposeInMainWorld`). */\nexport const BRIDGE_KEY = \"guidelyElectron\";\n\n/** Desktop operating system names used in Guidely device properties. */\nexport function osName(platform: string): string {\n if (platform === \"darwin\") return \"macos\";\n if (platform === \"win32\") return \"windows\";\n if (platform === \"linux\") return \"linux\";\n return platform;\n}\n"],"mappings":";AA0BO,IAAM,mBAAmB;AAEzB,IAAM,aAAa;AAGnB,SAAS,OAAO,UAA0B;AAC/C,MAAI,aAAa,SAAU,QAAO;AAClC,MAAI,aAAa,QAAS,QAAO;AACjC,MAAI,aAAa,QAAS,QAAO;AACjC,SAAO;AACT;","names":[]}
package/dist/index.cjs ADDED
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/index.ts
21
+ var index_exports = {};
22
+ __export(index_exports, {
23
+ APP_INFO_CHANNEL: () => APP_INFO_CHANNEL,
24
+ BRIDGE_KEY: () => BRIDGE_KEY,
25
+ createGuidelyElectron: () => createGuidelyElectron,
26
+ desktopTraits: () => desktopTraits,
27
+ electronOptions: () => electronOptions,
28
+ getElectronAppInfo: () => getElectronAppInfo,
29
+ normalizeAppUrl: () => import_sdk_core2.normalizeAppUrl,
30
+ osName: () => osName
31
+ });
32
+ module.exports = __toCommonJS(index_exports);
33
+ var import_sdk_core = require("@guidelytech/sdk-core");
34
+
35
+ // src/types.ts
36
+ var APP_INFO_CHANNEL = "guidely:app-info";
37
+ var BRIDGE_KEY = "guidelyElectron";
38
+ function osName(platform) {
39
+ if (platform === "darwin") return "macos";
40
+ if (platform === "win32") return "windows";
41
+ if (platform === "linux") return "linux";
42
+ return platform;
43
+ }
44
+
45
+ // src/index.ts
46
+ var import_sdk_core2 = require("@guidelytech/sdk-core");
47
+ var bridge = () => {
48
+ const g = globalThis;
49
+ const b = g[BRIDGE_KEY];
50
+ return b && typeof b.getAppInfo === "function" ? b : null;
51
+ };
52
+ async function getElectronAppInfo(timeoutMs = 1e3) {
53
+ const b = bridge();
54
+ if (!b) return null;
55
+ let timer;
56
+ try {
57
+ return await Promise.race([
58
+ b.getAppInfo().then((info) => info && typeof info === "object" && typeof info.appVersion === "string" ? info : null),
59
+ new Promise((resolve) => timer = setTimeout(() => resolve(null), timeoutMs))
60
+ ]);
61
+ } catch {
62
+ return null;
63
+ } finally {
64
+ if (timer) clearTimeout(timer);
65
+ }
66
+ }
67
+ function electronOptions(info) {
68
+ return {
69
+ pageUrl: import_sdk_core.normalizeAppUrl,
70
+ ...info?.appVersion ? { appVersion: info.appVersion, release: info.appVersion } : {}
71
+ };
72
+ }
73
+ function desktopTraits(info) {
74
+ if (!info) return {};
75
+ const out = { appVersion: info.appVersion, desktopOs: osName(info.platform), desktopArch: info.arch };
76
+ if (info.osVersion) out.desktopOsVersion = info.osVersion;
77
+ if (info.electronVersion) out.electronVersion = info.electronVersion;
78
+ return out;
79
+ }
80
+ async function createGuidelyElectron(options) {
81
+ const { bridgeTimeoutMs, ...rest } = options;
82
+ const info = await getElectronAppInfo(bridgeTimeoutMs);
83
+ const user = rest.user ? { ...rest.user, traits: { ...desktopTraits(info), ...rest.user.traits ?? {} } } : void 0;
84
+ return (0, import_sdk_core.createGuidely)({ ...electronOptions(info), ...rest, ...user ? { user } : {} });
85
+ }
86
+ // Annotate the CommonJS export names for ESM import in node:
87
+ 0 && (module.exports = {
88
+ APP_INFO_CHANNEL,
89
+ BRIDGE_KEY,
90
+ createGuidelyElectron,
91
+ desktopTraits,
92
+ electronOptions,
93
+ getElectronAppInfo,
94
+ normalizeAppUrl,
95
+ osName
96
+ });
97
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/types.ts"],"sourcesContent":["import { createGuidely, normalizeAppUrl, type GuidelyClient, type GuidelyOptions } from \"@guidelytech/sdk-core\";\nimport { BRIDGE_KEY, osName, type ElectronAppInfo, type GuidelyElectronBridge } from \"./types\";\n\nexport { APP_INFO_CHANNEL, BRIDGE_KEY, osName } from \"./types\";\nexport type { ElectronAppInfo, GuidelyElectronBridge } from \"./types\";\nexport { normalizeAppUrl } from \"@guidelytech/sdk-core\";\n\nconst bridge = (): GuidelyElectronBridge | null => {\n const g = globalThis as unknown as Record<string, unknown>;\n const b = g[BRIDGE_KEY] as GuidelyElectronBridge | undefined;\n return b && typeof b.getAppInfo === \"function\" ? b : null;\n};\n\n/**\n * Renderer: the app info exposed by the preload bridge, or null when it is missing (plain browser,\n * preload not installed) or does not answer within `timeoutMs`.\n */\nexport async function getElectronAppInfo(timeoutMs = 1000): Promise<ElectronAppInfo | null> {\n const b = bridge();\n if (!b) return null;\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n b.getAppInfo().then((info) => (info && typeof info === \"object\" && typeof info.appVersion === \"string\" ? info : null)),\n new Promise<null>((resolve) => (timer = setTimeout(() => resolve(null), timeoutMs))),\n ]);\n } catch {\n return null;\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\n/**\n * SDK options for a desktop app: app-relative page URLs for `file:` and custom protocols, the app\n * version for **App version** targeting rules and flag attributes, and the release for source-mapped\n * errors. Spread your own options after it to override.\n */\nexport function electronOptions(info: ElectronAppInfo | null): Pick<GuidelyOptions, \"pageUrl\" | \"appVersion\" | \"release\"> {\n return {\n pageUrl: normalizeAppUrl,\n ...(info?.appVersion ? { appVersion: info.appVersion, release: info.appVersion } : {}),\n };\n}\n\n/**\n * Desktop details as user traits (`desktopOs`, `desktopOsVersion`, `desktopArch`, `electronVersion`,\n * `appVersion`), for `identify(userId, { ...traits, ...desktopTraits(info) })` so targeting rules,\n * audiences and the Users list can use them.\n */\nexport function desktopTraits(info: ElectronAppInfo | null): Record<string, string> {\n if (!info) return {};\n const out: Record<string, string> = { appVersion: info.appVersion, desktopOs: osName(info.platform), desktopArch: info.arch };\n if (info.osVersion) out.desktopOsVersion = info.osVersion;\n if (info.electronVersion) out.electronVersion = info.electronVersion;\n return out;\n}\n\n/**\n * Renderer: creates the Guidely client for an Electron window, after reading the app info from the\n * preload bridge (at most `bridgeTimeoutMs`, default 1 s; without the bridge it still works, with\n * app-relative page URLs but no app version). `options.user.traits` get the desktop traits added.\n *\n * ```ts\n * import { createGuidelyElectron } from \"@guidelytech/electron\";\n * const guidely = await createGuidelyElectron({ projectId: \"pk_prod_…\", user: { id: me.id, traits: { plan: me.plan } } });\n * ```\n */\nexport async function createGuidelyElectron(options: GuidelyOptions & { bridgeTimeoutMs?: number }): Promise<GuidelyClient> {\n const { bridgeTimeoutMs, ...rest } = options;\n const info = await getElectronAppInfo(bridgeTimeoutMs);\n const user = rest.user ? { ...rest.user, traits: { ...desktopTraits(info), ...(rest.user.traits ?? {}) } } : undefined;\n return createGuidely({ ...electronOptions(info), ...rest, ...(user ? { user } : {}) });\n}\n","/** What the main process knows about the desktop app, sent to the renderer over IPC. */\nexport interface ElectronAppInfo {\n /** `app.getName()`. */\n appName: string;\n /** `app.getVersion()` (from package.json). */\n appVersion: string;\n /** `process.platform`: `darwin`, `win32`, `linux`. */\n platform: string;\n /** `process.arch`: `x64`, `arm64`, … */\n arch: string;\n /** `os.release()` / `process.getSystemVersion()`, when available. */\n osVersion?: string;\n electronVersion?: string;\n chromeVersion?: string;\n /** `app.getLocale()`. */\n locale?: string;\n /** `app.isPackaged`: false while running from source (`electron .`). */\n packaged?: boolean;\n}\n\n/** The API the preload script exposes on `window.guidelyElectron`. */\nexport interface GuidelyElectronBridge {\n getAppInfo(): Promise<ElectronAppInfo>;\n}\n\n/** IPC channel used between the main-process handler and the preload bridge. */\nexport const APP_INFO_CHANNEL = \"guidely:app-info\";\n/** Global the preload bridge is exposed as (`contextBridge.exposeInMainWorld`). */\nexport const BRIDGE_KEY = \"guidelyElectron\";\n\n/** Desktop operating system names used in Guidely device properties. */\nexport function osName(platform: string): string {\n if (platform === \"darwin\") return \"macos\";\n if (platform === \"win32\") return \"windows\";\n if (platform === \"linux\") return \"linux\";\n return platform;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,sBAAwF;;;AC0BjF,IAAM,mBAAmB;AAEzB,IAAM,aAAa;AAGnB,SAAS,OAAO,UAA0B;AAC/C,MAAI,aAAa,SAAU,QAAO;AAClC,MAAI,aAAa,QAAS,QAAO;AACjC,MAAI,aAAa,QAAS,QAAO;AACjC,SAAO;AACT;;;AD/BA,IAAAA,mBAAgC;AAEhC,IAAM,SAAS,MAAoC;AACjD,QAAM,IAAI;AACV,QAAM,IAAI,EAAE,UAAU;AACtB,SAAO,KAAK,OAAO,EAAE,eAAe,aAAa,IAAI;AACvD;AAMA,eAAsB,mBAAmB,YAAY,KAAuC;AAC1F,QAAM,IAAI,OAAO;AACjB,MAAI,CAAC,EAAG,QAAO;AACf,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK;AAAA,MACxB,EAAE,WAAW,EAAE,KAAK,CAAC,SAAU,QAAQ,OAAO,SAAS,YAAY,OAAO,KAAK,eAAe,WAAW,OAAO,IAAK;AAAA,MACrH,IAAI,QAAc,CAAC,YAAa,QAAQ,WAAW,MAAM,QAAQ,IAAI,GAAG,SAAS,CAAE;AAAA,IACrF,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,QAAI,MAAO,cAAa,KAAK;AAAA,EAC/B;AACF;AAOO,SAAS,gBAAgB,MAA0F;AACxH,SAAO;AAAA,IACL,SAAS;AAAA,IACT,GAAI,MAAM,aAAa,EAAE,YAAY,KAAK,YAAY,SAAS,KAAK,WAAW,IAAI,CAAC;AAAA,EACtF;AACF;AAOO,SAAS,cAAc,MAAsD;AAClF,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAM,MAA8B,EAAE,YAAY,KAAK,YAAY,WAAW,OAAO,KAAK,QAAQ,GAAG,aAAa,KAAK,KAAK;AAC5H,MAAI,KAAK,UAAW,KAAI,mBAAmB,KAAK;AAChD,MAAI,KAAK,gBAAiB,KAAI,kBAAkB,KAAK;AACrD,SAAO;AACT;AAYA,eAAsB,sBAAsB,SAAgF;AAC1H,QAAM,EAAE,iBAAiB,GAAG,KAAK,IAAI;AACrC,QAAM,OAAO,MAAM,mBAAmB,eAAe;AACrD,QAAM,OAAO,KAAK,OAAO,EAAE,GAAG,KAAK,MAAM,QAAQ,EAAE,GAAG,cAAc,IAAI,GAAG,GAAI,KAAK,KAAK,UAAU,CAAC,EAAG,EAAE,IAAI;AAC7G,aAAO,+BAAc,EAAE,GAAG,gBAAgB,IAAI,GAAG,GAAG,MAAM,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,EAAG,CAAC;AACvF;","names":["import_sdk_core"]}
@@ -0,0 +1,37 @@
1
+ import { GuidelyOptions, GuidelyClient } from '@guidelytech/sdk-core';
2
+ export { normalizeAppUrl } from '@guidelytech/sdk-core';
3
+ import { E as ElectronAppInfo } from './types-BEnWCecg.cjs';
4
+ export { A as APP_INFO_CHANNEL, B as BRIDGE_KEY, G as GuidelyElectronBridge, o as osName } from './types-BEnWCecg.cjs';
5
+
6
+ /**
7
+ * Renderer: the app info exposed by the preload bridge, or null when it is missing (plain browser,
8
+ * preload not installed) or does not answer within `timeoutMs`.
9
+ */
10
+ declare function getElectronAppInfo(timeoutMs?: number): Promise<ElectronAppInfo | null>;
11
+ /**
12
+ * SDK options for a desktop app: app-relative page URLs for `file:` and custom protocols, the app
13
+ * version for **App version** targeting rules and flag attributes, and the release for source-mapped
14
+ * errors. Spread your own options after it to override.
15
+ */
16
+ declare function electronOptions(info: ElectronAppInfo | null): Pick<GuidelyOptions, "pageUrl" | "appVersion" | "release">;
17
+ /**
18
+ * Desktop details as user traits (`desktopOs`, `desktopOsVersion`, `desktopArch`, `electronVersion`,
19
+ * `appVersion`), for `identify(userId, { ...traits, ...desktopTraits(info) })` so targeting rules,
20
+ * audiences and the Users list can use them.
21
+ */
22
+ declare function desktopTraits(info: ElectronAppInfo | null): Record<string, string>;
23
+ /**
24
+ * Renderer: creates the Guidely client for an Electron window, after reading the app info from the
25
+ * preload bridge (at most `bridgeTimeoutMs`, default 1 s; without the bridge it still works, with
26
+ * app-relative page URLs but no app version). `options.user.traits` get the desktop traits added.
27
+ *
28
+ * ```ts
29
+ * import { createGuidelyElectron } from "@guidelytech/electron";
30
+ * const guidely = await createGuidelyElectron({ projectId: "pk_prod_…", user: { id: me.id, traits: { plan: me.plan } } });
31
+ * ```
32
+ */
33
+ declare function createGuidelyElectron(options: GuidelyOptions & {
34
+ bridgeTimeoutMs?: number;
35
+ }): Promise<GuidelyClient>;
36
+
37
+ export { ElectronAppInfo, createGuidelyElectron, desktopTraits, electronOptions, getElectronAppInfo };
@@ -0,0 +1,37 @@
1
+ import { GuidelyOptions, GuidelyClient } from '@guidelytech/sdk-core';
2
+ export { normalizeAppUrl } from '@guidelytech/sdk-core';
3
+ import { E as ElectronAppInfo } from './types-BEnWCecg.js';
4
+ export { A as APP_INFO_CHANNEL, B as BRIDGE_KEY, G as GuidelyElectronBridge, o as osName } from './types-BEnWCecg.js';
5
+
6
+ /**
7
+ * Renderer: the app info exposed by the preload bridge, or null when it is missing (plain browser,
8
+ * preload not installed) or does not answer within `timeoutMs`.
9
+ */
10
+ declare function getElectronAppInfo(timeoutMs?: number): Promise<ElectronAppInfo | null>;
11
+ /**
12
+ * SDK options for a desktop app: app-relative page URLs for `file:` and custom protocols, the app
13
+ * version for **App version** targeting rules and flag attributes, and the release for source-mapped
14
+ * errors. Spread your own options after it to override.
15
+ */
16
+ declare function electronOptions(info: ElectronAppInfo | null): Pick<GuidelyOptions, "pageUrl" | "appVersion" | "release">;
17
+ /**
18
+ * Desktop details as user traits (`desktopOs`, `desktopOsVersion`, `desktopArch`, `electronVersion`,
19
+ * `appVersion`), for `identify(userId, { ...traits, ...desktopTraits(info) })` so targeting rules,
20
+ * audiences and the Users list can use them.
21
+ */
22
+ declare function desktopTraits(info: ElectronAppInfo | null): Record<string, string>;
23
+ /**
24
+ * Renderer: creates the Guidely client for an Electron window, after reading the app info from the
25
+ * preload bridge (at most `bridgeTimeoutMs`, default 1 s; without the bridge it still works, with
26
+ * app-relative page URLs but no app version). `options.user.traits` get the desktop traits added.
27
+ *
28
+ * ```ts
29
+ * import { createGuidelyElectron } from "@guidelytech/electron";
30
+ * const guidely = await createGuidelyElectron({ projectId: "pk_prod_…", user: { id: me.id, traits: { plan: me.plan } } });
31
+ * ```
32
+ */
33
+ declare function createGuidelyElectron(options: GuidelyOptions & {
34
+ bridgeTimeoutMs?: number;
35
+ }): Promise<GuidelyClient>;
36
+
37
+ export { ElectronAppInfo, createGuidelyElectron, desktopTraits, electronOptions, getElectronAppInfo };
package/dist/index.js ADDED
@@ -0,0 +1,59 @@
1
+ import {
2
+ APP_INFO_CHANNEL,
3
+ BRIDGE_KEY,
4
+ osName
5
+ } from "./chunk-AGZOVF3N.js";
6
+
7
+ // src/index.ts
8
+ import { createGuidely, normalizeAppUrl } from "@guidelytech/sdk-core";
9
+ import { normalizeAppUrl as normalizeAppUrl2 } from "@guidelytech/sdk-core";
10
+ var bridge = () => {
11
+ const g = globalThis;
12
+ const b = g[BRIDGE_KEY];
13
+ return b && typeof b.getAppInfo === "function" ? b : null;
14
+ };
15
+ async function getElectronAppInfo(timeoutMs = 1e3) {
16
+ const b = bridge();
17
+ if (!b) return null;
18
+ let timer;
19
+ try {
20
+ return await Promise.race([
21
+ b.getAppInfo().then((info) => info && typeof info === "object" && typeof info.appVersion === "string" ? info : null),
22
+ new Promise((resolve) => timer = setTimeout(() => resolve(null), timeoutMs))
23
+ ]);
24
+ } catch {
25
+ return null;
26
+ } finally {
27
+ if (timer) clearTimeout(timer);
28
+ }
29
+ }
30
+ function electronOptions(info) {
31
+ return {
32
+ pageUrl: normalizeAppUrl,
33
+ ...info?.appVersion ? { appVersion: info.appVersion, release: info.appVersion } : {}
34
+ };
35
+ }
36
+ function desktopTraits(info) {
37
+ if (!info) return {};
38
+ const out = { appVersion: info.appVersion, desktopOs: osName(info.platform), desktopArch: info.arch };
39
+ if (info.osVersion) out.desktopOsVersion = info.osVersion;
40
+ if (info.electronVersion) out.electronVersion = info.electronVersion;
41
+ return out;
42
+ }
43
+ async function createGuidelyElectron(options) {
44
+ const { bridgeTimeoutMs, ...rest } = options;
45
+ const info = await getElectronAppInfo(bridgeTimeoutMs);
46
+ const user = rest.user ? { ...rest.user, traits: { ...desktopTraits(info), ...rest.user.traits ?? {} } } : void 0;
47
+ return createGuidely({ ...electronOptions(info), ...rest, ...user ? { user } : {} });
48
+ }
49
+ export {
50
+ APP_INFO_CHANNEL,
51
+ BRIDGE_KEY,
52
+ createGuidelyElectron,
53
+ desktopTraits,
54
+ electronOptions,
55
+ getElectronAppInfo,
56
+ normalizeAppUrl2 as normalizeAppUrl,
57
+ osName
58
+ };
59
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import { createGuidely, normalizeAppUrl, type GuidelyClient, type GuidelyOptions } from \"@guidelytech/sdk-core\";\nimport { BRIDGE_KEY, osName, type ElectronAppInfo, type GuidelyElectronBridge } from \"./types\";\n\nexport { APP_INFO_CHANNEL, BRIDGE_KEY, osName } from \"./types\";\nexport type { ElectronAppInfo, GuidelyElectronBridge } from \"./types\";\nexport { normalizeAppUrl } from \"@guidelytech/sdk-core\";\n\nconst bridge = (): GuidelyElectronBridge | null => {\n const g = globalThis as unknown as Record<string, unknown>;\n const b = g[BRIDGE_KEY] as GuidelyElectronBridge | undefined;\n return b && typeof b.getAppInfo === \"function\" ? b : null;\n};\n\n/**\n * Renderer: the app info exposed by the preload bridge, or null when it is missing (plain browser,\n * preload not installed) or does not answer within `timeoutMs`.\n */\nexport async function getElectronAppInfo(timeoutMs = 1000): Promise<ElectronAppInfo | null> {\n const b = bridge();\n if (!b) return null;\n let timer: ReturnType<typeof setTimeout> | undefined;\n try {\n return await Promise.race([\n b.getAppInfo().then((info) => (info && typeof info === \"object\" && typeof info.appVersion === \"string\" ? info : null)),\n new Promise<null>((resolve) => (timer = setTimeout(() => resolve(null), timeoutMs))),\n ]);\n } catch {\n return null;\n } finally {\n if (timer) clearTimeout(timer);\n }\n}\n\n/**\n * SDK options for a desktop app: app-relative page URLs for `file:` and custom protocols, the app\n * version for **App version** targeting rules and flag attributes, and the release for source-mapped\n * errors. Spread your own options after it to override.\n */\nexport function electronOptions(info: ElectronAppInfo | null): Pick<GuidelyOptions, \"pageUrl\" | \"appVersion\" | \"release\"> {\n return {\n pageUrl: normalizeAppUrl,\n ...(info?.appVersion ? { appVersion: info.appVersion, release: info.appVersion } : {}),\n };\n}\n\n/**\n * Desktop details as user traits (`desktopOs`, `desktopOsVersion`, `desktopArch`, `electronVersion`,\n * `appVersion`), for `identify(userId, { ...traits, ...desktopTraits(info) })` so targeting rules,\n * audiences and the Users list can use them.\n */\nexport function desktopTraits(info: ElectronAppInfo | null): Record<string, string> {\n if (!info) return {};\n const out: Record<string, string> = { appVersion: info.appVersion, desktopOs: osName(info.platform), desktopArch: info.arch };\n if (info.osVersion) out.desktopOsVersion = info.osVersion;\n if (info.electronVersion) out.electronVersion = info.electronVersion;\n return out;\n}\n\n/**\n * Renderer: creates the Guidely client for an Electron window, after reading the app info from the\n * preload bridge (at most `bridgeTimeoutMs`, default 1 s; without the bridge it still works, with\n * app-relative page URLs but no app version). `options.user.traits` get the desktop traits added.\n *\n * ```ts\n * import { createGuidelyElectron } from \"@guidelytech/electron\";\n * const guidely = await createGuidelyElectron({ projectId: \"pk_prod_…\", user: { id: me.id, traits: { plan: me.plan } } });\n * ```\n */\nexport async function createGuidelyElectron(options: GuidelyOptions & { bridgeTimeoutMs?: number }): Promise<GuidelyClient> {\n const { bridgeTimeoutMs, ...rest } = options;\n const info = await getElectronAppInfo(bridgeTimeoutMs);\n const user = rest.user ? { ...rest.user, traits: { ...desktopTraits(info), ...(rest.user.traits ?? {}) } } : undefined;\n return createGuidely({ ...electronOptions(info), ...rest, ...(user ? { user } : {}) });\n}\n"],"mappings":";;;;;;;AAAA,SAAS,eAAe,uBAAgE;AAKxF,SAAS,mBAAAA,wBAAuB;AAEhC,IAAM,SAAS,MAAoC;AACjD,QAAM,IAAI;AACV,QAAM,IAAI,EAAE,UAAU;AACtB,SAAO,KAAK,OAAO,EAAE,eAAe,aAAa,IAAI;AACvD;AAMA,eAAsB,mBAAmB,YAAY,KAAuC;AAC1F,QAAM,IAAI,OAAO;AACjB,MAAI,CAAC,EAAG,QAAO;AACf,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,QAAQ,KAAK;AAAA,MACxB,EAAE,WAAW,EAAE,KAAK,CAAC,SAAU,QAAQ,OAAO,SAAS,YAAY,OAAO,KAAK,eAAe,WAAW,OAAO,IAAK;AAAA,MACrH,IAAI,QAAc,CAAC,YAAa,QAAQ,WAAW,MAAM,QAAQ,IAAI,GAAG,SAAS,CAAE;AAAA,IACrF,CAAC;AAAA,EACH,QAAQ;AACN,WAAO;AAAA,EACT,UAAE;AACA,QAAI,MAAO,cAAa,KAAK;AAAA,EAC/B;AACF;AAOO,SAAS,gBAAgB,MAA0F;AACxH,SAAO;AAAA,IACL,SAAS;AAAA,IACT,GAAI,MAAM,aAAa,EAAE,YAAY,KAAK,YAAY,SAAS,KAAK,WAAW,IAAI,CAAC;AAAA,EACtF;AACF;AAOO,SAAS,cAAc,MAAsD;AAClF,MAAI,CAAC,KAAM,QAAO,CAAC;AACnB,QAAM,MAA8B,EAAE,YAAY,KAAK,YAAY,WAAW,OAAO,KAAK,QAAQ,GAAG,aAAa,KAAK,KAAK;AAC5H,MAAI,KAAK,UAAW,KAAI,mBAAmB,KAAK;AAChD,MAAI,KAAK,gBAAiB,KAAI,kBAAkB,KAAK;AACrD,SAAO;AACT;AAYA,eAAsB,sBAAsB,SAAgF;AAC1H,QAAM,EAAE,iBAAiB,GAAG,KAAK,IAAI;AACrC,QAAM,OAAO,MAAM,mBAAmB,eAAe;AACrD,QAAM,OAAO,KAAK,OAAO,EAAE,GAAG,KAAK,MAAM,QAAQ,EAAE,GAAG,cAAc,IAAI,GAAG,GAAI,KAAK,KAAK,UAAU,CAAC,EAAG,EAAE,IAAI;AAC7G,SAAO,cAAc,EAAE,GAAG,gBAAgB,IAAI,GAAG,GAAG,MAAM,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,EAAG,CAAC;AACvF;","names":["normalizeAppUrl"]}
package/dist/main.cjs ADDED
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/main.ts
21
+ var main_exports = {};
22
+ __export(main_exports, {
23
+ APP_INFO_CHANNEL: () => APP_INFO_CHANNEL,
24
+ appInfo: () => appInfo,
25
+ setupGuidelyMain: () => setupGuidelyMain
26
+ });
27
+ module.exports = __toCommonJS(main_exports);
28
+
29
+ // src/types.ts
30
+ var APP_INFO_CHANNEL = "guidely:app-info";
31
+
32
+ // src/main.ts
33
+ function appInfo(app, proc = process, osRelease) {
34
+ const safe = (fn) => {
35
+ try {
36
+ return fn();
37
+ } catch {
38
+ return void 0;
39
+ }
40
+ };
41
+ const osVersion = safe(() => proc.getSystemVersion?.()) || safe(() => osRelease?.());
42
+ return {
43
+ appName: safe(() => app.getName()) ?? "app",
44
+ appVersion: safe(() => app.getVersion()) ?? "0.0.0",
45
+ platform: proc.platform,
46
+ arch: proc.arch,
47
+ ...osVersion ? { osVersion } : {},
48
+ ...proc.versions.electron ? { electronVersion: proc.versions.electron } : {},
49
+ ...proc.versions.chrome ? { chromeVersion: proc.versions.chrome } : {},
50
+ ...app.getLocale ? { locale: safe(() => app.getLocale()) } : {},
51
+ ...typeof app.isPackaged === "boolean" ? { packaged: app.isPackaged } : {}
52
+ };
53
+ }
54
+ function setupGuidelyMain(opts) {
55
+ const info = appInfo(opts.app, opts.process, opts.osRelease);
56
+ opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);
57
+ opts.ipcMain.handle(APP_INFO_CHANNEL, () => info);
58
+ return () => opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);
59
+ }
60
+ // Annotate the CommonJS export names for ESM import in node:
61
+ 0 && (module.exports = {
62
+ APP_INFO_CHANNEL,
63
+ appInfo,
64
+ setupGuidelyMain
65
+ });
66
+ //# sourceMappingURL=main.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/main.ts","../src/types.ts"],"sourcesContent":["import { APP_INFO_CHANNEL, type ElectronAppInfo } from \"./types\";\n\nexport { APP_INFO_CHANNEL } from \"./types\";\nexport type { ElectronAppInfo } from \"./types\";\n\n/** The parts of Electron's `app` the helper reads (pass `import { app } from \"electron\"`). */\nexport interface ElectronAppLike {\n getName(): string;\n getVersion(): string;\n getLocale?(): string;\n isPackaged?: boolean;\n}\n\n/** The parts of Electron's `ipcMain` the helper uses. */\nexport interface IpcMainLike {\n handle(channel: string, listener: (event: unknown, ...args: unknown[]) => unknown): void;\n removeHandler?(channel: string): void;\n}\n\n/** Node's `process` fields read for the app info (overridable for tests). */\nexport interface ProcessLike {\n platform: string;\n arch: string;\n versions: Record<string, string | undefined>;\n getSystemVersion?: () => string;\n}\n\n/** Collects the app info Guidely reports: app name and version, OS, architecture and Electron/Chrome versions. */\nexport function appInfo(app: ElectronAppLike, proc: ProcessLike = process as unknown as ProcessLike, osRelease?: () => string): ElectronAppInfo {\n const safe = <T>(fn: () => T): T | undefined => {\n try {\n return fn();\n } catch {\n return undefined;\n }\n };\n const osVersion = safe(() => proc.getSystemVersion?.()) || safe(() => osRelease?.());\n return {\n appName: safe(() => app.getName()) ?? \"app\",\n appVersion: safe(() => app.getVersion()) ?? \"0.0.0\",\n platform: proc.platform,\n arch: proc.arch,\n ...(osVersion ? { osVersion } : {}),\n ...(proc.versions.electron ? { electronVersion: proc.versions.electron } : {}),\n ...(proc.versions.chrome ? { chromeVersion: proc.versions.chrome } : {}),\n ...(app.getLocale ? { locale: safe(() => app.getLocale!()) } : {}),\n ...(typeof app.isPackaged === \"boolean\" ? { packaged: app.isPackaged } : {}),\n };\n}\n\n/**\n * Main process: answers the preload bridge's app-info request. Call once after `app` is ready:\n *\n * ```ts\n * import { app, ipcMain } from \"electron\";\n * import { setupGuidelyMain } from \"@guidelytech/electron/main\";\n * app.whenReady().then(() => { setupGuidelyMain({ app, ipcMain }); createWindow(); });\n * ```\n *\n * Returns a function that removes the handler.\n */\nexport function setupGuidelyMain(opts: { app: ElectronAppLike; ipcMain: IpcMainLike; process?: ProcessLike; osRelease?: () => string }): () => void {\n const info = appInfo(opts.app, opts.process, opts.osRelease);\n opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);\n opts.ipcMain.handle(APP_INFO_CHANNEL, () => info);\n return () => opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);\n}\n","/** What the main process knows about the desktop app, sent to the renderer over IPC. */\nexport interface ElectronAppInfo {\n /** `app.getName()`. */\n appName: string;\n /** `app.getVersion()` (from package.json). */\n appVersion: string;\n /** `process.platform`: `darwin`, `win32`, `linux`. */\n platform: string;\n /** `process.arch`: `x64`, `arm64`, … */\n arch: string;\n /** `os.release()` / `process.getSystemVersion()`, when available. */\n osVersion?: string;\n electronVersion?: string;\n chromeVersion?: string;\n /** `app.getLocale()`. */\n locale?: string;\n /** `app.isPackaged`: false while running from source (`electron .`). */\n packaged?: boolean;\n}\n\n/** The API the preload script exposes on `window.guidelyElectron`. */\nexport interface GuidelyElectronBridge {\n getAppInfo(): Promise<ElectronAppInfo>;\n}\n\n/** IPC channel used between the main-process handler and the preload bridge. */\nexport const APP_INFO_CHANNEL = \"guidely:app-info\";\n/** Global the preload bridge is exposed as (`contextBridge.exposeInMainWorld`). */\nexport const BRIDGE_KEY = \"guidelyElectron\";\n\n/** Desktop operating system names used in Guidely device properties. */\nexport function osName(platform: string): string {\n if (platform === \"darwin\") return \"macos\";\n if (platform === \"win32\") return \"windows\";\n if (platform === \"linux\") return \"linux\";\n return platform;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC0BO,IAAM,mBAAmB;;;ADEzB,SAAS,QAAQ,KAAsB,OAAoB,SAAmC,WAA2C;AAC9I,QAAM,OAAO,CAAI,OAA+B;AAC9C,QAAI;AACF,aAAO,GAAG;AAAA,IACZ,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,YAAY,KAAK,MAAM,KAAK,mBAAmB,CAAC,KAAK,KAAK,MAAM,YAAY,CAAC;AACnF,SAAO;AAAA,IACL,SAAS,KAAK,MAAM,IAAI,QAAQ,CAAC,KAAK;AAAA,IACtC,YAAY,KAAK,MAAM,IAAI,WAAW,CAAC,KAAK;AAAA,IAC5C,UAAU,KAAK;AAAA,IACf,MAAM,KAAK;AAAA,IACX,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,KAAK,SAAS,WAAW,EAAE,iBAAiB,KAAK,SAAS,SAAS,IAAI,CAAC;AAAA,IAC5E,GAAI,KAAK,SAAS,SAAS,EAAE,eAAe,KAAK,SAAS,OAAO,IAAI,CAAC;AAAA,IACtE,GAAI,IAAI,YAAY,EAAE,QAAQ,KAAK,MAAM,IAAI,UAAW,CAAC,EAAE,IAAI,CAAC;AAAA,IAChE,GAAI,OAAO,IAAI,eAAe,YAAY,EAAE,UAAU,IAAI,WAAW,IAAI,CAAC;AAAA,EAC5E;AACF;AAaO,SAAS,iBAAiB,MAAmH;AAClJ,QAAM,OAAO,QAAQ,KAAK,KAAK,KAAK,SAAS,KAAK,SAAS;AAC3D,OAAK,QAAQ,gBAAgB,gBAAgB;AAC7C,OAAK,QAAQ,OAAO,kBAAkB,MAAM,IAAI;AAChD,SAAO,MAAM,KAAK,QAAQ,gBAAgB,gBAAgB;AAC5D;","names":[]}
@@ -0,0 +1,43 @@
1
+ import { E as ElectronAppInfo } from './types-BEnWCecg.cjs';
2
+ export { A as APP_INFO_CHANNEL } from './types-BEnWCecg.cjs';
3
+
4
+ /** The parts of Electron's `app` the helper reads (pass `import { app } from "electron"`). */
5
+ interface ElectronAppLike {
6
+ getName(): string;
7
+ getVersion(): string;
8
+ getLocale?(): string;
9
+ isPackaged?: boolean;
10
+ }
11
+ /** The parts of Electron's `ipcMain` the helper uses. */
12
+ interface IpcMainLike {
13
+ handle(channel: string, listener: (event: unknown, ...args: unknown[]) => unknown): void;
14
+ removeHandler?(channel: string): void;
15
+ }
16
+ /** Node's `process` fields read for the app info (overridable for tests). */
17
+ interface ProcessLike {
18
+ platform: string;
19
+ arch: string;
20
+ versions: Record<string, string | undefined>;
21
+ getSystemVersion?: () => string;
22
+ }
23
+ /** Collects the app info Guidely reports: app name and version, OS, architecture and Electron/Chrome versions. */
24
+ declare function appInfo(app: ElectronAppLike, proc?: ProcessLike, osRelease?: () => string): ElectronAppInfo;
25
+ /**
26
+ * Main process: answers the preload bridge's app-info request. Call once after `app` is ready:
27
+ *
28
+ * ```ts
29
+ * import { app, ipcMain } from "electron";
30
+ * import { setupGuidelyMain } from "@guidelytech/electron/main";
31
+ * app.whenReady().then(() => { setupGuidelyMain({ app, ipcMain }); createWindow(); });
32
+ * ```
33
+ *
34
+ * Returns a function that removes the handler.
35
+ */
36
+ declare function setupGuidelyMain(opts: {
37
+ app: ElectronAppLike;
38
+ ipcMain: IpcMainLike;
39
+ process?: ProcessLike;
40
+ osRelease?: () => string;
41
+ }): () => void;
42
+
43
+ export { ElectronAppInfo, type ElectronAppLike, type IpcMainLike, type ProcessLike, appInfo, setupGuidelyMain };
package/dist/main.d.ts ADDED
@@ -0,0 +1,43 @@
1
+ import { E as ElectronAppInfo } from './types-BEnWCecg.js';
2
+ export { A as APP_INFO_CHANNEL } from './types-BEnWCecg.js';
3
+
4
+ /** The parts of Electron's `app` the helper reads (pass `import { app } from "electron"`). */
5
+ interface ElectronAppLike {
6
+ getName(): string;
7
+ getVersion(): string;
8
+ getLocale?(): string;
9
+ isPackaged?: boolean;
10
+ }
11
+ /** The parts of Electron's `ipcMain` the helper uses. */
12
+ interface IpcMainLike {
13
+ handle(channel: string, listener: (event: unknown, ...args: unknown[]) => unknown): void;
14
+ removeHandler?(channel: string): void;
15
+ }
16
+ /** Node's `process` fields read for the app info (overridable for tests). */
17
+ interface ProcessLike {
18
+ platform: string;
19
+ arch: string;
20
+ versions: Record<string, string | undefined>;
21
+ getSystemVersion?: () => string;
22
+ }
23
+ /** Collects the app info Guidely reports: app name and version, OS, architecture and Electron/Chrome versions. */
24
+ declare function appInfo(app: ElectronAppLike, proc?: ProcessLike, osRelease?: () => string): ElectronAppInfo;
25
+ /**
26
+ * Main process: answers the preload bridge's app-info request. Call once after `app` is ready:
27
+ *
28
+ * ```ts
29
+ * import { app, ipcMain } from "electron";
30
+ * import { setupGuidelyMain } from "@guidelytech/electron/main";
31
+ * app.whenReady().then(() => { setupGuidelyMain({ app, ipcMain }); createWindow(); });
32
+ * ```
33
+ *
34
+ * Returns a function that removes the handler.
35
+ */
36
+ declare function setupGuidelyMain(opts: {
37
+ app: ElectronAppLike;
38
+ ipcMain: IpcMainLike;
39
+ process?: ProcessLike;
40
+ osRelease?: () => string;
41
+ }): () => void;
42
+
43
+ export { ElectronAppInfo, type ElectronAppLike, type IpcMainLike, type ProcessLike, appInfo, setupGuidelyMain };
package/dist/main.js ADDED
@@ -0,0 +1,38 @@
1
+ import {
2
+ APP_INFO_CHANNEL
3
+ } from "./chunk-AGZOVF3N.js";
4
+
5
+ // src/main.ts
6
+ function appInfo(app, proc = process, osRelease) {
7
+ const safe = (fn) => {
8
+ try {
9
+ return fn();
10
+ } catch {
11
+ return void 0;
12
+ }
13
+ };
14
+ const osVersion = safe(() => proc.getSystemVersion?.()) || safe(() => osRelease?.());
15
+ return {
16
+ appName: safe(() => app.getName()) ?? "app",
17
+ appVersion: safe(() => app.getVersion()) ?? "0.0.0",
18
+ platform: proc.platform,
19
+ arch: proc.arch,
20
+ ...osVersion ? { osVersion } : {},
21
+ ...proc.versions.electron ? { electronVersion: proc.versions.electron } : {},
22
+ ...proc.versions.chrome ? { chromeVersion: proc.versions.chrome } : {},
23
+ ...app.getLocale ? { locale: safe(() => app.getLocale()) } : {},
24
+ ...typeof app.isPackaged === "boolean" ? { packaged: app.isPackaged } : {}
25
+ };
26
+ }
27
+ function setupGuidelyMain(opts) {
28
+ const info = appInfo(opts.app, opts.process, opts.osRelease);
29
+ opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);
30
+ opts.ipcMain.handle(APP_INFO_CHANNEL, () => info);
31
+ return () => opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);
32
+ }
33
+ export {
34
+ APP_INFO_CHANNEL,
35
+ appInfo,
36
+ setupGuidelyMain
37
+ };
38
+ //# sourceMappingURL=main.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/main.ts"],"sourcesContent":["import { APP_INFO_CHANNEL, type ElectronAppInfo } from \"./types\";\n\nexport { APP_INFO_CHANNEL } from \"./types\";\nexport type { ElectronAppInfo } from \"./types\";\n\n/** The parts of Electron's `app` the helper reads (pass `import { app } from \"electron\"`). */\nexport interface ElectronAppLike {\n getName(): string;\n getVersion(): string;\n getLocale?(): string;\n isPackaged?: boolean;\n}\n\n/** The parts of Electron's `ipcMain` the helper uses. */\nexport interface IpcMainLike {\n handle(channel: string, listener: (event: unknown, ...args: unknown[]) => unknown): void;\n removeHandler?(channel: string): void;\n}\n\n/** Node's `process` fields read for the app info (overridable for tests). */\nexport interface ProcessLike {\n platform: string;\n arch: string;\n versions: Record<string, string | undefined>;\n getSystemVersion?: () => string;\n}\n\n/** Collects the app info Guidely reports: app name and version, OS, architecture and Electron/Chrome versions. */\nexport function appInfo(app: ElectronAppLike, proc: ProcessLike = process as unknown as ProcessLike, osRelease?: () => string): ElectronAppInfo {\n const safe = <T>(fn: () => T): T | undefined => {\n try {\n return fn();\n } catch {\n return undefined;\n }\n };\n const osVersion = safe(() => proc.getSystemVersion?.()) || safe(() => osRelease?.());\n return {\n appName: safe(() => app.getName()) ?? \"app\",\n appVersion: safe(() => app.getVersion()) ?? \"0.0.0\",\n platform: proc.platform,\n arch: proc.arch,\n ...(osVersion ? { osVersion } : {}),\n ...(proc.versions.electron ? { electronVersion: proc.versions.electron } : {}),\n ...(proc.versions.chrome ? { chromeVersion: proc.versions.chrome } : {}),\n ...(app.getLocale ? { locale: safe(() => app.getLocale!()) } : {}),\n ...(typeof app.isPackaged === \"boolean\" ? { packaged: app.isPackaged } : {}),\n };\n}\n\n/**\n * Main process: answers the preload bridge's app-info request. Call once after `app` is ready:\n *\n * ```ts\n * import { app, ipcMain } from \"electron\";\n * import { setupGuidelyMain } from \"@guidelytech/electron/main\";\n * app.whenReady().then(() => { setupGuidelyMain({ app, ipcMain }); createWindow(); });\n * ```\n *\n * Returns a function that removes the handler.\n */\nexport function setupGuidelyMain(opts: { app: ElectronAppLike; ipcMain: IpcMainLike; process?: ProcessLike; osRelease?: () => string }): () => void {\n const info = appInfo(opts.app, opts.process, opts.osRelease);\n opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);\n opts.ipcMain.handle(APP_INFO_CHANNEL, () => info);\n return () => opts.ipcMain.removeHandler?.(APP_INFO_CHANNEL);\n}\n"],"mappings":";;;;;AA4BO,SAAS,QAAQ,KAAsB,OAAoB,SAAmC,WAA2C;AAC9I,QAAM,OAAO,CAAI,OAA+B;AAC9C,QAAI;AACF,aAAO,GAAG;AAAA,IACZ,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF;AACA,QAAM,YAAY,KAAK,MAAM,KAAK,mBAAmB,CAAC,KAAK,KAAK,MAAM,YAAY,CAAC;AACnF,SAAO;AAAA,IACL,SAAS,KAAK,MAAM,IAAI,QAAQ,CAAC,KAAK;AAAA,IACtC,YAAY,KAAK,MAAM,IAAI,WAAW,CAAC,KAAK;AAAA,IAC5C,UAAU,KAAK;AAAA,IACf,MAAM,KAAK;AAAA,IACX,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,GAAI,KAAK,SAAS,WAAW,EAAE,iBAAiB,KAAK,SAAS,SAAS,IAAI,CAAC;AAAA,IAC5E,GAAI,KAAK,SAAS,SAAS,EAAE,eAAe,KAAK,SAAS,OAAO,IAAI,CAAC;AAAA,IACtE,GAAI,IAAI,YAAY,EAAE,QAAQ,KAAK,MAAM,IAAI,UAAW,CAAC,EAAE,IAAI,CAAC;AAAA,IAChE,GAAI,OAAO,IAAI,eAAe,YAAY,EAAE,UAAU,IAAI,WAAW,IAAI,CAAC;AAAA,EAC5E;AACF;AAaO,SAAS,iBAAiB,MAAmH;AAClJ,QAAM,OAAO,QAAQ,KAAK,KAAK,KAAK,SAAS,KAAK,SAAS;AAC3D,OAAK,QAAQ,gBAAgB,gBAAgB;AAC7C,OAAK,QAAQ,OAAO,kBAAkB,MAAM,IAAI;AAChD,SAAO,MAAM,KAAK,QAAQ,gBAAgB,gBAAgB;AAC5D;","names":[]}
@@ -0,0 +1,43 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/preload.ts
21
+ var preload_exports = {};
22
+ __export(preload_exports, {
23
+ exposeGuidely: () => exposeGuidely
24
+ });
25
+ module.exports = __toCommonJS(preload_exports);
26
+
27
+ // src/types.ts
28
+ var APP_INFO_CHANNEL = "guidely:app-info";
29
+ var BRIDGE_KEY = "guidelyElectron";
30
+
31
+ // src/preload.ts
32
+ function exposeGuidely(opts) {
33
+ let cached = null;
34
+ const bridge = {
35
+ getAppInfo: () => cached ?? (cached = opts.ipcRenderer.invoke(APP_INFO_CHANNEL))
36
+ };
37
+ opts.contextBridge.exposeInMainWorld(BRIDGE_KEY, bridge);
38
+ }
39
+ // Annotate the CommonJS export names for ESM import in node:
40
+ 0 && (module.exports = {
41
+ exposeGuidely
42
+ });
43
+ //# sourceMappingURL=preload.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/preload.ts","../src/types.ts"],"sourcesContent":["import { APP_INFO_CHANNEL, BRIDGE_KEY, type ElectronAppInfo, type GuidelyElectronBridge } from \"./types\";\n\nexport type { ElectronAppInfo, GuidelyElectronBridge } from \"./types\";\n\n/** The parts of Electron's `contextBridge` the helper uses. */\nexport interface ContextBridgeLike {\n exposeInMainWorld(key: string, api: unknown): void;\n}\n\n/** The parts of Electron's `ipcRenderer` the helper uses. */\nexport interface IpcRendererLike {\n invoke(channel: string, ...args: unknown[]): Promise<unknown>;\n}\n\n/**\n * Preload script: exposes `window.guidelyElectron.getAppInfo()` to the page (works with\n * `contextIsolation: true`; the page gets a function, never `ipcRenderer` itself).\n *\n * ```ts\n * // preload.ts\n * import { contextBridge, ipcRenderer } from \"electron\";\n * import { exposeGuidely } from \"@guidelytech/electron/preload\";\n * exposeGuidely({ contextBridge, ipcRenderer });\n * ```\n *\n * Sandboxed preloads (Electron's default since 20) can't `require` npm packages: bundle the preload\n * (esbuild, Vite, webpack), or copy these few lines into it.\n */\nexport function exposeGuidely(opts: { contextBridge: ContextBridgeLike; ipcRenderer: IpcRendererLike }): void {\n let cached: Promise<ElectronAppInfo> | null = null;\n const bridge: GuidelyElectronBridge = {\n getAppInfo: () => (cached ??= opts.ipcRenderer.invoke(APP_INFO_CHANNEL) as Promise<ElectronAppInfo>),\n };\n opts.contextBridge.exposeInMainWorld(BRIDGE_KEY, bridge);\n}\n","/** What the main process knows about the desktop app, sent to the renderer over IPC. */\nexport interface ElectronAppInfo {\n /** `app.getName()`. */\n appName: string;\n /** `app.getVersion()` (from package.json). */\n appVersion: string;\n /** `process.platform`: `darwin`, `win32`, `linux`. */\n platform: string;\n /** `process.arch`: `x64`, `arm64`, … */\n arch: string;\n /** `os.release()` / `process.getSystemVersion()`, when available. */\n osVersion?: string;\n electronVersion?: string;\n chromeVersion?: string;\n /** `app.getLocale()`. */\n locale?: string;\n /** `app.isPackaged`: false while running from source (`electron .`). */\n packaged?: boolean;\n}\n\n/** The API the preload script exposes on `window.guidelyElectron`. */\nexport interface GuidelyElectronBridge {\n getAppInfo(): Promise<ElectronAppInfo>;\n}\n\n/** IPC channel used between the main-process handler and the preload bridge. */\nexport const APP_INFO_CHANNEL = \"guidely:app-info\";\n/** Global the preload bridge is exposed as (`contextBridge.exposeInMainWorld`). */\nexport const BRIDGE_KEY = \"guidelyElectron\";\n\n/** Desktop operating system names used in Guidely device properties. */\nexport function osName(platform: string): string {\n if (platform === \"darwin\") return \"macos\";\n if (platform === \"win32\") return \"windows\";\n if (platform === \"linux\") return \"linux\";\n return platform;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;;;AC0BO,IAAM,mBAAmB;AAEzB,IAAM,aAAa;;;ADAnB,SAAS,cAAc,MAAgF;AAC5G,MAAI,SAA0C;AAC9C,QAAM,SAAgC;AAAA,IACpC,YAAY,MAAO,oBAAW,KAAK,YAAY,OAAO,gBAAgB;AAAA,EACxE;AACA,OAAK,cAAc,kBAAkB,YAAY,MAAM;AACzD;","names":[]}
@@ -0,0 +1,30 @@
1
+ export { E as ElectronAppInfo, G as GuidelyElectronBridge } from './types-BEnWCecg.cjs';
2
+
3
+ /** The parts of Electron's `contextBridge` the helper uses. */
4
+ interface ContextBridgeLike {
5
+ exposeInMainWorld(key: string, api: unknown): void;
6
+ }
7
+ /** The parts of Electron's `ipcRenderer` the helper uses. */
8
+ interface IpcRendererLike {
9
+ invoke(channel: string, ...args: unknown[]): Promise<unknown>;
10
+ }
11
+ /**
12
+ * Preload script: exposes `window.guidelyElectron.getAppInfo()` to the page (works with
13
+ * `contextIsolation: true`; the page gets a function, never `ipcRenderer` itself).
14
+ *
15
+ * ```ts
16
+ * // preload.ts
17
+ * import { contextBridge, ipcRenderer } from "electron";
18
+ * import { exposeGuidely } from "@guidelytech/electron/preload";
19
+ * exposeGuidely({ contextBridge, ipcRenderer });
20
+ * ```
21
+ *
22
+ * Sandboxed preloads (Electron's default since 20) can't `require` npm packages: bundle the preload
23
+ * (esbuild, Vite, webpack), or copy these few lines into it.
24
+ */
25
+ declare function exposeGuidely(opts: {
26
+ contextBridge: ContextBridgeLike;
27
+ ipcRenderer: IpcRendererLike;
28
+ }): void;
29
+
30
+ export { type ContextBridgeLike, type IpcRendererLike, exposeGuidely };
@@ -0,0 +1,30 @@
1
+ export { E as ElectronAppInfo, G as GuidelyElectronBridge } from './types-BEnWCecg.js';
2
+
3
+ /** The parts of Electron's `contextBridge` the helper uses. */
4
+ interface ContextBridgeLike {
5
+ exposeInMainWorld(key: string, api: unknown): void;
6
+ }
7
+ /** The parts of Electron's `ipcRenderer` the helper uses. */
8
+ interface IpcRendererLike {
9
+ invoke(channel: string, ...args: unknown[]): Promise<unknown>;
10
+ }
11
+ /**
12
+ * Preload script: exposes `window.guidelyElectron.getAppInfo()` to the page (works with
13
+ * `contextIsolation: true`; the page gets a function, never `ipcRenderer` itself).
14
+ *
15
+ * ```ts
16
+ * // preload.ts
17
+ * import { contextBridge, ipcRenderer } from "electron";
18
+ * import { exposeGuidely } from "@guidelytech/electron/preload";
19
+ * exposeGuidely({ contextBridge, ipcRenderer });
20
+ * ```
21
+ *
22
+ * Sandboxed preloads (Electron's default since 20) can't `require` npm packages: bundle the preload
23
+ * (esbuild, Vite, webpack), or copy these few lines into it.
24
+ */
25
+ declare function exposeGuidely(opts: {
26
+ contextBridge: ContextBridgeLike;
27
+ ipcRenderer: IpcRendererLike;
28
+ }): void;
29
+
30
+ export { type ContextBridgeLike, type IpcRendererLike, exposeGuidely };
@@ -0,0 +1,17 @@
1
+ import {
2
+ APP_INFO_CHANNEL,
3
+ BRIDGE_KEY
4
+ } from "./chunk-AGZOVF3N.js";
5
+
6
+ // src/preload.ts
7
+ function exposeGuidely(opts) {
8
+ let cached = null;
9
+ const bridge = {
10
+ getAppInfo: () => cached ?? (cached = opts.ipcRenderer.invoke(APP_INFO_CHANNEL))
11
+ };
12
+ opts.contextBridge.exposeInMainWorld(BRIDGE_KEY, bridge);
13
+ }
14
+ export {
15
+ exposeGuidely
16
+ };
17
+ //# sourceMappingURL=preload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/preload.ts"],"sourcesContent":["import { APP_INFO_CHANNEL, BRIDGE_KEY, type ElectronAppInfo, type GuidelyElectronBridge } from \"./types\";\n\nexport type { ElectronAppInfo, GuidelyElectronBridge } from \"./types\";\n\n/** The parts of Electron's `contextBridge` the helper uses. */\nexport interface ContextBridgeLike {\n exposeInMainWorld(key: string, api: unknown): void;\n}\n\n/** The parts of Electron's `ipcRenderer` the helper uses. */\nexport interface IpcRendererLike {\n invoke(channel: string, ...args: unknown[]): Promise<unknown>;\n}\n\n/**\n * Preload script: exposes `window.guidelyElectron.getAppInfo()` to the page (works with\n * `contextIsolation: true`; the page gets a function, never `ipcRenderer` itself).\n *\n * ```ts\n * // preload.ts\n * import { contextBridge, ipcRenderer } from \"electron\";\n * import { exposeGuidely } from \"@guidelytech/electron/preload\";\n * exposeGuidely({ contextBridge, ipcRenderer });\n * ```\n *\n * Sandboxed preloads (Electron's default since 20) can't `require` npm packages: bundle the preload\n * (esbuild, Vite, webpack), or copy these few lines into it.\n */\nexport function exposeGuidely(opts: { contextBridge: ContextBridgeLike; ipcRenderer: IpcRendererLike }): void {\n let cached: Promise<ElectronAppInfo> | null = null;\n const bridge: GuidelyElectronBridge = {\n getAppInfo: () => (cached ??= opts.ipcRenderer.invoke(APP_INFO_CHANNEL) as Promise<ElectronAppInfo>),\n };\n opts.contextBridge.exposeInMainWorld(BRIDGE_KEY, bridge);\n}\n"],"mappings":";;;;;;AA4BO,SAAS,cAAc,MAAgF;AAC5G,MAAI,SAA0C;AAC9C,QAAM,SAAgC;AAAA,IACpC,YAAY,MAAO,oBAAW,KAAK,YAAY,OAAO,gBAAgB;AAAA,EACxE;AACA,OAAK,cAAc,kBAAkB,YAAY,MAAM;AACzD;","names":[]}
@@ -0,0 +1,31 @@
1
+ /** What the main process knows about the desktop app, sent to the renderer over IPC. */
2
+ interface ElectronAppInfo {
3
+ /** `app.getName()`. */
4
+ appName: string;
5
+ /** `app.getVersion()` (from package.json). */
6
+ appVersion: string;
7
+ /** `process.platform`: `darwin`, `win32`, `linux`. */
8
+ platform: string;
9
+ /** `process.arch`: `x64`, `arm64`, … */
10
+ arch: string;
11
+ /** `os.release()` / `process.getSystemVersion()`, when available. */
12
+ osVersion?: string;
13
+ electronVersion?: string;
14
+ chromeVersion?: string;
15
+ /** `app.getLocale()`. */
16
+ locale?: string;
17
+ /** `app.isPackaged`: false while running from source (`electron .`). */
18
+ packaged?: boolean;
19
+ }
20
+ /** The API the preload script exposes on `window.guidelyElectron`. */
21
+ interface GuidelyElectronBridge {
22
+ getAppInfo(): Promise<ElectronAppInfo>;
23
+ }
24
+ /** IPC channel used between the main-process handler and the preload bridge. */
25
+ declare const APP_INFO_CHANNEL = "guidely:app-info";
26
+ /** Global the preload bridge is exposed as (`contextBridge.exposeInMainWorld`). */
27
+ declare const BRIDGE_KEY = "guidelyElectron";
28
+ /** Desktop operating system names used in Guidely device properties. */
29
+ declare function osName(platform: string): string;
30
+
31
+ export { APP_INFO_CHANNEL as A, BRIDGE_KEY as B, type ElectronAppInfo as E, type GuidelyElectronBridge as G, osName as o };
@@ -0,0 +1,31 @@
1
+ /** What the main process knows about the desktop app, sent to the renderer over IPC. */
2
+ interface ElectronAppInfo {
3
+ /** `app.getName()`. */
4
+ appName: string;
5
+ /** `app.getVersion()` (from package.json). */
6
+ appVersion: string;
7
+ /** `process.platform`: `darwin`, `win32`, `linux`. */
8
+ platform: string;
9
+ /** `process.arch`: `x64`, `arm64`, … */
10
+ arch: string;
11
+ /** `os.release()` / `process.getSystemVersion()`, when available. */
12
+ osVersion?: string;
13
+ electronVersion?: string;
14
+ chromeVersion?: string;
15
+ /** `app.getLocale()`. */
16
+ locale?: string;
17
+ /** `app.isPackaged`: false while running from source (`electron .`). */
18
+ packaged?: boolean;
19
+ }
20
+ /** The API the preload script exposes on `window.guidelyElectron`. */
21
+ interface GuidelyElectronBridge {
22
+ getAppInfo(): Promise<ElectronAppInfo>;
23
+ }
24
+ /** IPC channel used between the main-process handler and the preload bridge. */
25
+ declare const APP_INFO_CHANNEL = "guidely:app-info";
26
+ /** Global the preload bridge is exposed as (`contextBridge.exposeInMainWorld`). */
27
+ declare const BRIDGE_KEY = "guidelyElectron";
28
+ /** Desktop operating system names used in Guidely device properties. */
29
+ declare function osName(platform: string): string;
30
+
31
+ export { APP_INFO_CHANNEL as A, BRIDGE_KEY as B, type ElectronAppInfo as E, type GuidelyElectronBridge as G, osName as o };
package/package.json CHANGED
@@ -1,6 +1,72 @@
1
1
  {
2
2
  "name": "@guidelytech/electron",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.11.0",
4
+ "description": "Guidely for Electron apps: page paths for file:// and custom protocols, app version and OS metadata, preload bridge",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "sideEffects": false,
8
+ "main": "./dist/index.cjs",
9
+ "module": "./dist/index.js",
10
+ "types": "./dist/index.d.ts",
11
+ "exports": {
12
+ ".": {
13
+ "types": "./dist/index.d.ts",
14
+ "import": "./dist/index.js",
15
+ "require": "./dist/index.cjs"
16
+ },
17
+ "./main": {
18
+ "types": "./dist/main.d.ts",
19
+ "import": "./dist/main.js",
20
+ "require": "./dist/main.cjs"
21
+ },
22
+ "./preload": {
23
+ "types": "./dist/preload.d.ts",
24
+ "import": "./dist/preload.js",
25
+ "require": "./dist/preload.cjs"
26
+ }
27
+ },
28
+ "files": [
29
+ "dist",
30
+ "README.md"
31
+ ],
32
+ "dependencies": {
33
+ "@guidelytech/sdk-core": "0.11.0"
34
+ },
35
+ "devDependencies": {
36
+ "@eslint/js": "^9.39.5",
37
+ "@types/node": "^22.20.5",
38
+ "eslint": "^9.39.5",
39
+ "tsup": "^8.5.1",
40
+ "typescript": "^5.9.3",
41
+ "typescript-eslint": "^8.46.0",
42
+ "vitest": "^3.2.7",
43
+ "happy-dom": "^17.6.3"
44
+ },
45
+ "publishConfig": {
46
+ "access": "public"
47
+ },
48
+ "repository": {
49
+ "type": "git",
50
+ "url": "git+https://github.com/GuidelyTech/Guidely.git",
51
+ "directory": "packages/electron"
52
+ },
53
+ "homepage": "https://github.com/GuidelyTech/Guidely/tree/main/packages/electron#readme",
54
+ "bugs": {
55
+ "url": "https://github.com/GuidelyTech/Guidely/issues"
56
+ },
57
+ "keywords": [
58
+ "guidely",
59
+ "electron",
60
+ "desktop",
61
+ "analytics",
62
+ "onboarding"
63
+ ],
64
+ "scripts": {
65
+ "build": "rm -rf dist && tsup",
66
+ "dev": "tsup --watch",
67
+ "typecheck": "tsc --noEmit",
68
+ "test": "vitest run",
69
+ "lint": "eslint src",
70
+ "clean": "rm -rf dist"
71
+ }
6
72
  }