@omega.js/desktop 0.52.0 → 0.54.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/README.md +53 -48
- package/dist/assets/css/core/_initialize.scss +1 -1
- package/dist/assets/js/core/app-shell.js +14 -15
- package/dist/assets/themes/_template/_theme.js +6 -6
- package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
- package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
- package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
- package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
- package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
- package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
- package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
- package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
- package/dist/assets/themes/base/_theme.js +4 -3
- package/dist/assets/themes/bootstrap/_theme.js +2 -2
- package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
- package/dist/assets/themes/classy/_theme.js +8 -6
- package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
- package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
- package/dist/assets/themes/neobrutalism/_theme.js +5 -5
- package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/assets/themes/newsflash/_theme.js +6 -6
- package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
- package/dist/build.js +87 -111
- package/dist/cli-run.js +4 -1
- package/dist/cli.js +3 -3
- package/dist/commands/build.js +2 -2
- package/dist/commands/cdp/capture.js +2 -2
- package/dist/commands/cdp/client.js +1 -1
- package/dist/commands/cdp/quit.js +2 -2
- package/dist/commands/cdp/relaunch.js +2 -2
- package/dist/commands/cdp/theme.js +1 -1
- package/dist/commands/cdp.js +1 -1
- package/dist/commands/clean.js +4 -5
- package/dist/commands/deploy.js +4 -4
- package/dist/commands/dev.js +25 -0
- package/dist/commands/finalize-release.js +4 -4
- package/dist/commands/launch.js +2 -2
- package/dist/commands/lib/deploy-precheck.js +3 -3
- package/dist/commands/lib/ensure-target.js +18 -23
- package/dist/commands/lib/migrate.js +17 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/package.js +2 -2
- package/dist/commands/publish.js +2 -2
- package/dist/commands/release.js +4 -4
- package/dist/commands/runner.js +11 -11
- package/dist/commands/sign-windows.js +5 -5
- package/dist/commands/test.js +8 -8
- package/dist/commands/update.js +7 -6
- package/dist/commands/validate-certs.js +4 -4
- package/dist/commands/version.js +3 -3
- package/dist/defaults/.github/workflows/build.yml +18 -18
- package/dist/defaults/_.gitignore +0 -2
- package/dist/defaults/_mas/README.md +3 -3
- package/dist/defaults/config/certs/README.md +1 -1
- package/dist/defaults/config/omega.json5 +43 -43
- package/dist/defaults/docs/README.md +3 -3
- package/dist/defaults/gulpfile.js +1 -1
- package/dist/defaults/hooks/build/post.js +2 -2
- package/dist/defaults/hooks/build/pre.js +2 -2
- package/dist/defaults/hooks/deploy/pre.js +1 -1
- package/dist/defaults/hooks/notarize/post.js +2 -2
- package/dist/defaults/hooks/release/post.js +2 -2
- package/dist/defaults/hooks/release/pre.js +2 -2
- package/dist/defaults/src/assets/js/components/about/index.js +3 -5
- package/dist/defaults/src/assets/js/components/main/index.js +3 -5
- package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
- package/dist/defaults/src/assets/scss/pages/about.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/main.scss +1 -1
- package/dist/defaults/src/assets/scss/pages/settings.scss +1 -1
- package/dist/defaults/src/integrations/context-menu/index.js +13 -13
- package/dist/defaults/src/integrations/menu/index.js +8 -8
- package/dist/defaults/src/integrations/tray/index.js +12 -12
- package/dist/defaults/src/main.js +5 -7
- package/dist/defaults/src/preload.js +4 -6
- package/dist/defaults/test/README.md +5 -5
- package/dist/defaults/test/_init.js +1 -1
- package/dist/gulp/main.js +9 -10
- package/dist/gulp/tasks/audit.js +11 -14
- package/dist/gulp/tasks/build-config.js +8 -8
- package/dist/gulp/tasks/bundle.js +16 -16
- package/dist/gulp/tasks/defaults.js +3 -3
- package/dist/gulp/tasks/distribute.js +2 -2
- package/dist/gulp/tasks/html.js +9 -9
- package/dist/gulp/tasks/package-quick.js +3 -3
- package/dist/gulp/tasks/package.js +3 -3
- package/dist/gulp/tasks/release.js +3 -3
- package/dist/gulp/tasks/sass.js +6 -6
- package/dist/gulp/tasks/serve.js +4 -4
- package/dist/hooks/notarize-artifacts.js +1 -1
- package/dist/hooks/notarize.js +1 -1
- package/dist/index.js +5 -8
- package/dist/lib/_environment-mixin.js +50 -0
- package/dist/lib/_lifecycle-mixin.js +45 -0
- package/dist/lib/analytics.js +33 -35
- package/dist/lib/app-state.js +14 -14
- package/dist/lib/auth-flow.js +18 -18
- package/dist/lib/auth-persistence.js +12 -12
- package/dist/lib/auth.js +421 -0
- package/dist/lib/auto-updater.js +49 -49
- package/dist/lib/context-menu.js +13 -13
- package/dist/lib/context.js +19 -19
- package/dist/lib/deep-link.js +34 -34
- package/dist/lib/fontawesome.js +5 -5
- package/dist/lib/ipc.js +4 -4
- package/dist/lib/menu.js +25 -25
- package/dist/lib/protocol.js +5 -5
- package/dist/lib/remote-config.js +22 -22
- package/dist/lib/remote-scripts.js +21 -21
- package/dist/lib/restart-manager/index.js +29 -29
- package/dist/lib/restart-manager/install.js +1 -1
- package/dist/lib/restart-manager/protocol.js +1 -1
- package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
- package/dist/lib/sign-helpers/sign-events.js +1 -1
- package/dist/lib/startup.js +18 -13
- package/dist/lib/storage.js +10 -10
- package/dist/lib/templating.js +16 -16
- package/dist/lib/theme.js +10 -10
- package/dist/lib/tray.js +27 -27
- package/dist/lib/usage.js +11 -11
- package/dist/lib/window-manager.js +26 -26
- package/dist/main.js +399 -483
- package/dist/preload.js +236 -176
- package/dist/renderer.js +417 -391
- package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
- package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
- package/dist/test/fixtures/consumer-app/src/main.js +5 -7
- package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
- package/dist/test/harness/boot-entry.js +22 -20
- package/dist/test/harness/main-entry.js +31 -30
- package/dist/test/harness/renderer-entry.js +5 -5
- package/dist/test/harness/renderer-preload.js +137 -141
- package/dist/test/index.js +10 -10
- package/dist/test/runner.js +2 -2
- package/dist/test/runners/boot.js +7 -6
- package/dist/test/runners/electron.js +3 -2
- package/dist/test/runners/render-event.js +2 -2
- package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
- package/dist/test/suites/boot/restart-manager.test.js +2 -2
- package/dist/test/suites/boot/storage-bundled.test.js +5 -5
- package/dist/test/suites/boot/theme.test.js +13 -13
- package/dist/test/suites/build/audit.test.js +21 -8
- package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
- package/dist/test/suites/build/boot-fixture.test.js +2 -2
- package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
- package/dist/test/suites/build/brand-scss.test.js +1 -1
- package/dist/test/suites/build/build-json-bake.test.js +1 -1
- package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
- package/dist/test/suites/build/cli.test.js +30 -2
- package/dist/test/suites/build/config-schema.test.js +5 -5
- package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +21 -7
- package/dist/test/suites/build/deploy-direct.test.js +7 -5
- package/dist/test/suites/build/deploy-dispatch.test.js +2 -1
- package/dist/test/suites/build/deploy-hook.test.js +7 -5
- package/dist/test/suites/build/dev-verb.test.js +67 -0
- package/dist/test/suites/build/ensure-target.test.js +13 -5
- package/dist/test/suites/build/env-delivery.test.js +2 -2
- package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
- package/dist/test/suites/build/exports.test.js +9 -8
- package/dist/test/suites/build/get-config.test.js +4 -4
- package/dist/test/suites/build/manifest-deps.test.js +1 -1
- package/dist/test/suites/build/merge-line-files.test.js +7 -7
- package/dist/test/suites/build/migrate.test.js +29 -0
- package/dist/test/suites/build/omega-shell.test.js +34 -2
- package/dist/test/suites/build/omega.test.js +350 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
- package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
- package/dist/test/suites/build/runner-env-write.test.js +73 -0
- package/dist/test/suites/build/runner.test.js +11 -10
- package/dist/test/suites/build/sentry.test.js +2 -2
- package/dist/test/suites/build/setup-scripts.test.js +27 -0
- package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
- package/dist/test/suites/build/templating.test.js +3 -3
- package/dist/test/suites/build/test-stealth.test.js +7 -9
- package/dist/test/suites/build/url-helpers.test.js +55 -56
- package/dist/test/suites/build/validate-config.test.js +15 -4
- package/dist/test/suites/build/verb-logs.test.js +20 -0
- package/dist/test/suites/build/wave5-pins.test.js +2 -2
- package/dist/test/suites/main/analytics.test.js +59 -59
- package/dist/test/suites/main/app-state.test.js +66 -66
- package/dist/test/suites/main/auth-flow.test.js +41 -41
- package/dist/test/suites/main/auth-persistence.test.js +54 -43
- package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
- package/dist/test/suites/main/auth.test.js +336 -0
- package/dist/test/suites/main/auto-updater.test.js +134 -134
- package/dist/test/suites/main/boot-sequence.test.js +37 -49
- package/dist/test/suites/main/context-menu.test.js +51 -50
- package/dist/test/suites/main/context.test.js +25 -25
- package/dist/test/suites/main/deep-link.test.js +74 -74
- package/dist/test/suites/main/fontawesome.test.js +27 -27
- package/dist/test/suites/main/ipc.test.js +35 -35
- package/dist/test/suites/main/menu.test.js +101 -100
- package/dist/test/suites/main/protocol.test.js +19 -19
- package/dist/test/suites/main/remote-config.test.js +63 -63
- package/dist/test/suites/main/remote-scripts.test.js +103 -103
- package/dist/test/suites/main/request.test.js +71 -0
- package/dist/test/suites/main/restart-manager.test.js +33 -33
- package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
- package/dist/test/suites/main/startup.test.js +26 -26
- package/dist/test/suites/main/stealth-window.test.js +1 -1
- package/dist/test/suites/main/storage.test.js +25 -25
- package/dist/test/suites/main/theme.test.js +34 -34
- package/dist/test/suites/main/tray.test.js +79 -79
- package/dist/test/suites/main/url-helpers.test.js +133 -133
- package/dist/test/suites/main/usage.test.js +25 -25
- package/dist/test/suites/main/window-bounds.test.js +27 -27
- package/dist/test/suites/main/window-manager.test.js +44 -44
- package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
- package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
- package/dist/test/suites/renderer/round-trip.test.js +3 -3
- package/dist/test/suites/renderer/tooltips.test.js +15 -15
- package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +28 -8
- package/dist/test/utils/extended-mode-warning.js +1 -1
- package/dist/utils/boot-harness.js +56 -0
- package/dist/utils/build-pipeline.js +4 -4
- package/dist/utils/mode-helpers.js +2 -15
- package/dist/utils/runner-env.js +13 -28
- package/dist/utils/ship-keys.js +3 -3
- package/dist/utils/signing-status.js +51 -0
- package/dist/utils/test-events.js +7 -0
- package/dist/utils/test-stealth.js +6 -6
- package/dist/utils/url-helpers.js +52 -42
- package/dist/utils/user-agent.js +44 -0
- package/dist/vendor/account/engine.js +3 -3
- package/dist/vendor/account/index.js +14 -45
- package/dist/vendor/account/resolve-account.js +44 -0
- package/dist/vendor/account/schema.js +1 -1
- package/dist/vendor/account/user.js +99 -0
- package/dist/vendor/config/client-config.js +1 -1
- package/dist/vendor/config/company.js +46 -14
- package/dist/vendor/config/defaults.js +30 -7
- package/dist/vendor/config/edit.js +25 -3
- package/dist/vendor/config/env-delivery.js +1 -1
- package/dist/vendor/config/env-schema.js +3 -6
- package/dist/vendor/config/env.js +34 -22
- package/dist/vendor/config/environment.js +11 -30
- package/dist/vendor/config/index.js +21 -28
- package/dist/vendor/config/load.js +16 -9
- package/dist/vendor/config/platforms.js +1 -1
- package/dist/vendor/config/repo.js +10 -27
- package/dist/vendor/config/schema-client.js +64 -0
- package/dist/vendor/config/schema-cloud.js +38 -0
- package/dist/vendor/config/schema-manager.js +118 -0
- package/dist/vendor/config/schema-overrides.js +68 -0
- package/dist/vendor/config/schema.js +104 -160
- package/dist/vendor/config/site-global.js +2 -3
- package/dist/vendor/config/validate.js +97 -78
- package/dist/vendor/config/winback.js +1 -1
- package/dist/vendor/devkit/actions-secrets.js +1 -1
- package/dist/vendor/devkit/agents-md.js +233 -0
- package/dist/vendor/devkit/attach-log-file.js +16 -2
- package/dist/vendor/devkit/build-json.js +1 -1
- package/dist/vendor/devkit/ci-workflows.js +30 -30
- package/dist/vendor/devkit/cli-router.js +16 -11
- package/dist/vendor/devkit/defaults-engine.js +15 -51
- package/dist/vendor/devkit/deploy-snapshot.js +44 -9
- package/dist/vendor/devkit/env-lines.js +183 -0
- package/dist/vendor/devkit/local.js +64 -10
- package/dist/vendor/devkit/lockfile.js +32 -13
- package/dist/vendor/devkit/logger.js +7 -2
- package/dist/vendor/devkit/merge-line-files.js +219 -177
- package/dist/vendor/devkit/omega-bin.js +208 -111
- package/dist/vendor/devkit/preludes/docs-sync.js +52 -0
- package/dist/vendor/devkit/preludes/index.js +1 -0
- package/dist/vendor/devkit/target-picker.js +45 -0
- package/dist/vendor/devkit/test/dashed-files.js +37 -0
- package/dist/vendor/devkit/test/run-verb-under-tee.js +71 -0
- package/dist/vendor/devkit/test/runner-core.js +6 -6
- package/dist/vendor/devkit/update.js +15 -15
- package/dist/vendor/devkit/verb-scripts.js +40 -0
- package/dist/vendor/devkit/verbs.js +170 -0
- package/dist/vendor/monitoring/env.js +2 -2
- package/dist/vendor/monitoring/index.js +1 -1
- package/dist/vendor/monitoring/main.js +1 -1
- package/dist/vendor/monitoring/preload.js +1 -1
- package/dist/vendor/monitoring/renderer.js +1 -1
- package/package.json +19 -26
- package/dist/commands/install.js +0 -37
- package/dist/defaults/AGENTS.md +0 -110
- package/dist/defaults/CLAUDE.md +0 -1
- package/dist/lib/client-bridge.js +0 -374
- package/dist/lib/logger.js +0 -4
- package/dist/test/suites/build/manager.test.js +0 -213
- package/dist/test/suites/main/client-bridge.test.js +0 -262
- package/dist/vendor/config/env-retired.js +0 -137
- package/dist/vendor/config/retired-keys.js +0 -635
- package/docs/analytics.md +0 -140
- package/docs/app-state.md +0 -92
- package/docs/audit.md +0 -69
- package/docs/auto-updater.md +0 -243
- package/docs/boot-sequence.md +0 -39
- package/docs/build-system.md +0 -169
- package/docs/cdp-debugging.md +0 -169
- package/docs/client-bridge.md +0 -269
- package/docs/common-mistakes.md +0 -21
- package/docs/config-schema.md +0 -120
- package/docs/context-menu.md +0 -112
- package/docs/context.md +0 -81
- package/docs/css.md +0 -90
- package/docs/deep-link.md +0 -186
- package/docs/environment-detection.md +0 -112
- package/docs/fontawesome.md +0 -107
- package/docs/hooks.md +0 -89
- package/docs/icons.md +0 -79
- package/docs/index.md +0 -317
- package/docs/installer-options.md +0 -165
- package/docs/ipc.md +0 -61
- package/docs/lib-modules.md +0 -53
- package/docs/logging.md +0 -229
- package/docs/menu.md +0 -160
- package/docs/releasing.md +0 -239
- package/docs/remote-config.md +0 -118
- package/docs/remote-scripts.md +0 -144
- package/docs/restart-manager.md +0 -144
- package/docs/runner.md +0 -290
- package/docs/sentry.md +0 -97
- package/docs/shared/agent-docs.md +0 -89
- package/docs/shared/analytics.md +0 -612
- package/docs/shared/brands.md +0 -57
- package/docs/shared/breaking-changes.md +0 -851
- package/docs/shared/config.md +0 -1952
- package/docs/shared/deploys.md +0 -341
- package/docs/shared/icons.md +0 -219
- package/docs/shared/local-dev.md +0 -167
- package/docs/shared/logging.md +0 -205
- package/docs/shared/monitoring.md +0 -167
- package/docs/shared/publishing.md +0 -187
- package/docs/shared/rulings.md +0 -34
- package/docs/shared/testing.md +0 -147
- package/docs/shared/theming.md +0 -629
- package/docs/shared/translation.md +0 -333
- package/docs/shared/updates.md +0 -61
- package/docs/signing.md +0 -293
- package/docs/startup.md +0 -142
- package/docs/storage.md +0 -59
- package/docs/templating.md +0 -101
- package/docs/test-boot-layer.md +0 -157
- package/docs/test-framework.md +0 -362
- package/docs/themes.md +0 -149
- package/docs/tooltips.md +0 -99
- package/docs/tray.md +0 -164
- package/docs/usage.md +0 -58
- package/docs/verts.md +0 -62
- package/docs/windows.md +0 -149
package/dist/main.js
CHANGED
|
@@ -1,14 +1,17 @@
|
|
|
1
|
-
//
|
|
2
|
-
// Consumer entry: `
|
|
3
|
-
//
|
|
1
|
+
// The main-process runtime: ONE ready-made `omega` instance.
|
|
2
|
+
// Consumer entry: `const omega = require('@omega.js/desktop/main'); omega.initialize()`; config
|
|
3
|
+
// auto-loads (config/omega.json5). The boot sequence below delegates each step to a `lib/*.js` module.
|
|
4
4
|
|
|
5
5
|
const LoggerLite = require('./lib/logger-lite.js');
|
|
6
6
|
const { setEnvironment, ENVIRONMENT_VAR } = require('./vendor/config/environment.js');
|
|
7
|
+
const { createRequest } = require('@omega.js/client/modules/request.js');
|
|
8
|
+
const environment = require('./lib/_environment-mixin.js');
|
|
9
|
+
const lifecycle = require('./lib/_lifecycle-mixin.js');
|
|
7
10
|
|
|
8
11
|
const storage = require('./lib/storage.js');
|
|
9
12
|
const theme = require('./lib/theme.js');
|
|
10
13
|
const fontawesome = require('./lib/fontawesome.js');
|
|
11
|
-
// Error reporting is the shared @omega.js/monitoring contract (#380)
|
|
14
|
+
// Error reporting is the shared @omega.js/monitoring contract (#380): the
|
|
12
15
|
// package's entry detects main vs renderer and forwards, exactly as the
|
|
13
16
|
// lib/sentry/ split it replaced did.
|
|
14
17
|
const sentry = require('./vendor/monitoring/index.js');
|
|
@@ -22,7 +25,7 @@ const tray = require('./lib/tray.js');
|
|
|
22
25
|
const menu = require('./lib/menu.js');
|
|
23
26
|
const ctxMenu = require('./lib/context-menu.js');
|
|
24
27
|
const startup = require('./lib/startup.js');
|
|
25
|
-
const
|
|
28
|
+
const auth = require('./lib/auth.js');
|
|
26
29
|
const windows = require('./lib/window-manager.js');
|
|
27
30
|
const context = require('./lib/context.js');
|
|
28
31
|
const usage = require('./lib/usage.js');
|
|
@@ -31,499 +34,428 @@ const remoteScripts = require('./lib/remote-scripts.js');
|
|
|
31
34
|
const analytics = require('./lib/analytics.js');
|
|
32
35
|
const restartManager = require('./lib/restart-manager/index.js');
|
|
33
36
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
//
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
// Force a real quit, bypassing per-window `hideOnClose`. Use this anywhere the
|
|
83
|
-
// app legitimately wants to exit (tray Quit, Cmd+Q from menu role:'quit',
|
|
84
|
-
// auto-updater install). Without `{ force: true }`, the close events still get
|
|
85
|
-
// trapped by hide-on-close handlers and the app stays running.
|
|
86
|
-
Manager.prototype.quit = function (options) {
|
|
87
|
-
const self = this;
|
|
88
|
-
options = options || {};
|
|
89
|
-
|
|
90
|
-
if (options.force) {
|
|
91
|
-
self._allowQuit = true;
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
try {
|
|
95
|
-
require('electron').app.quit();
|
|
96
|
-
} catch (e) { /* electron not available — no-op in test/headless */ }
|
|
97
|
-
};
|
|
37
|
+
/**
|
|
38
|
+
* The main-process runtime. This module exports ONE instance of it; a consumer
|
|
39
|
+
* never writes `new`, and awaits `initialize()` or `ready`. Every library is a
|
|
40
|
+
* plain property (`omega.windows`, `omega.tray`, `omega.auth`, ...).
|
|
41
|
+
*/
|
|
42
|
+
class Omega {
|
|
43
|
+
constructor() {
|
|
44
|
+
this.config = null;
|
|
45
|
+
this.logger = new LoggerLite('main');
|
|
46
|
+
|
|
47
|
+
// Quit-vs-hide gating. The window-manager `close` handler checks `_allowQuit` /
|
|
48
|
+
// `_isQuitting` before deciding whether to actually close (=quit) or to swallow
|
|
49
|
+
// the event and just hide the window. Set true via `omega.quit({ force: true })`,
|
|
50
|
+
// by `app.on('before-quit')` (any user-initiated quit), and by the auto-updater
|
|
51
|
+
// when it's about to call `quitAndInstall()`.
|
|
52
|
+
this._allowQuit = false;
|
|
53
|
+
this._isQuitting = false;
|
|
54
|
+
|
|
55
|
+
// Public lib references (consumer code can call them by name)
|
|
56
|
+
this.storage = storage;
|
|
57
|
+
this.theme = theme;
|
|
58
|
+
this.fontawesome = fontawesome;
|
|
59
|
+
this.sentry = sentry;
|
|
60
|
+
this.protocol = protocol;
|
|
61
|
+
this.deepLink = deepLink;
|
|
62
|
+
this.authFlow = authFlow;
|
|
63
|
+
this.appState = appState;
|
|
64
|
+
this.ipc = ipc;
|
|
65
|
+
this.autoUpdater = autoUpdater;
|
|
66
|
+
this.tray = tray;
|
|
67
|
+
this.menu = menu;
|
|
68
|
+
this.contextMenu = ctxMenu;
|
|
69
|
+
this.startup = startup;
|
|
70
|
+
this.auth = auth;
|
|
71
|
+
this.windows = windows;
|
|
72
|
+
this.context = context;
|
|
73
|
+
this.usage = usage;
|
|
74
|
+
this.remoteConfig = remoteConfig;
|
|
75
|
+
this.remoteScripts = remoteScripts;
|
|
76
|
+
this.analytics = analytics;
|
|
77
|
+
this.restartManager = restartManager;
|
|
78
|
+
|
|
79
|
+
// The harmonized API fetch (omega.request), the client base's shape: a
|
|
80
|
+
// fresh Bearer token from main's session when signed in
|
|
81
|
+
this._request = createRequest({
|
|
82
|
+
getApiUrl: () => this.getApiUrl(),
|
|
83
|
+
getIdToken: (force) => this.auth.getIdToken(force),
|
|
84
|
+
});
|
|
98
85
|
|
|
99
|
-
//
|
|
100
|
-
//
|
|
101
|
-
//
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
86
|
+
// Settled by initialize(): resolves with the instance, rejects with the
|
|
87
|
+
// error initialize() rethrows. A module that did not call initialize() can
|
|
88
|
+
// still await it.
|
|
89
|
+
this._readyResolve = null;
|
|
90
|
+
this._readyReject = null;
|
|
91
|
+
this.ready = new Promise((resolve, reject) => {
|
|
92
|
+
this._readyResolve = resolve;
|
|
93
|
+
this._readyReject = reject;
|
|
94
|
+
});
|
|
105
95
|
|
|
106
|
-
|
|
107
|
-
|
|
96
|
+
// A rejected boot nobody awaited must not surface as an unhandled
|
|
97
|
+
// rejection; a consumer awaiting `ready` still sees the error, because this
|
|
98
|
+
// catch hangs off a separate branch of the same promise.
|
|
99
|
+
this.ready.catch(() => {});
|
|
108
100
|
}
|
|
109
101
|
|
|
110
|
-
|
|
102
|
+
// Open the sign-in round trip in the user's default browser (lib/auth-flow.js).
|
|
103
|
+
// Resolves once launched; completion arrives via the auth/token deep-link route →
|
|
104
|
+
// auth.handleToken → the desktop:auth:sign-in-with-token broadcast.
|
|
105
|
+
openAuthFlow(options) {
|
|
106
|
+
return authFlow.open(options);
|
|
107
|
+
}
|
|
111
108
|
|
|
112
|
-
//
|
|
113
|
-
//
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
if (updaterStatus.code === 'downloaded') {
|
|
117
|
-
return self.autoUpdater.installNow();
|
|
109
|
+
// Make an API request: `omega.request('/omega/user/token', { method: 'POST', body: {} })`,
|
|
110
|
+
// with @omega.js/client's options (`auth: false`, `output: 'complete'`, `wakeup: true`)
|
|
111
|
+
request(url, options) {
|
|
112
|
+
return this._request(url, options);
|
|
118
113
|
}
|
|
119
114
|
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
// 2. <appRoot>/config/omega.json5 — resolved via @omega.js/config for dev mode where
|
|
134
|
-
// @omega.js/desktop is loaded directly (unbundled). appRoot = the consumer project dir.
|
|
135
|
-
if (typeof consumerConfig === 'string') {
|
|
136
|
-
consumerConfig = loadResolvedConfig(consumerConfig);
|
|
137
|
-
} else if (!consumerConfig) {
|
|
138
|
-
// Try OMEGA_BUILD_JSON (set by DefinePlugin in packaged builds) first.
|
|
139
|
-
if (typeof OMEGA_BUILD_JSON !== 'undefined' && OMEGA_BUILD_JSON?.config) {
|
|
140
|
-
consumerConfig = OMEGA_BUILD_JSON.config;
|
|
141
|
-
} else {
|
|
142
|
-
const appRoot = require('./utils/app-root.js')();
|
|
143
|
-
consumerConfig = loadResolvedConfig(appRoot);
|
|
115
|
+
/**
|
|
116
|
+
* Boot the main process in the fixed order (docs/desktop/boot-sequence.md), and
|
|
117
|
+
* settle `ready`.
|
|
118
|
+
* @param {object|string} [consumerConfig] - a RESOLVED config, a project dir to resolve one from, or nothing.
|
|
119
|
+
* @param {object} [options] - boot options (the test harness passes `skipWindowCreation`).
|
|
120
|
+
* @returns {Promise<Omega>} the instance.
|
|
121
|
+
*/
|
|
122
|
+
async initialize(consumerConfig, options) {
|
|
123
|
+
try {
|
|
124
|
+
await this._boot(consumerConfig, options);
|
|
125
|
+
} catch (error) {
|
|
126
|
+
this._readyReject(error);
|
|
127
|
+
throw error;
|
|
144
128
|
}
|
|
145
|
-
}
|
|
146
129
|
|
|
147
|
-
|
|
148
|
-
self._options = options || {};
|
|
149
|
-
|
|
150
|
-
// The environment's ONE input is the `OMEGA_ENVIRONMENT` variable
|
|
151
|
-
// ([#817](https://github.com/Omega-JS-Stack/omega/issues/817)), and a lane
|
|
152
|
-
// that named one is NEVER overridden here
|
|
153
|
-
// ([#925](https://github.com/Omega-JS-Stack/omega/issues/925)). The baked word
|
|
154
|
-
// is the FALLBACK, for the one case with no parent lane to inherit from: a
|
|
155
|
-
// packaged app, where this is the input every later read answers (the
|
|
156
|
-
// context-free ones, like test-stealth's, included). A dev boot inherits the
|
|
157
|
-
// word from the gulp lane that spawned this electron, and the test lanes spawn
|
|
158
|
-
// their child with `testing` while booting a PRODUCTION artifact, so writing
|
|
159
|
-
// the baked word over theirs turned every isTesting() gate in a booted app
|
|
160
|
-
// silently off.
|
|
161
|
-
if (!process.env[ENVIRONMENT_VAR] && self.config.environment) {
|
|
162
|
-
setEnvironment(self.config.environment);
|
|
163
|
-
}
|
|
130
|
+
this._readyResolve(this);
|
|
164
131
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
const _path = require('path');
|
|
168
|
-
const _app = require('electron').app;
|
|
132
|
+
return this;
|
|
133
|
+
}
|
|
169
134
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
135
|
+
async _boot(consumerConfig, options) {
|
|
136
|
+
// Accept either an already-RESOLVED config object, a string path to a consumer
|
|
137
|
+
// project dir, or nothing. Default resolution order (when called with no arg):
|
|
138
|
+
// 1. OMEGA_BUILD_JSON.config: injected at build time by the bundle task's esbuild `define`. This is
|
|
139
|
+
// authoritative in packaged apps because config/omega.json5 is inside the asar and
|
|
140
|
+
// not loadable from disk. It's the RESOLVED config (build.getConfig() output:
|
|
141
|
+
// shared sections + targets.desktop overlaid) snapshotted at build time.
|
|
142
|
+
// 2. <appRoot>/config/omega.json5: resolved via @omega.js/config for dev mode where
|
|
143
|
+
// @omega.js/desktop is loaded directly (unbundled). appRoot = the consumer project dir.
|
|
144
|
+
if (typeof consumerConfig === 'string') {
|
|
145
|
+
consumerConfig = loadResolvedConfig(consumerConfig);
|
|
146
|
+
} else if (!consumerConfig) {
|
|
147
|
+
// Try OMEGA_BUILD_JSON (set by DefinePlugin in packaged builds) first.
|
|
148
|
+
if (typeof OMEGA_BUILD_JSON !== 'undefined' && OMEGA_BUILD_JSON?.config) {
|
|
149
|
+
consumerConfig = OMEGA_BUILD_JSON.config;
|
|
150
|
+
} else {
|
|
151
|
+
const appRoot = require('./utils/app-root.js')();
|
|
152
|
+
consumerConfig = loadResolvedConfig(appRoot);
|
|
153
|
+
}
|
|
173
154
|
}
|
|
174
|
-
const _logPath = _app.isPackaged
|
|
175
|
-
? _path.join(_app.getPath('logs'), 'runtime.log')
|
|
176
|
-
: _path.join(process.cwd(), 'logs', 'runtime.log');
|
|
177
|
-
try { fs.writeFileSync(_logPath, ''); } catch (e) {}
|
|
178
|
-
}
|
|
179
155
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
self.logger.log(`signing: signed (${label})`);
|
|
197
|
-
});
|
|
198
|
-
}
|
|
199
|
-
});
|
|
200
|
-
} else if (process.platform === 'win32') {
|
|
201
|
-
execFile('powershell', ['-NoProfile', '-Command', `(Get-AuthenticodeSignature '${process.execPath}').Status`], { encoding: 'utf8' }, (err, stdout) => {
|
|
202
|
-
const status = (stdout || '').trim();
|
|
203
|
-
if (err || status === 'NotSigned') {
|
|
204
|
-
self.logger.warn(`signing: NOT signed`);
|
|
205
|
-
} else {
|
|
206
|
-
self.logger.log(`signing: signed (${status})`);
|
|
207
|
-
}
|
|
208
|
-
});
|
|
209
|
-
} else {
|
|
210
|
-
self.logger.log('signing: n/a (Linux — no OS-level code signing)');
|
|
156
|
+
this.config = consumerConfig || {};
|
|
157
|
+
this._options = options || {};
|
|
158
|
+
|
|
159
|
+
// The environment's ONE input is the `OMEGA_ENVIRONMENT` variable
|
|
160
|
+
// ([#817](https://github.com/Omega-JS-Stack/omega/issues/817)), and a lane
|
|
161
|
+
// that named one is NEVER overridden here
|
|
162
|
+
// ([#925](https://github.com/Omega-JS-Stack/omega/issues/925)). The baked word
|
|
163
|
+
// is the FALLBACK, for the one case with no parent lane to inherit from: a
|
|
164
|
+
// packaged app, where this is the input every later read answers (the
|
|
165
|
+
// context-free ones, like test-stealth's, included). A dev boot inherits the
|
|
166
|
+
// word from the gulp lane that spawned this electron, and the test lanes spawn
|
|
167
|
+
// their child with `testing` while booting a PRODUCTION artifact, so writing
|
|
168
|
+
// the baked word over theirs turned every isTesting() gate in a booted app
|
|
169
|
+
// silently off.
|
|
170
|
+
if (!process.env[ENVIRONMENT_VAR] && this.config.environment) {
|
|
171
|
+
setEnvironment(this.config.environment);
|
|
211
172
|
}
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
173
|
+
|
|
174
|
+
{
|
|
175
|
+
const fs = require('fs');
|
|
176
|
+
const _path = require('path');
|
|
177
|
+
const _app = require('electron').app;
|
|
178
|
+
|
|
179
|
+
const _productName = this.config.app?.productName || this.config.brand?.name;
|
|
180
|
+
if (_productName) {
|
|
181
|
+
_app.setName(_productName);
|
|
182
|
+
}
|
|
183
|
+
const _logPath = _app.isPackaged
|
|
184
|
+
? _path.join(_app.getPath('logs'), 'runtime.log')
|
|
185
|
+
: _path.join(process.cwd(), 'logs', 'runtime.log');
|
|
186
|
+
try { fs.writeFileSync(_logPath, ''); } catch (e) {}
|
|
223
187
|
}
|
|
224
|
-
}
|
|
225
188
|
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
app.on('child-process-gone', (_e, details) => self.logger.warn(`app event: child-process-gone type=${details.type} reason=${details.reason} exitCode=${details.exitCode}`));
|
|
242
|
-
app.on('activate', () => self.logger.log('app event: activate (macOS — dock click or app re-launch)'));
|
|
243
|
-
app.on('open-url', (_e, url) => self.logger.log(`app event: open-url url=${url}`));
|
|
244
|
-
app.on('open-file', (_e, p) => self.logger.log(`app event: open-file path=${p}`));
|
|
245
|
-
|
|
246
|
-
// Process-level signals that bypass Electron's app events. Catches uncaught exceptions
|
|
247
|
-
// so we never crash silently — combined with electron-log file transport, this means
|
|
248
|
-
// ANY unhandled throw lands in runtime.log rather than disappearing into stderr.
|
|
249
|
-
process.on('uncaughtException', (e) => {
|
|
250
|
-
// EPIPE = stdout/stderr pipe closed (CLI consumer hung up). Logging it would
|
|
251
|
-
// write to console, which triggers another EPIPE, cascading into thousands of
|
|
252
|
-
// identical log entries. Exit cleanly — standard Unix behavior.
|
|
253
|
-
if (e?.code === 'EPIPE') {
|
|
254
|
-
process.exit(0);
|
|
255
|
-
return;
|
|
189
|
+
this.logger.log(`Initializing @omega.js/desktop (main)... pid=${process.pid} platform=${process.platform} arch=${process.arch} packaged=${require('electron').app.isPackaged} argv=${JSON.stringify(process.argv.slice(1))}`);
|
|
190
|
+
|
|
191
|
+
require('./utils/signing-status.js')(this.logger);
|
|
192
|
+
|
|
193
|
+
// Schema validation. Hard-fail boot if required fields are missing: same rules as
|
|
194
|
+
// gulp/audit (single source of truth in @omega.js/config: shared schema + the desktop
|
|
195
|
+
// target refinements). We do this before any lib initializes so a misconfigured app
|
|
196
|
+
// fails loud + early instead of partway through boot with a confusing stack trace.
|
|
197
|
+
{
|
|
198
|
+
const { validateConfig, formatErrors } = require('./vendor/config/index.js');
|
|
199
|
+
// A packaged app's config is baked, build facts included: validate it as decorated
|
|
200
|
+
const { errors } = validateConfig(this.config, { target: 'desktop', decorated: true });
|
|
201
|
+
if (errors.length > 0) {
|
|
202
|
+
throw new Error(`@omega.js/desktop: config validation failed. Fix the following in config/omega.json5:\n${formatErrors(errors)}`);
|
|
203
|
+
}
|
|
256
204
|
}
|
|
257
|
-
self.logger.error(`uncaughtException: ${e?.stack || e?.message || String(e)}`);
|
|
258
|
-
});
|
|
259
|
-
process.on('unhandledRejection', (reason) => {
|
|
260
|
-
self.logger.error(`unhandledRejection: ${reason?.stack || reason?.message || String(reason)}`);
|
|
261
|
-
});
|
|
262
|
-
process.on('exit', (code) => {
|
|
263
|
-
// electron-log's file transport flushes synchronously, so this last line lands.
|
|
264
|
-
self.logger.log(`process exit code=${code}`);
|
|
265
|
-
});
|
|
266
|
-
|
|
267
|
-
// 1. Apply early startup-mode hide. For `mode: 'hidden'` we call app.dock.hide() *before*
|
|
268
|
-
// anything else so macOS spends as little time animating the dock entry as possible.
|
|
269
|
-
// In packaged builds the Info.plist's LSUIElement (injected by gulp/build-config when
|
|
270
|
-
// startup.mode === 'hidden') prevents the bounce entirely.
|
|
271
|
-
self.startup._manager = self;
|
|
272
|
-
self.startup._electron = electron || null;
|
|
273
|
-
self.startup.applyEarly();
|
|
274
|
-
|
|
275
|
-
// 1a. Test stealth: suppress app-level activation on macOS. Launching a regular-
|
|
276
|
-
// policy app activates it — menu bar + keyboard focus switch away from whatever
|
|
277
|
-
// the developer is typing in — even though stealth windows surface via
|
|
278
|
-
// showInactive() (see lib/window-manager.js). The accessory policy (the same
|
|
279
|
-
// switch app.dock.hide() flips, and what LSUIElement bakes for packaged
|
|
280
|
-
// hidden-mode apps) keeps the test process from ever activating; windows still
|
|
281
|
-
// render normally. Must run before app ready — activation happens when the app
|
|
282
|
-
// finishes launching. OMEGA_TEST_SHOW=1 restores normal activation along with
|
|
283
|
-
// visible windows.
|
|
284
|
-
if (process.platform === 'darwin' && require('./utils/test-stealth.js')(self)) {
|
|
285
|
-
app.dock.hide();
|
|
286
|
-
self.logger.log('test stealth: app activation suppressed (dock hidden / accessory policy) — launch will not steal focus');
|
|
287
|
-
}
|
|
288
205
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
require('./utils/stealth-window.js').applyStealth(win);
|
|
206
|
+
// electron is a peer dep, main process only (we're in main.js, always defined).
|
|
207
|
+
const electron = require('electron');
|
|
208
|
+
const app = electron.app;
|
|
209
|
+
|
|
210
|
+
// Lifecycle event logging. These are the high-signal app-level events worth tracing
|
|
211
|
+
// when something goes wrong: quit reasons, window-all-closed, will-finish-launching,
|
|
212
|
+
// ready, render-process-gone, child-process-gone. All cheap to log; one line each.
|
|
213
|
+
app.on('before-quit', () => {
|
|
214
|
+
this._isQuitting = true;
|
|
215
|
+
this.logger.log('app event: before-quit (entering quit sequence: close events bypass hide-on-close)');
|
|
300
216
|
});
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
217
|
+
app.on('will-quit', () => this.logger.log('app event: will-quit'));
|
|
218
|
+
app.on('quit', (_e, exitCode) => this.logger.log(`app event: quit code=${exitCode}`));
|
|
219
|
+
app.on('window-all-closed', () => this.logger.log('app event: window-all-closed'));
|
|
220
|
+
app.on('render-process-gone', (_e, webContents, details) => this.logger.warn(`app event: render-process-gone reason=${details.reason} exitCode=${details.exitCode}`));
|
|
221
|
+
app.on('child-process-gone', (_e, details) => this.logger.warn(`app event: child-process-gone type=${details.type} reason=${details.reason} exitCode=${details.exitCode}`));
|
|
222
|
+
app.on('activate', () => this.logger.log('app event: activate (macOS: dock click or app re-launch)'));
|
|
223
|
+
app.on('open-url', (_e, url) => this.logger.log(`app event: open-url url=${url}`));
|
|
224
|
+
app.on('open-file', (_e, p) => this.logger.log(`app event: open-file path=${p}`));
|
|
225
|
+
|
|
226
|
+
// Process-level signals that bypass Electron's app events. Catches uncaught exceptions
|
|
227
|
+
// so we never crash silently: combined with electron-log file transport, this means
|
|
228
|
+
// ANY unhandled throw lands in runtime.log rather than disappearing into stderr.
|
|
229
|
+
process.on('uncaughtException', (e) => {
|
|
230
|
+
// EPIPE = stdout/stderr pipe closed (CLI consumer hung up). Logging it would
|
|
231
|
+
// write to console, which triggers another EPIPE, cascading into thousands of
|
|
232
|
+
// identical log entries. Exit cleanly: standard Unix behavior.
|
|
233
|
+
if (e?.code === 'EPIPE') {
|
|
234
|
+
process.exit(0);
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
this.logger.error(`uncaughtException: ${e?.stack || e?.message || String(e)}`);
|
|
238
|
+
});
|
|
239
|
+
process.on('unhandledRejection', (reason) => {
|
|
240
|
+
this.logger.error(`unhandledRejection: ${reason?.stack || reason?.message || String(reason)}`);
|
|
241
|
+
});
|
|
242
|
+
process.on('exit', (code) => {
|
|
243
|
+
// electron-log's file transport flushes synchronously, so this last line lands.
|
|
244
|
+
this.logger.log(`process exit code=${code}`);
|
|
313
245
|
});
|
|
314
|
-
self.logger.log('test stealth: every BrowserWindow (raw ones included) surfaces invisible + unfocusable, webContents.focus() suppressed (OMEGA_TEST_SHOW=1 to watch)');
|
|
315
|
-
}
|
|
316
246
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
247
|
+
// 1. Apply early startup-mode hide. For `mode: 'hidden'` we call app.dock.hide() *before*
|
|
248
|
+
// anything else so macOS spends as little time animating the dock entry as possible.
|
|
249
|
+
// In packaged builds the Info.plist's LSUIElement (injected by gulp/build-config when
|
|
250
|
+
// startup.mode === 'hidden') prevents the bounce entirely.
|
|
251
|
+
this.startup._omega = this;
|
|
252
|
+
this.startup._electron = electron || null;
|
|
253
|
+
this.startup.applyEarly();
|
|
254
|
+
|
|
255
|
+
// 1a. Test stealth: suppress app-level activation on macOS. Launching a regular-
|
|
256
|
+
// policy app activates it (menu bar + keyboard focus switch away from whatever
|
|
257
|
+
// the developer is typing in) even though stealth windows surface via
|
|
258
|
+
// showInactive() (see lib/window-manager.js). The accessory policy (the same
|
|
259
|
+
// switch app.dock.hide() flips, and what LSUIElement bakes for packaged
|
|
260
|
+
// hidden-mode apps) keeps the test process from ever activating; windows still
|
|
261
|
+
// render normally. Must run before app ready: activation happens when the app
|
|
262
|
+
// finishes launching. OMEGA_TEST_SHOW=1 restores normal activation along with
|
|
263
|
+
// visible windows.
|
|
264
|
+
if (process.platform === 'darwin' && require('./utils/test-stealth.js')(this)) {
|
|
265
|
+
app.dock.hide();
|
|
266
|
+
this.logger.log('test stealth: app activation suppressed (dock hidden / accessory policy), launch will not steal focus');
|
|
332
267
|
}
|
|
333
|
-
app.setPath('userData', after);
|
|
334
|
-
self.logger.log(`userData path: ${before} -> ${after} (testing mode, ${keep ? 'kept' : 'wiped at boot'})`);
|
|
335
|
-
} else if (!self.isProduction()) {
|
|
336
|
-
const before = app.getPath('userData');
|
|
337
|
-
const after = `${before} (Development)`;
|
|
338
|
-
app.setPath('userData', after);
|
|
339
|
-
self.logger.log(`userData path: ${before} -> ${after} (dev mode)`);
|
|
340
|
-
} else {
|
|
341
|
-
self.logger.log(`userData path: ${app.getPath('userData')} (production)`);
|
|
342
|
-
}
|
|
343
268
|
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
}
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
const ua = template(tmpl, ctx);
|
|
372
|
-
app.userAgentFallback = ua;
|
|
373
|
-
self.logger.log(`userAgent: ${ua}`);
|
|
374
|
-
}
|
|
269
|
+
// 1a-ii. Test stealth for EVERY BrowserWindow, including RAW ones created with
|
|
270
|
+
// `new BrowserWindow()` that never pass through lib/window-manager (e.g.
|
|
271
|
+
// a consumer's automation popup). Window-manager stealths only its own
|
|
272
|
+
// named windows via _surface(); this hook closes the gap so no window
|
|
273
|
+
// can flash or steal focus during a test run. The predicate is evaluated
|
|
274
|
+
// PER WINDOW so OMEGA_TEST_SHOW=1 keeps working even when flipped mid-run
|
|
275
|
+
// (the window-manager suite does exactly that).
|
|
276
|
+
if (this.isTesting()) {
|
|
277
|
+
app.on('browser-window-created', (_event, win) => {
|
|
278
|
+
if (!require('./utils/test-stealth.js')(this)) return;
|
|
279
|
+
require('./utils/stealth-window.js').applyStealth(win);
|
|
280
|
+
});
|
|
281
|
+
// webContents.focus() is NOT covered by the window stealth above: it's a
|
|
282
|
+
// different object whose focus() reaches the native window directly,
|
|
283
|
+
// making the invisible window KEY, so the test app grabs the keyboard from
|
|
284
|
+
// whatever the developer is typing in (the accessory policy from 1a does
|
|
285
|
+
// not prevent key-window steals, only launch activation). Consumers call
|
|
286
|
+
// it legitimately (address-bar focus on tab select, overlay dismiss
|
|
287
|
+
// hand-back), so no-op it per-contents under the same predicate.
|
|
288
|
+
// Synthetic input (executeJavaScript, sendInputEvent, CDP) targets a
|
|
289
|
+
// specific webContents and never depends on OS key status.
|
|
290
|
+
app.on('web-contents-created', (_event, wc) => {
|
|
291
|
+
if (!require('./utils/test-stealth.js')(this)) return;
|
|
292
|
+
wc.focus = () => {};
|
|
293
|
+
});
|
|
294
|
+
this.logger.log('test stealth: every BrowserWindow (raw ones included) surfaces invisible + unfocusable, webContents.focus() suppressed (OMEGA_TEST_SHOW=1 to watch)');
|
|
295
|
+
}
|
|
375
296
|
|
|
376
|
-
|
|
377
|
-
|
|
297
|
+
// 1b. Isolate the userData path per environment. MUST run before
|
|
298
|
+
// storage.initialize() because electron-store reads `app.getPath('userData')`
|
|
299
|
+
// at construction time.
|
|
300
|
+
// production → <name> (untouched)
|
|
301
|
+
// development → <name> (Development) (dev runs never touch installed-app data)
|
|
302
|
+
// testing → <name> (Testing) (wiped at boot: every test run starts
|
|
303
|
+
// from a clean slate; post-run state stays
|
|
304
|
+
// on disk for inspection until the next run.
|
|
305
|
+
// Set OMEGA_TEST_KEEP_USERDATA=1 to skip the wipe.)
|
|
306
|
+
if (this.isTesting()) {
|
|
307
|
+
const before = app.getPath('userData');
|
|
308
|
+
const after = `${before} (Testing)`;
|
|
309
|
+
const keep = process.env.OMEGA_TEST_KEEP_USERDATA === '1';
|
|
310
|
+
if (!keep) {
|
|
311
|
+
require('fs').rmSync(after, { recursive: true, force: true });
|
|
312
|
+
}
|
|
313
|
+
app.setPath('userData', after);
|
|
314
|
+
this.logger.log(`userData path: ${before} -> ${after} (testing mode, ${keep ? 'kept' : 'wiped at boot'})`);
|
|
315
|
+
} else if (!this.isProduction()) {
|
|
316
|
+
const before = app.getPath('userData');
|
|
317
|
+
const after = `${before} (Development)`;
|
|
318
|
+
app.setPath('userData', after);
|
|
319
|
+
this.logger.log(`userData path: ${before} -> ${after} (dev mode)`);
|
|
320
|
+
} else {
|
|
321
|
+
this.logger.log(`userData path: ${app.getPath('userData')} (production)`);
|
|
322
|
+
}
|
|
378
323
|
|
|
379
|
-
|
|
380
|
-
|
|
324
|
+
// 1c. Set the global user agent fallback (utils/user-agent.js): a branded UA on
|
|
325
|
+
// every BrowserWindow load, fetch and electron-updater download.
|
|
326
|
+
require('./utils/user-agent.js')(this);
|
|
381
327
|
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
// from its very first paint. Needs storage (override) + ipc (handlers) only.
|
|
385
|
-
self.theme.initialize(self);
|
|
328
|
+
// 2. IPC bus online first: storage and other libs register handlers on it
|
|
329
|
+
this.ipc.initialize(this);
|
|
386
330
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
self.fontawesome.initialize(self);
|
|
331
|
+
// 3. Storage (precedes sentry + auth so opt-out + persisted session are honored)
|
|
332
|
+
await this.storage.initialize(this);
|
|
390
333
|
|
|
391
|
-
|
|
392
|
-
|
|
334
|
+
// 3b. Theme: sets nativeTheme.themeSource from the persisted override / config
|
|
335
|
+
// default, so every renderer (and native UI) resolves the right appearance
|
|
336
|
+
// from its very first paint. Needs storage (override) + ipc (handlers) only.
|
|
337
|
+
this.theme.initialize(this);
|
|
393
338
|
|
|
394
|
-
|
|
395
|
-
|
|
339
|
+
// 3c. FontAwesome: serves the bundled icon SVGs to renderers over IPC
|
|
340
|
+
// (desktop:fontawesome:get). Needs ipc only.
|
|
341
|
+
this.fontawesome.initialize(this);
|
|
396
342
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
// initialize(), letting the consumer's .then() run its whole main.js (servers,
|
|
400
|
-
// shared files, IPC) against a dying Electron — the duplicate must go quietly.
|
|
401
|
-
// The returned promise intentionally never settles; the process exits first.
|
|
402
|
-
self.logger.warn('Single-instance lock lost. Quitting this duplicate instance.');
|
|
403
|
-
app.quit();
|
|
404
|
-
return new Promise(() => {});
|
|
405
|
-
}
|
|
343
|
+
// 4. Sentry (earliest catchable global handler)
|
|
344
|
+
this.sentry.initialize(this);
|
|
406
345
|
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
// Must run AFTER storage (writes deviceId + cached geolocation to storage) and
|
|
419
|
-
// BEFORE analytics (which reads context.session.deviceId). Async but the geolocation
|
|
420
|
-
// fetch is fire-and-forget so this returns quickly.
|
|
421
|
-
await self.context.initialize(self);
|
|
422
|
-
|
|
423
|
-
// 7c. Usage tracking — opens / hours-total / hours-this-session. Reads/writes
|
|
424
|
-
// storage.usage and registers a before-quit handler to record session duration.
|
|
425
|
-
self.usage.initialize(self);
|
|
426
|
-
|
|
427
|
-
// 8. Wait for app readiness before any UI
|
|
428
|
-
await app.whenReady();
|
|
429
|
-
|
|
430
|
-
// 9. Auto-updater (queues check, never blocks UI)
|
|
431
|
-
self.autoUpdater.initialize(self);
|
|
432
|
-
|
|
433
|
-
// 10. Tray + menu + context menu
|
|
434
|
-
self.tray.initialize(self);
|
|
435
|
-
self.menu.initialize(self);
|
|
436
|
-
self.contextMenu.initialize(self);
|
|
437
|
-
|
|
438
|
-
// 11. Open-at-login + hide-on-startup state sync
|
|
439
|
-
self.startup.initialize(self);
|
|
440
|
-
|
|
441
|
-
// 12. Web-manager bridge (main-side Firebase Auth source of truth, IPC handlers for renderers)
|
|
442
|
-
await self.omega.initialize(self);
|
|
443
|
-
|
|
444
|
-
// 12b. Remote config — fetches `<brand.url>/data/resources/main.json` for hot
|
|
445
|
-
// config flips (force-update gate, default user agents, etc.). Polls hourly.
|
|
446
|
-
// Wired AFTER auto-updater so it can inherit feedCheckIntervalMs from there.
|
|
447
|
-
self.remoteConfig.initialize(self);
|
|
448
|
-
|
|
449
|
-
// 12c. Remote scripts — fetches `<brand.url>/data/scripts/main.json` for
|
|
450
|
-
// emergency hotfixes (force-update, storage patches, etc.) when the normal
|
|
451
|
-
// update pipeline is broken. Same polling cadence as remote-config.
|
|
452
|
-
self.remoteScripts.initialize(self);
|
|
453
|
-
|
|
454
|
-
// 12d. Analytics — GA4 via Measurement Protocol. Wired AFTER client-bridge
|
|
455
|
-
// so it can subscribe to onAuthChange and flip user_id automatically.
|
|
456
|
-
self.analytics.initialize(self);
|
|
457
|
-
|
|
458
|
-
// 12e. Restart Manager — external guardian app that relaunches us if we crash.
|
|
459
|
-
// Registers over RM's loopback HTTP protocol (runtime.json advertises the port),
|
|
460
|
-
// heartbeats every 60s, deregisters on graceful quit, and silently installs RM
|
|
461
|
-
// when missing (mac zip / win silent NSIS / linux AppImage — RM then self-updates
|
|
462
|
-
// via its own @omega.js/desktop autoUpdater). Skips itself when this app IS restart-manager, in
|
|
463
|
-
// dev (unless OMEGA_RESTART_MANAGER_DEV=1), or when restartManager.enabled=false.
|
|
464
|
-
// See docs/restart-manager.md.
|
|
465
|
-
self.restartManager.initialize(self);
|
|
466
|
-
|
|
467
|
-
// 13. Initialize the windows lib — registers app-level handlers (window-all-closed, etc.)
|
|
468
|
-
// but does NOT create any windows. Consumers are responsible for calling
|
|
469
|
-
// `manager.windows.create('main')` (or any other named window) from their main.js
|
|
470
|
-
// when they want to surface UI. This makes hidden / agent-app patterns trivial:
|
|
471
|
-
// just don't call create() until something (tray click, deep link, IPC) warrants it.
|
|
472
|
-
self.windows.initialize(self);
|
|
473
|
-
|
|
474
|
-
self._initialized = true;
|
|
475
|
-
|
|
476
|
-
// 14. Release deep-link dispatch — cold-start URLs (and any early open-url)
|
|
477
|
-
// were queued so handlers like auth/token never fire before client-bridge
|
|
478
|
-
// has Firebase up. Everything they touch exists now.
|
|
479
|
-
self.deepLink.markManagerReady();
|
|
480
|
-
|
|
481
|
-
self.logger.log('@omega.js/desktop (main) initialized.');
|
|
482
|
-
|
|
483
|
-
// Boot test harness — runs against the live manager AFTER all libs are up. Test runner
|
|
484
|
-
// sets OMEGA_TEST_BOOT=1 + OMEGA_TEST_BOOT_HARNESS=<absolute path> + OMEGA_TEST_BOOT_SPEC=<path>
|
|
485
|
-
// before spawning electron. The harness emits __EM_TEST__ JSON lines on stdout (parsed
|
|
486
|
-
// by runners/boot.js) then app.exit()s.
|
|
487
|
-
//
|
|
488
|
-
// We use a runtime env-var path (not a static `require('./test/harness/...')`) because
|
|
489
|
-
// @omega.js/desktop is bundled into the consumer's bundle, and a static require would either get
|
|
490
|
-
// inlined (bundling test code into production) or dead-code-eliminated. An env-var
|
|
491
|
-
// path stays external and can only resolve when the runner sets it.
|
|
492
|
-
if (process.env.OMEGA_TEST_BOOT === '1') {
|
|
493
|
-
global.__em_manager = self;
|
|
494
|
-
const harnessPath = process.env.OMEGA_TEST_BOOT_HARNESS;
|
|
495
|
-
if (harnessPath) {
|
|
496
|
-
// Defer the harness so the consumer's `manager.initialize().then(() => { ... })`
|
|
497
|
-
// callback gets a chance to run first. @omega.js/desktop doesn't auto-create any windows; the
|
|
498
|
-
// consumer's main.js does it inside .then(). If we ran the harness synchronously
|
|
499
|
-
// here, that callback wouldn't have fired yet and `manager.windows.get('main')`
|
|
500
|
-
// would be null. setImmediate flushes the microtask queue (where promise callbacks
|
|
501
|
-
// live) before our boot harness inspects state.
|
|
502
|
-
setImmediate(() => {
|
|
503
|
-
try {
|
|
504
|
-
// A variable specifier, so the bundler leaves the call alone and it
|
|
505
|
-
// resolves at RUNTIME against the path the runner set — which is the
|
|
506
|
-
// whole point (see the env-var note above).
|
|
507
|
-
const harness = require(harnessPath);
|
|
508
|
-
harness.run(self);
|
|
509
|
-
} catch (e) {
|
|
510
|
-
const { app } = require('electron');
|
|
511
|
-
process.stdout.write(`__EM_TEST__${JSON.stringify({ event: 'fatal', message: `boot harness failed to load: ${e.message}` })}\n`);
|
|
512
|
-
app.exit(1);
|
|
513
|
-
}
|
|
514
|
-
});
|
|
515
|
-
} else {
|
|
516
|
-
const { app } = require('electron');
|
|
517
|
-
process.stdout.write(`__EM_TEST__${JSON.stringify({ event: 'fatal', message: 'OMEGA_TEST_BOOT=1 but OMEGA_TEST_BOOT_HARNESS not set' })}\n`);
|
|
518
|
-
app.exit(1);
|
|
346
|
+
// 5. Protocol (single-instance lock + custom URL scheme)
|
|
347
|
+
this.protocol.initialize(this);
|
|
348
|
+
|
|
349
|
+
if (!this.protocol.hasSingleInstanceLock()) {
|
|
350
|
+
// Quit the duplicate AND halt the boot: returning normally would resolve
|
|
351
|
+
// initialize(), letting the consumer's .then() run its whole main.js (servers,
|
|
352
|
+
// shared files, IPC) against a dying Electron. The duplicate must go quietly.
|
|
353
|
+
// The returned promise intentionally never settles; the process exits first.
|
|
354
|
+
this.logger.warn('Single-instance lock lost. Quitting this duplicate instance.');
|
|
355
|
+
app.quit();
|
|
356
|
+
return new Promise(() => {});
|
|
519
357
|
}
|
|
358
|
+
|
|
359
|
+
// 6. Deep links (parse cold-start argv, install second-instance handler)
|
|
360
|
+
this.deepLink.initialize(this);
|
|
361
|
+
|
|
362
|
+
// 6b. Auth flow (the getAuthUrl sign-in round trip: external browser always;
|
|
363
|
+
// dev/test return via a loopback listener since the scheme isn't OS-registered)
|
|
364
|
+
this.authFlow.initialize(this);
|
|
365
|
+
|
|
366
|
+
// 7. App state (first-launch / crash / startup-context flags)
|
|
367
|
+
await this.appState.initialize(this);
|
|
368
|
+
|
|
369
|
+
// 7b. Runtime context: session id, deviceId, OS info, async geolocation fetch.
|
|
370
|
+
// Must run AFTER storage (writes deviceId + cached geolocation to storage) and
|
|
371
|
+
// BEFORE analytics (which reads context.session.deviceId). Async but the geolocation
|
|
372
|
+
// fetch is fire-and-forget so this returns quickly.
|
|
373
|
+
await this.context.initialize(this);
|
|
374
|
+
|
|
375
|
+
// 7c. Usage tracking: opens / hours-total / hours-this-session. Reads/writes
|
|
376
|
+
// storage.usage and registers a before-quit handler to record session duration.
|
|
377
|
+
this.usage.initialize(this);
|
|
378
|
+
|
|
379
|
+
// 8. Wait for app readiness before any UI
|
|
380
|
+
await app.whenReady();
|
|
381
|
+
|
|
382
|
+
// 9. Auto-updater (queues check, never blocks UI)
|
|
383
|
+
this.autoUpdater.initialize(this);
|
|
384
|
+
|
|
385
|
+
// 10. Tray + menu + context menu
|
|
386
|
+
this.tray.initialize(this);
|
|
387
|
+
this.menu.initialize(this);
|
|
388
|
+
this.contextMenu.initialize(this);
|
|
389
|
+
|
|
390
|
+
// 11. Open-at-login + hide-on-startup state sync
|
|
391
|
+
this.startup.initialize(this);
|
|
392
|
+
|
|
393
|
+
// 12. Auth (main-side Firebase Auth source of truth, IPC handlers for renderers)
|
|
394
|
+
await this.auth.initialize(this);
|
|
395
|
+
|
|
396
|
+
// 12b. Remote config: fetches `<brand.url>/data/resources/main.json` for hot
|
|
397
|
+
// config flips (force-update gate, default user agents, etc.). Polls hourly.
|
|
398
|
+
// Wired AFTER auto-updater so it can inherit feedCheckIntervalMs from there.
|
|
399
|
+
this.remoteConfig.initialize(this);
|
|
400
|
+
|
|
401
|
+
// 12c. Remote scripts: fetches `<brand.url>/data/scripts/main.json` for
|
|
402
|
+
// emergency hotfixes (force-update, storage patches, etc.) when the normal
|
|
403
|
+
// update pipeline is broken. Same polling cadence as remote-config.
|
|
404
|
+
this.remoteScripts.initialize(this);
|
|
405
|
+
|
|
406
|
+
// 12d. Analytics: GA4 via Measurement Protocol. Wired AFTER auth so it can
|
|
407
|
+
// listen to it and flip user_id automatically.
|
|
408
|
+
this.analytics.initialize(this);
|
|
409
|
+
|
|
410
|
+
// 12e. Restart Manager: external guardian app that relaunches us if we crash.
|
|
411
|
+
// Registers over RM's loopback HTTP protocol (runtime.json advertises the port),
|
|
412
|
+
// heartbeats every 60s, deregisters on graceful quit, and silently installs RM
|
|
413
|
+
// when missing (mac zip / win silent NSIS / linux AppImage; RM then self-updates
|
|
414
|
+
// via its own @omega.js/desktop autoUpdater). Skips itself when this app IS restart-manager, in
|
|
415
|
+
// dev (unless OMEGA_RESTART_MANAGER_DEV=1), or when restartManager.enabled=false.
|
|
416
|
+
// See docs/desktop/restart-manager.md.
|
|
417
|
+
this.restartManager.initialize(this);
|
|
418
|
+
|
|
419
|
+
// 13. Initialize the windows lib: registers app-level handlers (window-all-closed, etc.)
|
|
420
|
+
// but does NOT create any windows. Consumers are responsible for calling
|
|
421
|
+
// `omega.windows.create('main')` (or any other named window) from their main.js
|
|
422
|
+
// when they want to surface UI. This makes hidden / agent-app patterns trivial:
|
|
423
|
+
// just don't call create() until something (tray click, deep link, IPC) warrants it.
|
|
424
|
+
this.windows.initialize(this);
|
|
425
|
+
|
|
426
|
+
this._initialized = true;
|
|
427
|
+
|
|
428
|
+
// 14. Release deep-link dispatch: cold-start URLs (and any early open-url)
|
|
429
|
+
// were queued so handlers like auth/token never fire before auth
|
|
430
|
+
// has Firebase up. Everything they touch exists now.
|
|
431
|
+
this.deepLink.markOmegaReady();
|
|
432
|
+
|
|
433
|
+
this.logger.log('@omega.js/desktop (main) initialized.');
|
|
434
|
+
|
|
435
|
+
// Boot test harness (utils/boot-harness.js): runs against the live instance AFTER
|
|
436
|
+
// all libs are up, only when the boot test lane spawned this process.
|
|
437
|
+
require('./utils/boot-harness.js')(this);
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
// Require: lets consumer main-process code load @omega.js/desktop's bundled dependencies at runtime
|
|
441
|
+
// (e.g. `omega.require('fs-jetpack')`). Resolves from @omega.js/desktop's module context, not the
|
|
442
|
+
// consumer's. Mirrors @omega.js/backend's omega.require(). For build-time resolution, the
|
|
443
|
+
// bundle task's framework-deps resolve hook handles this automatically.
|
|
444
|
+
require(name) {
|
|
445
|
+
return require(name);
|
|
520
446
|
}
|
|
521
447
|
|
|
522
|
-
|
|
523
|
-
|
|
448
|
+
static require(name) {
|
|
449
|
+
return require(name);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
|
|
453
|
+
// The environment and URL helpers, and quit/relaunch: methods on the instance,
|
|
454
|
+
// each concern in its own lib file
|
|
455
|
+
Object.assign(Omega.prototype, environment, lifecycle);
|
|
524
456
|
|
|
525
457
|
function loadResolvedConfig(projectDir) {
|
|
526
|
-
// @omega.js/config is vendored into dist (and bundled from there)
|
|
458
|
+
// @omega.js/config is vendored into dist (and bundled from there): it
|
|
527
459
|
// finds config/omega.json5 under the project dir and resolves the desktop target
|
|
528
460
|
// (shared sections + targets.desktop overlaid, brand-monorepo walk-up included).
|
|
529
461
|
const { hasOmegaConfig, loadConfig } = require('./vendor/config/index.js');
|
|
@@ -535,24 +467,8 @@ function loadResolvedConfig(projectDir) {
|
|
|
535
467
|
return loadConfig(projectDir, 'desktop').config;
|
|
536
468
|
}
|
|
537
469
|
|
|
538
|
-
//
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
// Require — lets consumer main-process code load @omega.js/desktop's bundled dependencies at runtime
|
|
544
|
-
// (e.g. `manager.require('fs-jetpack')`). Resolves from @omega.js/desktop's module context, not the
|
|
545
|
-
// consumer's. Mirrors @omega.js/backend's Manager.require(). For build-time resolution, the
|
|
546
|
-
// bundle task's framework-deps resolve hook handles this automatically.
|
|
547
|
-
Manager.prototype.require = function (name) {
|
|
548
|
-
return require(name);
|
|
549
|
-
};
|
|
550
|
-
Manager.require = function (name) {
|
|
551
|
-
return require(name);
|
|
552
|
-
};
|
|
553
|
-
|
|
554
|
-
// Mix in shared cross-context helpers — same code path used in renderer, preload, build.
|
|
555
|
-
require('./utils/mode-helpers.js').attachTo(Manager);
|
|
556
|
-
require('./utils/url-helpers.js').attachTo(Manager);
|
|
557
|
-
|
|
558
|
-
module.exports = Manager;
|
|
470
|
+
// The ONE instance, initialized by the consumer's src/main.js
|
|
471
|
+
const omega = new Omega();
|
|
472
|
+
|
|
473
|
+
module.exports = omega;
|
|
474
|
+
module.exports.Omega = Omega;
|