@omega.js/desktop 0.53.0 → 0.54.1
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 +38 -38
- package/dist/cli-run.js +4 -1
- package/dist/cli.js +2 -2
- package/dist/commands/cdp/client.js +1 -1
- package/dist/commands/cdp.js +1 -1
- package/dist/commands/clean.js +2 -3
- package/dist/commands/dev.js +25 -0
- package/dist/commands/lib/ensure-target.js +12 -17
- package/dist/commands/lib/migrate.js +17 -0
- package/dist/commands/logs.js +1 -1
- package/dist/commands/release.js +1 -1
- package/dist/commands/test.js +4 -4
- package/dist/commands/update.js +5 -4
- 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 +36 -36
- package/dist/defaults/docs/README.md +3 -3
- package/dist/defaults/gulpfile.js +1 -1
- package/dist/defaults/hooks/build/post.js +1 -1
- package/dist/defaults/hooks/build/pre.js +1 -1
- package/dist/defaults/hooks/notarize/post.js +2 -2
- package/dist/defaults/hooks/release/post.js +1 -1
- package/dist/defaults/hooks/release/pre.js +1 -1
- 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 +11 -11
- package/dist/defaults/src/integrations/menu/index.js +5 -5
- package/dist/defaults/src/integrations/tray/index.js +9 -9
- package/dist/defaults/src/main.js +2 -2
- package/dist/defaults/src/preload.js +1 -1
- package/dist/defaults/test/README.md +3 -3
- package/dist/defaults/test/_init.js +1 -1
- package/dist/gulp/tasks/audit.js +5 -8
- package/dist/lib/restart-manager/index.js +1 -1
- package/dist/lib/restart-manager/install.js +1 -1
- package/dist/lib/restart-manager/protocol.js +1 -1
- package/dist/main.js +4 -3
- package/dist/preload.js +1 -1
- package/dist/test/suites/build/audit.test.js +20 -7
- package/dist/test/suites/build/build-workflow-jobs.test.js +2 -2
- package/dist/test/suites/build/cli.test.js +28 -0
- package/dist/test/suites/build/defaults-em-dash.test.js +22 -0
- package/dist/test/suites/build/defaults-scaffold.test.js +19 -5
- 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 +4 -2
- package/dist/test/suites/build/dev-verb.test.js +67 -0
- package/dist/test/suites/build/ensure-target.test.js +11 -3
- package/dist/test/suites/build/merge-line-files.test.js +6 -6
- package/dist/test/suites/build/migrate.test.js +29 -0
- package/dist/test/suites/build/project-scripts-deps.test.js +6 -10
- package/dist/test/suites/build/runner-env-write.test.js +73 -0
- package/dist/test/suites/build/runner.test.js +9 -8
- package/dist/test/suites/build/setup-scripts.test.js +27 -0
- package/dist/test/suites/build/validate-config.test.js +13 -2
- package/dist/test/suites/build/verb-logs.test.js +20 -0
- package/dist/test/suites/renderer/window-desktop-surface.test.js +1 -1
- package/dist/utils/build-pipeline.js +4 -4
- package/dist/utils/runner-env.js +13 -28
- 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/index.js +13 -17
- package/dist/vendor/config/load.js +15 -7
- 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 +99 -152
- package/dist/vendor/config/validate.js +97 -77
- package/dist/vendor/devkit/agents-md.js +233 -0
- package/dist/vendor/devkit/attach-log-file.js +15 -1
- package/dist/vendor/devkit/ci-workflows.js +30 -30
- package/dist/vendor/devkit/cli-router.js +13 -7
- package/dist/vendor/devkit/defaults-engine.js +9 -43
- package/dist/vendor/devkit/deploy-snapshot.js +44 -9
- package/dist/vendor/devkit/env-lines.js +183 -0
- package/dist/vendor/devkit/local.js +62 -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 -176
- 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/update.js +15 -15
- package/dist/vendor/devkit/verb-scripts.js +40 -0
- package/dist/vendor/devkit/verbs.js +170 -0
- package/package.json +18 -24
- package/dist/commands/install.js +0 -37
- package/dist/defaults/AGENTS.md +0 -119
- package/dist/defaults/CLAUDE.md +0 -1
- 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/auth.md +0 -284
- package/docs/auto-updater.md +0 -243
- package/docs/boot-sequence.md +0 -44
- package/docs/build-system.md +0 -169
- package/docs/cdp-debugging.md +0 -169
- 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 -84
- package/docs/deep-link.md +0 -186
- package/docs/environment-detection.md +0 -112
- package/docs/fontawesome.md +0 -109
- package/docs/hooks.md +0 -89
- package/docs/icons.md +0 -79
- package/docs/index.md +0 -328
- 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 -227
- 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 -917
- package/docs/shared/config.md +0 -1948
- 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 -342
- 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/docs/themes.md
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
# Themes
|
|
2
|
-
|
|
3
|
-
@omega.js/desktop ships the **classy** theme (built on Bootstrap 5) so consumer apps look polished out of the box. Variables are fully customizable via `@use 'omega-desktop' as * with (...)` — same pattern as UJM and BXM.
|
|
4
|
-
|
|
5
|
-
## How it works
|
|
6
|
-
|
|
7
|
-
@omega.js/desktop carries @omega.js/web's FULL theme tree in `<em>/dist/assets/themes/` — vendored from the resolved `@omega.js/web` devDependency at every prepare via the declared-assets channel (C4 cp104/cp109), never hand-copied:
|
|
8
|
-
|
|
9
|
-
| Theme | Base | Use case |
|
|
10
|
-
|---|---|---|
|
|
11
|
-
| `classy` (default) | Bootstrap 5.3 + OMEGA design system | Polished, modern app shell |
|
|
12
|
-
| `bootstrap` | Plain Bootstrap 5.3 | Minimal, vanilla Bootstrap |
|
|
13
|
-
| `neobrutalism` / `newsflash` | Bootstrap 5.3 | Alternate skins (universal `theme.id`) |
|
|
14
|
-
|
|
15
|
-
The active theme is selected via `config.theme.id` (default `'classy'`). The `gulp/sass` task adds `<em>/dist/assets/themes/<theme>` to its sass `loadPaths` so the bare `@use 'theme'` import inside `@omega.js/desktop.scss` resolves to the active theme.
|
|
16
|
-
|
|
17
|
-
## Consumer setup
|
|
18
|
-
|
|
19
|
-
Your `src/assets/scss/main.scss` becomes:
|
|
20
|
-
|
|
21
|
-
```scss
|
|
22
|
-
// Generated from `brand.color` in config/omega.json5 by the sass task.
|
|
23
|
-
@use 'brand';
|
|
24
|
-
|
|
25
|
-
@use 'omega-desktop' as * with (
|
|
26
|
-
$primary: brand.$primary,
|
|
27
|
-
// $secondary: #6C757D,
|
|
28
|
-
// $border-radius: 0.5rem,
|
|
29
|
-
);
|
|
30
|
-
|
|
31
|
-
// The runtime --omega-accent ramp, AFTER the framework import so it wins the
|
|
32
|
-
// cascade over the token sheet's placeholders.
|
|
33
|
-
@include brand.ramp;
|
|
34
|
-
|
|
35
|
-
// Custom global styles below...
|
|
36
|
-
main {
|
|
37
|
-
padding: 2rem;
|
|
38
|
-
}
|
|
39
|
-
```
|
|
40
|
-
|
|
41
|
-
`$primary` is `brand.color`, not a literal: the sass task writes
|
|
42
|
-
`dist/assets/scss/_brand.scss` from the resolved config before every compile, so
|
|
43
|
-
recoloring the app is a config edit. Want an accent that DIVERGES from the
|
|
44
|
-
brand? Put the literal back in its place: `$primary: #2563EB,`. No `brand.color`
|
|
45
|
-
set at all, and the partial carries the framework default
|
|
46
|
-
([shared/theming.md](shared/theming.md), [#912](https://github.com/Omega-JS-Stack/omega/issues/912)).
|
|
47
|
-
|
|
48
|
-
That single import gives you:
|
|
49
|
-
- Full Bootstrap 5 (utilities, components, grid, etc.)
|
|
50
|
-
- Classy theme overlays (typography, animations, refined spacing)
|
|
51
|
-
- @omega.js/desktop's `_initialize.scss` (desktop-specific defaults — full-window body, app-region drag classes)
|
|
52
|
-
|
|
53
|
-
## Per-page CSS
|
|
54
|
-
|
|
55
|
-
@omega.js/desktop compiles per-page bundles in addition to the shared `main.bundle.css`:
|
|
56
|
-
|
|
57
|
-
```
|
|
58
|
-
src/assets/scss/main.scss → dist/assets/css/main.bundle.css (every page)
|
|
59
|
-
src/assets/scss/pages/main.scss → dist/assets/css/components/main.bundle.css (main window only)
|
|
60
|
-
src/assets/scss/pages/settings.scss → dist/assets/css/components/settings.bundle.css (settings window only)
|
|
61
|
-
src/assets/scss/pages/about.scss → dist/assets/css/components/about.bundle.css (about window only)
|
|
62
|
-
```
|
|
63
|
-
|
|
64
|
-
The page template auto-loads both: `main.bundle.css` is on every HTML page, and `components/<page.name>.bundle.css` is loaded only on its specific page. To add styles for a new page, drop a new file at `src/assets/scss/pages/<view>.scss` — it'll auto-compile and auto-inject.
|
|
65
|
-
|
|
66
|
-
Per-page bundles can themselves `@use 'omega-desktop' as *;` if they need access to theme variables. Just be aware this means re-emitting some shared CSS — for very small per-page tweaks, prefer plain selectors that ride on the shared `main.bundle.css`.
|
|
67
|
-
|
|
68
|
-
## Customizable variables
|
|
69
|
-
|
|
70
|
-
The full classy variable list lives at `<em>/dist/assets/themes/classy/_config.scss`. ~60 variables you can override via the `@use ... with ()` form:
|
|
71
|
-
|
|
72
|
-
**Colors:** `$primary`, `$secondary`, `$success`, `$info`, `$warning`, `$danger`, `$light`, `$dark`
|
|
73
|
-
**Backgrounds (light mode):** `$classy-bg-light`, `$classy-bg-light-secondary`, `$classy-bg-light-tertiary`
|
|
74
|
-
**Backgrounds (dark mode):** `$classy-bg-dark`, `$classy-bg-dark-secondary`, `$classy-bg-dark-tertiary`
|
|
75
|
-
**Typography:** `$font-family-sans-serif`, `$font-family-base`, `$headings-font-weight`, `$classy-font-mono`, `$classy-font-accent`
|
|
76
|
-
**Border radius:** `$border-radius`, `$border-radius-sm/lg/xl/2xl/pill`
|
|
77
|
-
**Spacing, transitions, shadows** — see `_config.scss`
|
|
78
|
-
|
|
79
|
-
## Switching themes
|
|
80
|
-
|
|
81
|
-
Set `config.theme.id` in `config/omega.json5`:
|
|
82
|
-
|
|
83
|
-
```jsonc
|
|
84
|
-
theme: {
|
|
85
|
-
id: 'bootstrap', // 'classy' (default) | 'bootstrap'
|
|
86
|
-
appearance: 'system', // 'system' (default) | 'light' | 'dark'
|
|
87
|
-
}
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
## Appearance (light / dark / system): `omega.theme`
|
|
91
|
-
|
|
92
|
-
@omega.js/desktop owns appearance at runtime. `config.theme.appearance` is only the **app default**; the resolved appearance is applied and kept live by the theme lib:
|
|
93
|
-
|
|
94
|
-
- **`'system'` (default)** follows the OS preference **live** — when the OS flips, every page updates without a reload or restart.
|
|
95
|
-
- **`'light'` / `'dark'`** are explicit overrides.
|
|
96
|
-
- A user's runtime choice (`omega.theme.set(...)`) is **persisted in `omega.storage`** (`theme.appearance`) and wins over the config default on every boot.
|
|
97
|
-
|
|
98
|
-
### How it propagates
|
|
99
|
-
|
|
100
|
-
Everything rides on Electron's `nativeTheme.themeSource` (same three values). Setting it flips `prefers-color-scheme` in **every renderer of the app — BrowserWindows AND embedded WebContentsViews** — and @omega.js/desktop's preload applier listens via `matchMedia` and rewrites `<html data-bs-theme>` to the **resolved** value (`'light'`/`'dark'`) live. No IPC fan-out, no per-window wiring; native UI (menus, dialogs) follows too.
|
|
101
|
-
|
|
102
|
-
The applier is **opt-in by presence**: it only manages pages whose `<html>` already carries `data-bs-theme` (stamped by the page template at build). External sites loaded in a consumer's embedded web views get the same preload but are never touched.
|
|
103
|
-
|
|
104
|
-
### API
|
|
105
|
-
|
|
106
|
-
```js
|
|
107
|
-
// Main
|
|
108
|
-
omega.theme.get(); // 'system' | 'light' | 'dark' (the chosen source)
|
|
109
|
-
omega.theme.resolved(); // 'light' | 'dark' (what's showing)
|
|
110
|
-
omega.theme.set('dark'); // apply + persist (throws on invalid values)
|
|
111
|
-
const unsub = omega.theme.onChange(({ source, resolved }) => { ... });
|
|
112
|
-
|
|
113
|
-
// Renderer (any page with the @omega.js/desktop preload)
|
|
114
|
-
await window.desktop.theme.get(); // { source, resolved }
|
|
115
|
-
await window.desktop.theme.set('dark'); // → { source, resolved }
|
|
116
|
-
const unsub = window.desktop.theme.onChange(({ resolved }) => { ... }); // matchMedia-powered
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
Main also broadcasts `desktop:theme:changed { source, resolved }` to BrowserWindows as a courtesy — but renderers should rely on `onChange`/matchMedia, which works in every context.
|
|
120
|
-
|
|
121
|
-
### Declarative controls
|
|
122
|
-
|
|
123
|
-
Any element with `data-omega-theme-set` becomes a theme switch (wired by the renderer's `omega.initialize()`, event-delegated, so late-rendered controls work):
|
|
124
|
-
|
|
125
|
-
```html
|
|
126
|
-
<button data-omega-theme-set="light">Day</button>
|
|
127
|
-
<button data-omega-theme-set="dark">Dusk</button>
|
|
128
|
-
<button data-omega-theme-set="system">Auto</button>
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
### Build-time stamp
|
|
132
|
-
|
|
133
|
-
`data-bs-theme="{{ theme.appearance }}"` is still stamped into every page at build. For `'light'`/`'dark'` the stamp is already correct; `'system'` stamps an inert value that the preload applier replaces with the resolved appearance at `DOMContentLoaded` (Bootstrap treats unknown values as light for the instant before that).
|
|
134
|
-
|
|
135
|
-
## Where the themes live
|
|
136
|
-
|
|
137
|
-
The SSOT is **`@omega.js/web/themes/`** — one theme tree for web, desktop, and extension (C4 cp109: the classy triplication is dead). @omega.js/desktop declares `omega.vendorAssets` in its package.json, and every `prepare-package` run copies the resolved web package's `themes/` into `<em>/dist/assets/themes/`. Consumers import via the sass `loadPaths` mechanism — **nothing is ever copied into the consumer's tree**. Desktop-specific theme bits (the `.omega-titlebar` component, the `$min-contrast-ratio` knob) were upstreamed INTO the shared classy rather than kept as a fork.
|
|
138
|
-
|
|
139
|
-
## Updating themes
|
|
140
|
-
|
|
141
|
-
A theme change lands once in `packages/web/themes/` and rides into desktop + extension on their next prepare. There is no sync step and no version skew — dist is rebuilt from the resolved web package every time. (A standalone `@omega.js/themes` package was considered and rejected for now: the vendor channel gives one-source semantics without another publishable surface.)
|
|
142
|
-
|
|
143
|
-
## Gotchas
|
|
144
|
-
|
|
145
|
-
### Sass `@import` deprecation warnings
|
|
146
|
-
Classy's `_theme.scss` uses `@import` (Sass's legacy module system) for its own internal layout. You'll see a deprecation warning during compile. UJM has the same warning. Functional today; will be migrated when classy upgrades to fully-modular `@use`/`@forward`.
|
|
147
|
-
|
|
148
|
-
### Per-page CSS bundles are 0 bytes by default
|
|
149
|
-
Empty `pages/<name>.scss` produces empty bundles. That's fine — the page template still loads them, the browser just gets a 200 with no rules. Adding any selector populates it.
|
package/docs/tooltips.md
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
# Bootstrap JS & Tooltips
|
|
2
|
-
|
|
3
|
-
@omega.js/desktop ships **Bootstrap's JavaScript** (v5.3, Popper inlined) as a prebuilt bundle
|
|
4
|
-
— `assets/js/bootstrap.bundle.js` — loaded by the renderer
|
|
5
|
-
bootstrap. Consumers add **zero setup** and never vendor Bootstrap JS
|
|
6
|
-
themselves.
|
|
7
|
-
|
|
8
|
-
## Tooltips (auto-initialized)
|
|
9
|
-
|
|
10
|
-
Bootstrap makes tooltips opt-in (they need a JS instance per element); @omega.js/desktop does
|
|
11
|
-
the opt-in for you. Any element carrying the standard Bootstrap markup gets a
|
|
12
|
-
live tooltip:
|
|
13
|
-
|
|
14
|
-
```html
|
|
15
|
-
<button class="btn btn-primary" data-bs-toggle="tooltip" data-bs-title="Saves and continues">
|
|
16
|
-
Save
|
|
17
|
-
</button>
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
The renderer bootstrap (`renderer.js _wireTooltips`) initializes every
|
|
21
|
-
`[data-bs-toggle="tooltip"]` present at init and watches the DOM:
|
|
22
|
-
|
|
23
|
-
- elements **inserted later** get their tooltip on arrival,
|
|
24
|
-
- **`data-bs-title` / `title` changes** update the live instance in place
|
|
25
|
-
(emptying the title disposes it — no tooltip is a valid state),
|
|
26
|
-
- **removed elements** have their instance disposed — no orphaned tips.
|
|
27
|
-
|
|
28
|
-
Plain-`title` hosts work: Bootstrap's constructor MOVES `title` into
|
|
29
|
-
`data-bs-original-title`, and the observer reads that bookkeeping as a live
|
|
30
|
-
title source. (It must — reading only `title`/`data-bs-title` made the
|
|
31
|
-
observer dispose the instance, dispose restored `title`, re-init removed it
|
|
32
|
-
again: an infinite MutationObserver microtask loop that froze the whole
|
|
33
|
-
renderer. Found by Somiibo's session-limits boot suite; regression-tested in
|
|
34
|
-
the tooltips suite.) One knock-on: a title-only host can't be disposed by
|
|
35
|
-
emptying its title — remove `data-bs-toggle` instead (prefer `data-bs-title`
|
|
36
|
-
for dynamic tooltips).
|
|
37
|
-
|
|
38
|
-
All the standard Bootstrap `data-bs-*` options work (`data-bs-placement`,
|
|
39
|
-
`data-bs-delay`, …).
|
|
40
|
-
|
|
41
|
-
### Disabled controls
|
|
42
|
-
|
|
43
|
-
Bootstrap's own caveat: disabled elements don't fire hover events. Wrap the
|
|
44
|
-
control and put the tooltip on the wrapper:
|
|
45
|
-
|
|
46
|
-
```html
|
|
47
|
-
<span data-bs-toggle="tooltip" data-bs-title="Requires the Pro plan">
|
|
48
|
-
<button class="btn btn-primary" disabled>Bulk import</button>
|
|
49
|
-
</span>
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## The rest of Bootstrap's JS
|
|
53
|
-
|
|
54
|
-
The full namespace is exposed at **`window.bootstrap`** (and
|
|
55
|
-
`omega.bootstrap`): `Tooltip`, `Popover`, `Collapse`, `Dropdown`, `Modal`,
|
|
56
|
-
`Offcanvas`, `Tab`, `Toast`, `Alert`, `Button`, `Carousel`, `ScrollSpy`. Only
|
|
57
|
-
tooltips are auto-initialized; the other components' standard **data-api**
|
|
58
|
-
works out of the box on plain Bootstrap markup (e.g.
|
|
59
|
-
`data-bs-toggle="collapse"`), and everything is available for manual control:
|
|
60
|
-
|
|
61
|
-
```js
|
|
62
|
-
const collapse = window.bootstrap.Collapse.getOrCreateInstance(el);
|
|
63
|
-
collapse.show();
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Rebuilding the bundle
|
|
67
|
-
|
|
68
|
-
`assets/js/bootstrap.bundle.js` is a COMMITTED prebuilt artifact — no gulp task
|
|
69
|
-
rebuilds it, so a normal build never regenerates it. The checked-in bytes are a
|
|
70
|
-
legacy webpack UMD build, from before [#737](https://github.com/Omega-JS-Stack/omega/issues/737)
|
|
71
|
-
took webpack out of desktop.
|
|
72
|
-
|
|
73
|
-
Rebuild only when the vendored Bootstrap source is upgraded, with esbuild — the
|
|
74
|
-
one bundler desktop still has. The input is @omega.js/desktop's vendored
|
|
75
|
-
Bootstrap 5.3 source (the vendored themes tree) plus `@popperjs/core` (an
|
|
76
|
-
@omega.js/desktop dependency), and the output has to keep the contract its two
|
|
77
|
-
consumers rely on: `require()` hands back the Bootstrap namespace
|
|
78
|
-
(`renderer.js` reads `.Tooltip` off it and assigns `window.bootstrap` itself),
|
|
79
|
-
so the format is CommonJS:
|
|
80
|
-
|
|
81
|
-
```bash
|
|
82
|
-
esbuild bootstrap.js --bundle --minify --format=cjs \
|
|
83
|
-
--outfile=src/assets/js/bootstrap.bundle.js
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
Use `--format=iife --global-name=bootstrap` only if the bundle is ever loaded by
|
|
87
|
-
a plain `<script>` tag instead — nothing does that today.
|
|
88
|
-
|
|
89
|
-
Note: the bundle reads `document.documentElement` at import time — the renderer
|
|
90
|
-
bootstrap defers loading it until the document exists (relevant when wiring
|
|
91
|
-
runs from a preload, e.g. the test harness).
|
|
92
|
-
|
|
93
|
-
## Testing
|
|
94
|
-
|
|
95
|
-
- `src/test/suites/renderer/tooltips.test.js` — bundle loads, auto-init on
|
|
96
|
-
insertion, live retitle, dispose-on-removal, tip cleanup. (The harness wires
|
|
97
|
-
the renderer instance in the preload world: see the suite header for the
|
|
98
|
-
world-split notes; single-world hover behavior is covered by consumer boot
|
|
99
|
-
suites.)
|
package/docs/tray.md
DELETED
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
# Tray
|
|
2
|
-
|
|
3
|
-
File-based tray/menubar. @omega.js/desktop looks for `src/integrations/tray/index.js`; if it exists, the exported function is called during boot with a builder API + id-path API. If absent, @omega.js/desktop ships a default tray template (see ids below).
|
|
4
|
-
|
|
5
|
-
## Config
|
|
6
|
-
|
|
7
|
-
No config block. Path is conventional: `src/integrations/tray/index.js`. To opt out, call `omega.tray.disable()` from your main entry: idempotent, tears down any existing Tray.
|
|
8
|
-
|
|
9
|
-
## Definition file
|
|
10
|
-
|
|
11
|
-
```js
|
|
12
|
-
// src/integrations/tray/index.js
|
|
13
|
-
module.exports = ({ omega, tray }) => {
|
|
14
|
-
// @omega.js/desktop auto-resolves the tray icon from config/icons/<platform>/tray.png at build
|
|
15
|
-
// time, so explicit tray.icon() is OPTIONAL. Call it only to override.
|
|
16
|
-
// Note: on macOS, if you pass your own path, the filename MUST end in
|
|
17
|
-
// `Template.png` for the OS to auto-invert it in dark mode.
|
|
18
|
-
// tray.icon('src/assets/icons/my-trayTemplate.png');
|
|
19
|
-
tray.tooltip(omega.config?.app?.productName);
|
|
20
|
-
|
|
21
|
-
// Easiest: start from @omega.js/desktop's default template.
|
|
22
|
-
tray.useDefaults();
|
|
23
|
-
|
|
24
|
-
// Then customize by id (flat — no `tray/` prefix needed):
|
|
25
|
-
tray.insertAfter('open', {
|
|
26
|
-
id: 'dashboard',
|
|
27
|
-
label: 'Open Dashboard',
|
|
28
|
-
click: () => omega.windows.show('dashboard'),
|
|
29
|
-
});
|
|
30
|
-
tray.update('open', { label: 'Show Window' });
|
|
31
|
-
tray.remove('website');
|
|
32
|
-
tray.hide('check-for-updates');
|
|
33
|
-
};
|
|
34
|
-
```
|
|
35
|
-
|
|
36
|
-
## Builder API (during definition)
|
|
37
|
-
|
|
38
|
-
```js
|
|
39
|
-
tray.icon(path) // sets the tray icon (relative paths resolved from cwd)
|
|
40
|
-
tray.tooltip(text)
|
|
41
|
-
tray.item(descriptor) // see "Item descriptors" below
|
|
42
|
-
tray.separator()
|
|
43
|
-
tray.submenu(label, items)
|
|
44
|
-
tray.useDefaults() // populate with @omega.js/desktop's default template (id-tagged)
|
|
45
|
-
tray.clear() // start over
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
## Id-path API
|
|
49
|
-
|
|
50
|
-
Same shape across menu / tray / context-menu. Available **during definition** (on the `tray` builder arg) AND **at runtime** on `omega.tray`:
|
|
51
|
-
|
|
52
|
-
```js
|
|
53
|
-
.find(idPath) // live descriptor or null
|
|
54
|
-
.has(idPath) // bool
|
|
55
|
-
.update(idPath, patch) // Object.assign + re-render. returns true if found.
|
|
56
|
-
.remove(idPath) // splice + re-render. returns true if removed.
|
|
57
|
-
.enable(idPath, bool = true) // sugar over update({enabled})
|
|
58
|
-
.show(idPath, bool = true) // sugar over update({visible})
|
|
59
|
-
.hide(idPath) // visible:false
|
|
60
|
-
.insertBefore(idPath, item) // splice in a sibling
|
|
61
|
-
.insertAfter(idPath, item) // splice in a sibling
|
|
62
|
-
.appendTo(idPath, item) // push into a submenu (creates submenu if absent)
|
|
63
|
-
```
|
|
64
|
-
|
|
65
|
-
Tray ids are **flat** — no `tray/` prefix (the lib namespace is implicit). For nested submenus you can address children by `parent/child` paths (the resolver walks `submenu` arrays).
|
|
66
|
-
|
|
67
|
-
## Default template ids
|
|
68
|
-
|
|
69
|
-
| ID | Item |
|
|
70
|
-
|---|---|
|
|
71
|
-
| `title` | Disabled label showing the app name |
|
|
72
|
-
| `open` | "Open `<app>`": calls `omega.windows.show('main')` |
|
|
73
|
-
| `check-for-updates` | Wired to `omega.autoUpdater` (label updates dynamically) |
|
|
74
|
-
| `website` | Visit `brand.url` (only present if configured) |
|
|
75
|
-
| `quit` | Quit the app |
|
|
76
|
-
|
|
77
|
-
## Submenus
|
|
78
|
-
|
|
79
|
-
Submenus work the same as Electron's. The id-path resolver walks `submenu` arrays so children are addressable as `parent/child`:
|
|
80
|
-
|
|
81
|
-
```js
|
|
82
|
-
tray.item({ id: 'account', label: 'Account', submenu: [
|
|
83
|
-
{ id: 'sign-in', label: 'Sign in', click: () => {} },
|
|
84
|
-
{ id: 'sign-out', label: 'Sign out', click: () => {} },
|
|
85
|
-
]});
|
|
86
|
-
|
|
87
|
-
omega.tray.find('account/sign-out');
|
|
88
|
-
omega.tray.update('account/sign-out', { enabled: false });
|
|
89
|
-
omega.tray.appendTo('account', { id: 'profile', label: 'Profile' });
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
## Item descriptors
|
|
93
|
-
|
|
94
|
-
Mirror Electron's [`MenuItemConstructorOptions`](https://www.electronjs.org/docs/latest/api/menu#menubuildfromtemplatetemplate), with these additions:
|
|
95
|
-
|
|
96
|
-
| Field | Type | Notes |
|
|
97
|
-
|---|---|---|
|
|
98
|
-
| `id` | string | Used for id-path lookups (`open`, `quit`, `account/sign-out`, …) |
|
|
99
|
-
| `label` | string \| `() => string` | Function form re-evaluated on every `refresh()` |
|
|
100
|
-
| `enabled` | boolean \| `() => boolean` | Same |
|
|
101
|
-
| `visible` | boolean \| `() => boolean` | Same |
|
|
102
|
-
| `checked` | boolean \| `() => boolean` | Same |
|
|
103
|
-
| `click` | function | Wrapped to swallow errors so a bad handler can't kill the menu |
|
|
104
|
-
| `submenu` | array | Recursively resolved with the same conveniences |
|
|
105
|
-
|
|
106
|
-
## Runtime API on `omega.tray`
|
|
107
|
-
|
|
108
|
-
```js
|
|
109
|
-
omega.tray.refresh() // re-evaluate dynamic state and re-render
|
|
110
|
-
omega.tray.define(fn) // replace the whole definition at runtime
|
|
111
|
-
omega.tray.disable() // tear down + stop responding (idempotent)
|
|
112
|
-
omega.tray.setIcon(path)
|
|
113
|
-
omega.tray.setTooltip(text)
|
|
114
|
-
omega.tray.addItem(descriptor) // append (preserves existing items)
|
|
115
|
-
omega.tray.clearItems()
|
|
116
|
-
omega.tray.destroy() // tear down (mostly for tests)
|
|
117
|
-
|
|
118
|
-
// Id-path API — same as listed above.
|
|
119
|
-
omega.tray.find('quit')
|
|
120
|
-
omega.tray.update('quit', { label: 'Goodbye' })
|
|
121
|
-
omega.tray.remove('website')
|
|
122
|
-
omega.tray.insertAfter('open', { id: 'preferences', label: 'Preferences...', click: ... })
|
|
123
|
-
omega.tray.hide('check-for-updates')
|
|
124
|
-
|
|
125
|
-
// Inspection
|
|
126
|
-
omega.tray.getItems() // shallow copy of raw descriptors
|
|
127
|
-
omega.tray.getIcon()
|
|
128
|
-
omega.tray.getTooltip()
|
|
129
|
-
omega.tray.isRendered()
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Common patterns
|
|
133
|
-
|
|
134
|
-
### Update label after auth state changes
|
|
135
|
-
|
|
136
|
-
```js
|
|
137
|
-
// in your renderer/main code, after sign-in:
|
|
138
|
-
omega.storage.set('user', { ... });
|
|
139
|
-
omega.tray.refresh(); // dynamic-label functions re-evaluate
|
|
140
|
-
```
|
|
141
|
-
|
|
142
|
-
### Hide updater item if you ship without auto-update
|
|
143
|
-
|
|
144
|
-
```js
|
|
145
|
-
// src/integrations/tray/index.js
|
|
146
|
-
module.exports = ({ tray }) => {
|
|
147
|
-
tray.icon('...');
|
|
148
|
-
tray.useDefaults();
|
|
149
|
-
tray.remove('check-for-updates');
|
|
150
|
-
};
|
|
151
|
-
```
|
|
152
|
-
|
|
153
|
-
### Replace the entire tray at runtime
|
|
154
|
-
|
|
155
|
-
```js
|
|
156
|
-
omega.tray.define(({ omega, tray }) => {
|
|
157
|
-
tray.icon('icons/dark-mode.png');
|
|
158
|
-
tray.item({ id: 'x', label: 'New layout', click: ... });
|
|
159
|
-
});
|
|
160
|
-
```
|
|
161
|
-
|
|
162
|
-
## Default scaffold
|
|
163
|
-
|
|
164
|
-
The scaffold every verb runs ships `src/integrations/tray/index.js` calling `tray.useDefaults()` so you start with the same items the framework would supply on its own — plus commented-out examples covering insertAfter, update, remove, hide, enable, and submenus.
|
package/docs/usage.md
DELETED
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Usage
|
|
2
|
-
|
|
3
|
-
Tracks app-launch + hours-of-use stats. Sister of legacy @omega.js/desktop's Usage library, but uses `omega.storage` instead of a separate electron-store.
|
|
4
|
-
|
|
5
|
-
## What's tracked
|
|
6
|
-
|
|
7
|
-
```js
|
|
8
|
-
omega.usage.opens() // total app launches
|
|
9
|
-
omega.usage.hoursTotal() // cumulative hours-of-use across clean exits
|
|
10
|
-
omega.usage.hoursThisSession() // live, computed from session start
|
|
11
|
-
omega.usage.installedAt() // ISO timestamp of first launch
|
|
12
|
-
omega.usage.toJSON() // all of the above as a structured-cloneable object
|
|
13
|
-
```
|
|
14
|
-
|
|
15
|
-
## How it accumulates
|
|
16
|
-
|
|
17
|
-
Persisted shape (`storage.usage`):
|
|
18
|
-
|
|
19
|
-
```js
|
|
20
|
-
{
|
|
21
|
-
opens: 12,
|
|
22
|
-
hoursTotal: 4.75,
|
|
23
|
-
installedAt: '2025-12-01T...',
|
|
24
|
-
lastLaunchAt: '...',
|
|
25
|
-
lastQuitAt: '...' | null,
|
|
26
|
-
}
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
On boot:
|
|
30
|
-
|
|
31
|
-
1. Read previous snapshot.
|
|
32
|
-
2. If `lastQuitAt` is set, accumulate `(lastQuitAt - lastLaunchAt)` into `hoursTotal`. This is the "previous session ended cleanly" case.
|
|
33
|
-
3. If `lastQuitAt` is null, the previous session crashed — we don't credit any hours. We don't know how long it ran.
|
|
34
|
-
4. `opens += 1`, `lastLaunchAt = now`, `lastQuitAt = null`.
|
|
35
|
-
|
|
36
|
-
On quit (via `app.on('before-quit')`):
|
|
37
|
-
|
|
38
|
-
5. `lastQuitAt = now` written to storage.
|
|
39
|
-
6. Next launch's step 2 picks up the duration.
|
|
40
|
-
|
|
41
|
-
So `hoursTotal` is intentionally a lower bound — it never over-counts crashed sessions.
|
|
42
|
-
|
|
43
|
-
`hoursThisSession()` is computed live from `(Date.now() - sessionStart) / 3600000`. Never stale.
|
|
44
|
-
|
|
45
|
-
## Renderer
|
|
46
|
-
|
|
47
|
-
```js
|
|
48
|
-
const snap = await window.desktop.usage.get();
|
|
49
|
-
// { opens: 12, hoursTotal: 4.75, hoursThisSession: 0.05, installedAt: '...' }
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Why not just use app-state?
|
|
53
|
-
|
|
54
|
-
`app-state.js` already tracks `launchCount` (= opens). We could fold these in. But `app-state` is concerned with first-launch / crash-sentinel / version-change semantics: `usage` is concerned with telemetry. Keeping them separate keeps each module focused. Both write to disjoint keys in `omega.storage`.
|
|
55
|
-
|
|
56
|
-
## Tests
|
|
57
|
-
|
|
58
|
-
- `src/test/suites/main/usage.test.js` — opens-bumps-on-reinit, hoursTotal accumulation from clean prior session, no-credit for crashed sessions, installedAt persistence, IPC handler.
|
package/docs/verts.md
DELETED
|
@@ -1,62 +0,0 @@
|
|
|
1
|
-
# Verts — the `data-omega-vert` auto-bind
|
|
2
|
-
|
|
3
|
-
@omega.js/desktop renderers auto-bind the OMEGA verts (ads) system (monorepo
|
|
4
|
-
`docs/web/ads-system.md`, phase 4): drop a `[data-omega-vert]` element into any
|
|
5
|
-
view and the renderer bootstrap hands it to `@omega.js/client`'s verts module —
|
|
6
|
-
zero consumer JS, same element vocabulary as the web `verts/unit` section and
|
|
7
|
-
@omega.js/extension.
|
|
8
|
-
|
|
9
|
-
```html
|
|
10
|
-
<div data-omega-vert data-omega-vert-size="banner"></div>
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
## What the wiring does
|
|
14
|
-
|
|
15
|
-
`renderer.js _wireAds` (runs inside `omega.initialize()`, same liveness
|
|
16
|
-
model as the FontAwesome/tooltip wiring) binds every `[data-omega-vert]`
|
|
17
|
-
element present at init AND inserted later (MutationObserver), marking bound
|
|
18
|
-
hosts `data-omega-vert-bound="house"`. Everything after the bind lives in the
|
|
19
|
-
client module (`@omega.js/client/modules/verts.js`): lazy arming near the
|
|
20
|
-
viewport, a sandboxed iframe to the resolved in-house source's
|
|
21
|
-
`/omega/verts/serve`, origin-validated postMessage, host-owned rotation +
|
|
22
|
-
staleness recovery, and no-fill collapse (the host hides itself).
|
|
23
|
-
|
|
24
|
-
## House/company lane ONLY — no AdSense
|
|
25
|
-
|
|
26
|
-
Desktop surfaces never run the AdSense provider lane (policy: no web
|
|
27
|
-
context). The wiring pins `type: 'house'` on every mount — the pin wins over
|
|
28
|
-
the element's `data-omega-vert` type, so even a shared omega.json5 that carries
|
|
29
|
-
`advertising.providers.adsense` (the web target uses it) can only
|
|
30
|
-
ever reach the house/company inventory here. Pinned by the renderer verts
|
|
31
|
-
suite: an AdSense-configured harness must never see an `adsbygoogle` script
|
|
32
|
-
or `<ins>`.
|
|
33
|
-
|
|
34
|
-
## Config
|
|
35
|
-
|
|
36
|
-
The shared `advertising` section of `config/omega.json5` flows into the
|
|
37
|
-
renderer via `OMEGA_BUILD_JSON` like every other section:
|
|
38
|
-
|
|
39
|
-
```json5
|
|
40
|
-
advertising: {
|
|
41
|
-
providers: {
|
|
42
|
-
inhouse: { source: 'company' }, // 'self' | 'company' | full URL
|
|
43
|
-
},
|
|
44
|
-
tags: ['music', 'audio-tools'], // contextual targeting inputs
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
No `advertising` key (or no resolvable inhouse source) → bound units collapse
|
|
49
|
-
quietly. Nothing else to configure.
|
|
50
|
-
|
|
51
|
-
## Element vocabulary
|
|
52
|
-
|
|
53
|
-
| Attribute | Meaning |
|
|
54
|
-
|---|---|
|
|
55
|
-
| `data-omega-vert` | binds the element (type value is ignored on desktop — house pin) |
|
|
56
|
-
| `data-omega-vert-size` | size preset (`banner`/`leaderboard`/`rectangle`/…) or raw px max-height |
|
|
57
|
-
| `data-omega-vert-id` | pin a specific vert |
|
|
58
|
-
| `data-omega-vert-tags` | comma-separated contextual tags for this unit |
|
|
59
|
-
| `data-omega-vert-bound` | set by the wiring (`"house"`) once bound — observability/debugging |
|
|
60
|
-
|
|
61
|
-
Units emit `omega-vert:fill` / `omega-vert:no-fill` / `omega-vert:click` /
|
|
62
|
-
`omega-vert:reload` CustomEvents on the host (bubbling) for app-side hooks.
|