@omega.js/desktop 0.52.0 → 0.53.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.
Files changed (273) hide show
  1. package/README.md +17 -12
  2. package/dist/assets/css/core/_initialize.scss +1 -1
  3. package/dist/assets/js/core/app-shell.js +14 -15
  4. package/dist/assets/themes/_template/_theme.js +6 -6
  5. package/dist/assets/themes/base/_includes/global/sections/account.html +4 -4
  6. package/dist/assets/themes/base/_includes/global/sections/app-sidebar.html +5 -5
  7. package/dist/assets/themes/base/_layouts/frontend/pages/account/index.html +3 -3
  8. package/dist/assets/themes/base/_layouts/frontend/pages/alternatives/index.html +1 -1
  9. package/dist/assets/themes/base/_layouts/frontend/pages/blog/tags/tag.html +1 -1
  10. package/dist/assets/themes/base/_layouts/frontend/pages/payment/confirmation.html +1 -1
  11. package/dist/assets/themes/base/_sections/marketing/newsletter-cta/section.js +2 -3
  12. package/dist/assets/themes/base/_sections/verts/unit/section.html +1 -1
  13. package/dist/assets/themes/base/_sections/verts/unit/section.js +3 -4
  14. package/dist/assets/themes/base/_theme.js +4 -3
  15. package/dist/assets/themes/bootstrap/_theme.js +2 -2
  16. package/dist/assets/themes/bootstrap/overrides/_links.scss +1 -1
  17. package/dist/assets/themes/classy/_theme.js +8 -6
  18. package/dist/assets/themes/classy/css/marketing/_sections.scss +1 -2
  19. package/dist/assets/themes/classy/js/hero-demo-form.js +3 -2
  20. package/dist/assets/themes/neobrutalism/_theme.js +5 -5
  21. package/dist/assets/themes/neobrutalism/js/pages/test/libraries/layers/index.js +1 -1
  22. package/dist/assets/themes/newsflash/_theme.js +6 -6
  23. package/dist/assets/themes/newsflash/js/pages/test/libraries/layers/index.js +1 -1
  24. package/dist/build.js +87 -111
  25. package/dist/cli.js +1 -1
  26. package/dist/commands/build.js +2 -2
  27. package/dist/commands/cdp/capture.js +2 -2
  28. package/dist/commands/cdp/quit.js +2 -2
  29. package/dist/commands/cdp/relaunch.js +2 -2
  30. package/dist/commands/cdp/theme.js +1 -1
  31. package/dist/commands/clean.js +2 -2
  32. package/dist/commands/deploy.js +4 -4
  33. package/dist/commands/finalize-release.js +4 -4
  34. package/dist/commands/install.js +3 -3
  35. package/dist/commands/launch.js +2 -2
  36. package/dist/commands/lib/deploy-precheck.js +3 -3
  37. package/dist/commands/lib/ensure-target.js +6 -6
  38. package/dist/commands/package.js +2 -2
  39. package/dist/commands/publish.js +2 -2
  40. package/dist/commands/release.js +3 -3
  41. package/dist/commands/runner.js +11 -11
  42. package/dist/commands/sign-windows.js +5 -5
  43. package/dist/commands/test.js +4 -4
  44. package/dist/commands/update.js +2 -2
  45. package/dist/commands/validate-certs.js +4 -4
  46. package/dist/commands/version.js +3 -3
  47. package/dist/defaults/AGENTS.md +17 -8
  48. package/dist/defaults/config/omega.json5 +7 -7
  49. package/dist/defaults/hooks/build/post.js +1 -1
  50. package/dist/defaults/hooks/build/pre.js +1 -1
  51. package/dist/defaults/hooks/deploy/pre.js +1 -1
  52. package/dist/defaults/hooks/release/post.js +1 -1
  53. package/dist/defaults/hooks/release/pre.js +1 -1
  54. package/dist/defaults/src/assets/js/components/about/index.js +3 -5
  55. package/dist/defaults/src/assets/js/components/main/index.js +3 -5
  56. package/dist/defaults/src/assets/js/components/settings/index.js +3 -5
  57. package/dist/defaults/src/integrations/context-menu/index.js +2 -2
  58. package/dist/defaults/src/integrations/menu/index.js +3 -3
  59. package/dist/defaults/src/integrations/tray/index.js +3 -3
  60. package/dist/defaults/src/main.js +3 -5
  61. package/dist/defaults/src/preload.js +3 -5
  62. package/dist/defaults/test/README.md +2 -2
  63. package/dist/gulp/main.js +9 -10
  64. package/dist/gulp/tasks/audit.js +7 -7
  65. package/dist/gulp/tasks/build-config.js +8 -8
  66. package/dist/gulp/tasks/bundle.js +16 -16
  67. package/dist/gulp/tasks/defaults.js +3 -3
  68. package/dist/gulp/tasks/distribute.js +2 -2
  69. package/dist/gulp/tasks/html.js +9 -9
  70. package/dist/gulp/tasks/package-quick.js +3 -3
  71. package/dist/gulp/tasks/package.js +3 -3
  72. package/dist/gulp/tasks/release.js +3 -3
  73. package/dist/gulp/tasks/sass.js +6 -6
  74. package/dist/gulp/tasks/serve.js +4 -4
  75. package/dist/hooks/notarize-artifacts.js +1 -1
  76. package/dist/hooks/notarize.js +1 -1
  77. package/dist/index.js +5 -8
  78. package/dist/lib/_environment-mixin.js +50 -0
  79. package/dist/lib/_lifecycle-mixin.js +45 -0
  80. package/dist/lib/analytics.js +33 -35
  81. package/dist/lib/app-state.js +14 -14
  82. package/dist/lib/auth-flow.js +18 -18
  83. package/dist/lib/auth-persistence.js +12 -12
  84. package/dist/lib/auth.js +421 -0
  85. package/dist/lib/auto-updater.js +49 -49
  86. package/dist/lib/context-menu.js +13 -13
  87. package/dist/lib/context.js +19 -19
  88. package/dist/lib/deep-link.js +34 -34
  89. package/dist/lib/fontawesome.js +5 -5
  90. package/dist/lib/ipc.js +4 -4
  91. package/dist/lib/menu.js +25 -25
  92. package/dist/lib/protocol.js +5 -5
  93. package/dist/lib/remote-config.js +22 -22
  94. package/dist/lib/remote-scripts.js +21 -21
  95. package/dist/lib/restart-manager/index.js +28 -28
  96. package/dist/lib/sign-helpers/exec-with-limit.js +1 -1
  97. package/dist/lib/sign-helpers/sign-events.js +1 -1
  98. package/dist/lib/startup.js +18 -13
  99. package/dist/lib/storage.js +10 -10
  100. package/dist/lib/templating.js +16 -16
  101. package/dist/lib/theme.js +10 -10
  102. package/dist/lib/tray.js +27 -27
  103. package/dist/lib/usage.js +11 -11
  104. package/dist/lib/window-manager.js +26 -26
  105. package/dist/main.js +398 -483
  106. package/dist/preload.js +236 -176
  107. package/dist/renderer.js +417 -391
  108. package/dist/test/fixtures/consumer-app/config/omega.json5 +1 -1
  109. package/dist/test/fixtures/consumer-app/src/assets/js/components/main/index.js +8 -11
  110. package/dist/test/fixtures/consumer-app/src/main.js +5 -7
  111. package/dist/test/fixtures/consumer-app/src/preload.js +2 -2
  112. package/dist/test/harness/boot-entry.js +22 -20
  113. package/dist/test/harness/main-entry.js +31 -30
  114. package/dist/test/harness/renderer-entry.js +5 -5
  115. package/dist/test/harness/renderer-preload.js +137 -141
  116. package/dist/test/index.js +10 -10
  117. package/dist/test/runner.js +2 -2
  118. package/dist/test/runners/boot.js +7 -6
  119. package/dist/test/runners/electron.js +3 -2
  120. package/dist/test/runners/render-event.js +2 -2
  121. package/dist/test/suites/boot/consumer-app-boots.test.js +57 -26
  122. package/dist/test/suites/boot/restart-manager.test.js +2 -2
  123. package/dist/test/suites/boot/storage-bundled.test.js +5 -5
  124. package/dist/test/suites/boot/theme.test.js +13 -13
  125. package/dist/test/suites/build/audit.test.js +1 -1
  126. package/dist/test/suites/build/auth-persistence-resolve.test.js +6 -6
  127. package/dist/test/suites/build/boot-fixture.test.js +2 -2
  128. package/dist/test/suites/build/boot-runner-timeout.test.js +6 -5
  129. package/dist/test/suites/build/brand-scss.test.js +1 -1
  130. package/dist/test/suites/build/build-json-bake.test.js +1 -1
  131. package/dist/test/suites/build/cli.test.js +2 -2
  132. package/dist/test/suites/build/config-schema.test.js +5 -5
  133. package/dist/test/suites/build/defaults-scaffold.test.js +2 -2
  134. package/dist/test/suites/build/deploy-hook.test.js +3 -3
  135. package/dist/test/suites/build/ensure-target.test.js +2 -2
  136. package/dist/test/suites/build/env-delivery.test.js +2 -2
  137. package/dist/test/suites/build/esm-only-dependency.test.js +2 -2
  138. package/dist/test/suites/build/exports.test.js +9 -8
  139. package/dist/test/suites/build/get-config.test.js +4 -4
  140. package/dist/test/suites/build/manifest-deps.test.js +1 -1
  141. package/dist/test/suites/build/merge-line-files.test.js +1 -1
  142. package/dist/test/suites/build/omega-shell.test.js +34 -2
  143. package/dist/test/suites/build/omega.test.js +350 -0
  144. package/dist/test/suites/build/renderer-auth-bridge.test.js +211 -78
  145. package/dist/test/suites/build/runner.test.js +2 -2
  146. package/dist/test/suites/build/sentry.test.js +2 -2
  147. package/dist/test/suites/build/sign-windows-e2e.test.js +2 -2
  148. package/dist/test/suites/build/templating.test.js +3 -3
  149. package/dist/test/suites/build/test-stealth.test.js +7 -9
  150. package/dist/test/suites/build/url-helpers.test.js +55 -56
  151. package/dist/test/suites/build/validate-config.test.js +2 -2
  152. package/dist/test/suites/build/wave5-pins.test.js +2 -2
  153. package/dist/test/suites/main/analytics.test.js +59 -59
  154. package/dist/test/suites/main/app-state.test.js +66 -66
  155. package/dist/test/suites/main/auth-flow.test.js +41 -41
  156. package/dist/test/suites/main/auth-persistence.test.js +54 -43
  157. package/dist/test/suites/main/{client-bridge.integration.test.js → auth.integration.test.js} +10 -9
  158. package/dist/test/suites/main/auth.test.js +336 -0
  159. package/dist/test/suites/main/auto-updater.test.js +134 -134
  160. package/dist/test/suites/main/boot-sequence.test.js +37 -49
  161. package/dist/test/suites/main/context-menu.test.js +51 -50
  162. package/dist/test/suites/main/context.test.js +25 -25
  163. package/dist/test/suites/main/deep-link.test.js +74 -74
  164. package/dist/test/suites/main/fontawesome.test.js +27 -27
  165. package/dist/test/suites/main/ipc.test.js +35 -35
  166. package/dist/test/suites/main/menu.test.js +101 -100
  167. package/dist/test/suites/main/protocol.test.js +19 -19
  168. package/dist/test/suites/main/remote-config.test.js +63 -63
  169. package/dist/test/suites/main/remote-scripts.test.js +103 -103
  170. package/dist/test/suites/main/request.test.js +71 -0
  171. package/dist/test/suites/main/restart-manager.test.js +33 -33
  172. package/dist/test/suites/main/startup-paths-and-ua.test.js +4 -4
  173. package/dist/test/suites/main/startup.test.js +26 -26
  174. package/dist/test/suites/main/stealth-window.test.js +1 -1
  175. package/dist/test/suites/main/storage.test.js +25 -25
  176. package/dist/test/suites/main/theme.test.js +34 -34
  177. package/dist/test/suites/main/tray.test.js +79 -79
  178. package/dist/test/suites/main/url-helpers.test.js +133 -133
  179. package/dist/test/suites/main/usage.test.js +25 -25
  180. package/dist/test/suites/main/window-bounds.test.js +27 -27
  181. package/dist/test/suites/main/window-manager.test.js +44 -44
  182. package/dist/test/suites/renderer/analytics-bridge.test.js +5 -5
  183. package/dist/test/suites/renderer/cross-context-helpers.test.js +37 -31
  184. package/dist/test/suites/renderer/round-trip.test.js +3 -3
  185. package/dist/test/suites/renderer/tooltips.test.js +15 -15
  186. package/dist/test/suites/renderer/{window-em-surface.test.js → window-desktop-surface.test.js} +27 -7
  187. package/dist/test/utils/extended-mode-warning.js +1 -1
  188. package/dist/utils/boot-harness.js +56 -0
  189. package/dist/utils/mode-helpers.js +2 -15
  190. package/dist/utils/ship-keys.js +3 -3
  191. package/dist/utils/signing-status.js +51 -0
  192. package/dist/utils/test-events.js +7 -0
  193. package/dist/utils/test-stealth.js +6 -6
  194. package/dist/utils/url-helpers.js +52 -42
  195. package/dist/utils/user-agent.js +44 -0
  196. package/dist/vendor/account/engine.js +3 -3
  197. package/dist/vendor/account/index.js +14 -45
  198. package/dist/vendor/account/resolve-account.js +44 -0
  199. package/dist/vendor/account/schema.js +1 -1
  200. package/dist/vendor/account/user.js +99 -0
  201. package/dist/vendor/config/client-config.js +1 -1
  202. package/dist/vendor/config/environment.js +11 -30
  203. package/dist/vendor/config/index.js +8 -11
  204. package/dist/vendor/config/load.js +1 -2
  205. package/dist/vendor/config/platforms.js +1 -1
  206. package/dist/vendor/config/retired-keys.js +2 -2
  207. package/dist/vendor/config/schema.js +5 -8
  208. package/dist/vendor/config/site-global.js +2 -3
  209. package/dist/vendor/config/validate.js +1 -2
  210. package/dist/vendor/config/winback.js +1 -1
  211. package/dist/vendor/devkit/actions-secrets.js +1 -1
  212. package/dist/vendor/devkit/attach-log-file.js +1 -1
  213. package/dist/vendor/devkit/build-json.js +1 -1
  214. package/dist/vendor/devkit/cli-router.js +3 -4
  215. package/dist/vendor/devkit/defaults-engine.js +9 -11
  216. package/dist/vendor/devkit/local.js +2 -0
  217. package/dist/vendor/devkit/merge-line-files.js +2 -3
  218. package/dist/vendor/devkit/test/runner-core.js +6 -6
  219. package/dist/vendor/monitoring/env.js +2 -2
  220. package/dist/vendor/monitoring/index.js +1 -1
  221. package/dist/vendor/monitoring/main.js +1 -1
  222. package/dist/vendor/monitoring/preload.js +1 -1
  223. package/dist/vendor/monitoring/renderer.js +1 -1
  224. package/docs/analytics.md +8 -8
  225. package/docs/app-state.md +19 -19
  226. package/docs/audit.md +4 -4
  227. package/docs/{client-bridge.md → auth.md} +88 -73
  228. package/docs/auto-updater.md +8 -8
  229. package/docs/boot-sequence.md +11 -6
  230. package/docs/build-system.md +1 -1
  231. package/docs/cdp-debugging.md +1 -1
  232. package/docs/common-mistakes.md +7 -7
  233. package/docs/config-schema.md +1 -1
  234. package/docs/context-menu.md +13 -13
  235. package/docs/context.md +11 -11
  236. package/docs/css.md +3 -9
  237. package/docs/deep-link.md +25 -25
  238. package/docs/environment-detection.md +16 -16
  239. package/docs/fontawesome.md +7 -5
  240. package/docs/hooks.md +8 -8
  241. package/docs/index.md +38 -27
  242. package/docs/ipc.md +10 -10
  243. package/docs/lib-modules.md +9 -9
  244. package/docs/logging.md +12 -14
  245. package/docs/menu.md +18 -18
  246. package/docs/remote-config.md +9 -9
  247. package/docs/remote-scripts.md +12 -12
  248. package/docs/restart-manager.md +8 -8
  249. package/docs/sentry.md +4 -4
  250. package/docs/shared/analytics.md +1 -1
  251. package/docs/shared/breaking-changes.md +79 -13
  252. package/docs/shared/config.md +17 -21
  253. package/docs/shared/logging.md +1 -1
  254. package/docs/shared/monitoring.md +5 -5
  255. package/docs/shared/testing.md +2 -2
  256. package/docs/shared/theming.md +1 -1
  257. package/docs/shared/translation.md +19 -10
  258. package/docs/startup.md +16 -16
  259. package/docs/storage.md +11 -11
  260. package/docs/templating.md +3 -3
  261. package/docs/test-boot-layer.md +12 -12
  262. package/docs/test-framework.md +17 -17
  263. package/docs/themes.md +7 -7
  264. package/docs/tooltips.md +2 -2
  265. package/docs/tray.md +31 -31
  266. package/docs/usage.md +7 -7
  267. package/docs/verts.md +1 -1
  268. package/docs/windows.md +22 -22
  269. package/package.json +3 -4
  270. package/dist/lib/client-bridge.js +0 -374
  271. package/dist/lib/logger.js +0 -4
  272. package/dist/test/suites/build/manager.test.js +0 -213
  273. package/dist/test/suites/main/client-bridge.test.js +0 -262
package/README.md CHANGED
@@ -5,25 +5,25 @@
5
5
  </p>
6
6
 
7
7
  <p align="center">
8
- <strong>OMEGA Desktop</strong> — all-in-one development framework for Electron apps. Sister project to
8
+ <strong>OMEGA Desktop</strong>: all-in-one development framework for Electron apps. Sister project to
9
9
  <a href="../extension/">@omega.js/extension</a> and
10
- <a href="https://github.com/itw-creative-works/ultimate-jekyll-manager">Ultimate Jekyll Manager</a>.
10
+ <a href="../web/">@omega.js/web</a>.
11
11
  </p>
12
12
 
13
13
  ## What it does
14
14
 
15
- - **One-line bootstrap** per Electron process: `require('@omega.js/desktop/main')`, `/preload`, `/renderer`.
15
+ - **One ready-made `omega` per Electron process**: `const omega = require('@omega.js/desktop/main'); omega.initialize()`, and the same for `/preload` and `/renderer`. Main carries every lib as a property (`omega.windows`, `omega.tray`, `omega.auth`, ...); the renderer extends @omega.js/client and carries `omega.desktop`, the bridge to main.
16
16
  - **Modular feature library** — storage, IPC, theme, tray, menu, context menu, window manager, startup, app-state, deep-link, auto-updater, @omega.js/client auth, Sentry, **analytics, context, usage, remote-config, restart-manager**. Each feature is its own module with documented API.
17
- - **System-aware dynamic theme.** `manager.theme` follows the OS light/dark preference **live** by default (`'system'`), with `'light'`/`'dark'` overrides persisted across boots. Every renderer — windows AND embedded views — keeps `<html data-bs-theme>` in sync automatically; consumers drop plain `<button data-omega-theme-set="dark">` controls and @omega.js/desktop wires them.
18
- - **Cross-platform analytics identity.** GA4 Measurement Protocol with `client_id = uuidv5(deviceId, projectIdNamespace)` and `user_id = uuidv5(firebaseUid, projectIdNamespace)`. Same Firebase project ID in @omega.js/backend, UJM, @omega.js/client, and @omega.js/desktop produces identical `user_id` outputs everywhere → unified events for one human across desktop + web + backend, no manual stitching.
19
- - **"Hot config"** fetched from your brand site (`<brand.url>/data/resources/main.json`) and polled hourly — flip a force-update version, default user-agent, ad rotation, etc. without re-releasing. `manager.remoteConfig.get('versionRequired')`. Cached to storage so offline boots still have last-known values.
17
+ - **System-aware dynamic theme.** `omega.theme` follows the OS light/dark preference **live** by default (`'system'`), with `'light'`/`'dark'` overrides persisted across boots. Every renderer (windows AND embedded views) keeps `<html data-bs-theme>` in sync automatically; consumers drop plain `<button data-omega-theme-set="dark">` controls and @omega.js/desktop wires them.
18
+ - **Cross-platform analytics identity.** GA4 Measurement Protocol with `client_id = uuidv5(deviceId, projectIdNamespace)` and `user_id = uuidv5(firebaseUid, projectIdNamespace)`. Same Firebase project ID in @omega.js/backend, @omega.js/web, @omega.js/client, and @omega.js/desktop produces identical `user_id` outputs everywhere → unified events for one human across desktop + web + backend, no manual stitching.
19
+ - **"Hot config"** fetched from your brand site (`<brand.url>/data/resources/main.json`) and polled hourly: flip a force-update version, default user-agent, ad rotation, etc. without re-releasing. `omega.remoteConfig.get('versionRequired')`. Cached to storage so offline boots still have last-known values.
20
20
  - **File-based feature definitions** — trays, menus, and context-menus are JS files (full power, no DSL): `src/integrations/{tray,menu,context-menu}/index.js`. All three ship sensible **id-tagged defaults** (legacy-framework-style: about, preferences, check-for-updates, dev menu w/ inspector + log folders, etc.) and share the same **id-path mutation API**: `find`, `update`, `remove`, `enable`, `show`, `hide`, `insertBefore`, `insertAfter`, `appendTo`. Any default item is one line away from removal, customization, or repositioning.
21
21
  - **Lazy windows + Discord-style hide-on-close.** @omega.js/desktop doesn't auto-create any windows — your `main.js` calls `windows.create('main', { show: !startup.isLaunchHidden() })`. The `main` window's X button hides instead of quitting on every platform; real quit only via Cmd+Q / menu Quit / tray Quit / auto-update install. Inset titlebar by default (mac `hiddenInset` traffic lights / win native overlay buttons / linux native frame) with a draggable topbar in the page template.
22
22
  - **Zero-bounce hidden-launch on macOS.** `startup.mode = 'hidden'` bakes `LSUIElement: true` into Info.plist at build time → app launches completely invisible (no dock icon, no Cmd+Tab, no taskbar). Tray + notifications + networking still work. When the user double-clicks the running app's icon, @omega.js/desktop's `app.on('activate')` (macOS) / `app.on('second-instance')` (win/linux) handler surfaces the `main` window and the dock icon appears alongside it. CleanMyMac-style "tray-only at login, full window when manually opened" is the default.
23
23
  - **Auto-update background install.** When a download finishes from a background poll (not user-initiated), @omega.js/desktop auto-relaunches into the new version after 5s — apps update overnight without bothering the user. User-initiated checks skip this so your UI can prompt instead.
24
24
  - **Vert (ad) units with zero JS.** Drop `<div data-omega-vert></div>` into any view — the renderer auto-binds it (live, MutationObserver) to the shared OMEGA verts module: house/company inventory only (no AdSense in desktop surfaces), lazy near-viewport loading, sandboxed iframe, no-fill collapse. See [verts](docs/verts.md).
25
25
  - **esbuild-bundled** main / preload / renderer for source protection.
26
- - **Built-in test framework** — Jest-like syntax, four layers: `build` (plain Node), `main` (spawned Electron), `renderer` (hidden BrowserWindow), and `boot` (spawns the consumer's actual built `dist/main.bundle.js` for end-to-end smoke tests against the live manager — no `npm start && sleep && kill` shell hacks). Boot layer always rebuilds the bundle first so tests never see stale code.
26
+ - **Built-in test framework**: Jest-like syntax, four layers: `build` (plain Node), `main` (spawned Electron), `renderer` (hidden BrowserWindow), and `boot` (spawns the consumer's actual built `dist/main.bundle.js` for end-to-end smoke tests against the live `omega`, no `npm start && sleep && kill` shell hacks). Boot layer always rebuilds the bundle first so tests never see stale code.
27
27
  - **Schema-validated config.** One `config/omega.json5` (the OMEGA-wide format: shared brand/analytics/payment/firebase sections + desktop settings under `targets.desktop`), validated against the canonical schema in the bundled `@omega.js/config`. Validation runs at app boot AND during `gulp audit` — a misconfigured app never reaches the "white window of confusion" stage; it tells you exactly which field is broken with a numbered list. Simple flag model — `required: true | false | (config) => bool` — and `match` / `enum` / `type` only fire on field presence so consumers never see a flood of redundant errors for the same field. Pure-JS validator, no Ajv/Joi/Zod dep. See [config-schema](docs/config-schema.md).
28
28
  - **Multi-platform build/release** via GitHub Actions — macOS sign + notarize, Linux (deb + AppImage + optional Snap), Windows EV-token signing (self-hosted runner now, cloud-signing pluggable). Sensible installer defaults out of the box: NSIS one-click install on Windows (desktop + start menu shortcut, launch on finish), universal mac binary (one .dmg for Intel + Apple Silicon), `app.category` automatically mapped to per-platform values, copyright `{YEAR}` token always current. Snap Store publishing is on by default in the scaffold and auto-skipped at build time when `SNAPCRAFT_STORE_CREDENTIALS` isn't set — drop the credential blob into `.env`, run `mgr push-secrets`, and the next release ships to the Snap Store. See [installer-options](docs/installer-options.md).
29
29
 
@@ -113,15 +113,20 @@ with the C3/D10 skin.
113
113
 
114
114
  ## Per-process imports
115
115
 
116
+ Each entry exports ONE ready-made instance, `omega`; a consumer never writes `new`.
117
+
116
118
  ```js
117
119
  // src/main.js
118
- new (require('@omega.js/desktop/main'))().initialize();
120
+ const omega = require('@omega.js/desktop/main');
121
+ omega.initialize().then(() => { const { logger, windows } = omega; });
119
122
 
120
123
  // src/preload.js
121
- new (require('@omega.js/desktop/preload'))().initialize();
124
+ const omega = require('@omega.js/desktop/preload');
125
+ omega.initialize();
122
126
 
123
127
  // src/assets/js/components/<view>/index.js
124
- new (require('@omega.js/desktop/renderer'))().initialize();
128
+ import omega from '@omega.js/desktop/renderer';
129
+ omega.initialize().then(() => { const { logger, desktop } = omega; });
125
130
  ```
126
131
 
127
132
  ## Documentation
@@ -137,7 +142,7 @@ Each subsystem has its own API reference under [`docs/`](docs/):
137
142
  - [startup](docs/startup.md) — launch modes (`normal` / `hidden`), LSUIElement on macOS, login-item handling
138
143
  - [app-state](docs/app-state.md) — first-launch / launch-count / crash-sentinel flags
139
144
  - [deep-link](docs/deep-link.md) — cross-platform deep links, single-instance, pattern routing, built-in routes
140
- - [client-bridge](docs/client-bridge.md) — Firebase auth state synchronized across main + every renderer
145
+ - [auth](docs/auth.md): `omega.auth`, Firebase auth state synchronized across main + every renderer
141
146
  - [auto-updater](docs/auto-updater.md) — startup + periodic checks, 30-day max-age gate, dev simulation
142
147
  - [analytics](docs/analytics.md) — GA4 Measurement Protocol with cross-platform `uuidv5` identity (same human → same `user_id` across desktop/web/backend)
143
148
  - [context](docs/context.md) — runtime info block (geolocation, client, session, app) — @omega.js/backend-shaped
@@ -146,7 +151,7 @@ Each subsystem has its own API reference under [`docs/`](docs/):
146
151
  - [restart-manager](docs/restart-manager.md) — auxiliary helper app for relaunches; auto-installs via signed mac.zip / NSIS exe / browser-opened .deb
147
152
  - [config-schema](docs/config-schema.md) — canonical schema + validator for `config/omega.json5`. Hard-fails boot AND `gulp audit` on missing required fields, regex mismatches, enum violations, type mismatches. Single source of truth in the bundled `@omega.js/config`
148
153
  - [templating](docs/templating.md) — `{{ var }}` token replacement, page template, body-only views
149
- - [themes](docs/themes.md) — classy + bootstrap themes, `@use 'omega-desktop' as * with (...)` overrides, per-page CSS bundles, system-aware appearance (`manager.theme`)
154
+ - [themes](docs/themes.md): classy + bootstrap themes, `@use 'omega-desktop' as * with (...)` overrides, per-page CSS bundles, system-aware appearance (`omega.theme`)
150
155
  - [sentry](docs/sentry.md) — error/crash reporting, dev-mode gating, auto auth attribution, release tagging
151
156
  - [hooks](docs/hooks.md) — lifecycle hooks (build/pre, build/post, release/pre, release/post, notarize)
152
157
  - [installer-options](docs/installer-options.md) — installer/distribution config: NSIS one-click defaults, ia32 inclusion, app.category mapping, `{YEAR}` copyright token, snap publishing (default-on with cred-gated auto-skip), MAS roadmap
@@ -1,6 +1,6 @@
1
1
  // @omega.js/desktop core init — desktop-targeted defaults that complement the active theme.
2
2
  // Web-specific bits (cookieconsent, exit-popup, social-sharing, lazy-loading, service-worker)
3
- // are intentionally not ported from UJM — they don't apply to a packaged Electron app.
3
+ // are intentionally left out — they don't apply to a packaged Electron app.
4
4
 
5
5
  // Make sure the html / body fill the window with no scrollbars from layout glitches.
6
6
  html, body {
@@ -3,15 +3,18 @@
3
3
  * Drives the .omega-shell mechanics (core/css/shell/_index.scss): desktop
4
4
  * sidebar collapse (persisted) and the mobile drawer (scrim + Escape dismiss).
5
5
  * Controls are declarative — [data-shell-toggle="collapse|drawer"] and
6
- * [data-shell-dismiss] anywhere in the page.
6
+ * [data-shell-dismiss] anywhere in the page. The API is `omega.shell`.
7
7
  */
8
- import omega from '@omega.js/client';
9
8
 
10
9
  // Constants
11
10
  const STORAGE_KEY = 'shell.collapsed';
12
11
 
13
- // Module
14
- export default () => {
12
+ /**
13
+ * Build the shell API for `omega.shell` and wire the page's shell controls.
14
+ * @param {object} omega - the runtime instance (its storage holds the collapse state).
15
+ * @returns {object} the shell API: isCollapsed, isOpen, setCollapsed, setOpen, toggleCollapsed, toggleOpen.
16
+ */
17
+ export function createShell(omega) {
15
18
  const $shell = document.querySelector('[data-omega-shell]');
16
19
 
17
20
  // Create app shell API
@@ -38,7 +41,7 @@ export default () => {
38
41
  }
39
42
 
40
43
  $shell.setAttribute('data-shell-collapsed', value ? 'true' : 'false');
41
- omega.storage().set(STORAGE_KEY, !!value);
44
+ omega.storage.set(STORAGE_KEY, !!value);
42
45
  syncControls(shellAPI);
43
46
  },
44
47
 
@@ -70,19 +73,13 @@ export default () => {
70
73
  },
71
74
  };
72
75
 
73
- // Register on the omega library — web's bundle entry creates the container before
74
- // this runs; vendored surfaces (desktop/extension renderers) call this
75
- // module directly with no such entry, so create it if absent (#111)
76
- omega._library = omega._library || {};
77
- omega._library.appShell = shellAPI;
78
-
79
- // No shell on this page — the API stays registered but inert
76
+ // No shell on this page: the API is still returned, but inert
80
77
  if (!$shell) {
81
- return;
78
+ return shellAPI;
82
79
  }
83
80
 
84
81
  // Restore the persisted collapse state
85
- if (String(omega.storage().get(STORAGE_KEY)) === 'true') {
82
+ if (String(omega.storage.get(STORAGE_KEY)) === 'true') {
86
83
  $shell.setAttribute('data-shell-collapsed', 'true');
87
84
  }
88
85
 
@@ -119,7 +116,9 @@ export default () => {
119
116
  syncControls(shellAPI);
120
117
 
121
118
  console.log('App shell module loaded');
122
- };
119
+
120
+ return shellAPI;
121
+ }
123
122
 
124
123
  /**
125
124
  * Sync aria-expanded on every shell control to the current state
@@ -1,6 +1,4 @@
1
- // <Theme Name> — JS entry point
2
- // Loaded at runtime via webpack's __theme__ alias. Exposes Bootstrap globally
3
- // and runs your theme behaviors once the DOM is ready.
1
+ // <Theme Name>: JS entry point. A theme module: the host calls the default export with { omega, options }.
4
2
  import bootstrap from '__main_assets__/themes/bootstrap/js/index.umd.js';
5
3
  import { ready as domReady } from '@omega.js/client/modules/dom.js';
6
4
 
@@ -8,7 +6,9 @@ import { ready as domReady } from '@omega.js/client/modules/dom.js';
8
6
  window.bootstrap = bootstrap;
9
7
 
10
8
  // Initialize theme behaviors when the DOM is ready
11
- domReady().then(() => {
9
+ export default async function ({ omega, options }) {
10
+ await domReady();
11
+
12
12
  // Add your theme's initializers here, e.g.:
13
- // import('./js/navbar-scroll.js').then(m => m.default());
14
- });
13
+ // await import('./js/navbar-scroll.js').then((m) => m.default(omega));
14
+ }
@@ -6,12 +6,12 @@
6
6
 
7
7
  {% capture action_attributes %}{% if include.attributes %}{% for attr in include.attributes %} {{ attr[0] }}="{{ attr[1] }}"{% endfor %}{% endif %}{% endcapture %}
8
8
 
9
- <div class="dropdown animation-slide-up d-inline-flex" data-omega-bind="@show auth.user" hidden>
9
+ <div class="dropdown animation-slide-up d-inline-flex" data-omega-bind="@show auth.user.authenticated" hidden>
10
10
  <button class="p-0 border-0 bg-transparent" type="button" data-bs-toggle="dropdown" {{ action_attributes }} aria-expanded="false">
11
11
  <span class="d-flex align-items-center">
12
12
  <span class="position-relative d-inline-flex">
13
13
  <span class="avatar avatar-{{ avatar_size }} rounded-circle bg-secondary bg-opacity-10 border d-flex align-items-center justify-content-center overflow-hidden d-inline-flex">
14
- <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.photoURL" alt="{{ resolved.config.brand.name }} profile picture"/>
14
+ <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.profile.photoURL" alt="{{ resolved.config.brand.name }} profile picture"/>
15
15
  </span>
16
16
  <!-- Active status indicator -->
17
17
  <span class="position-absolute bottom-0 end-0 p-1 bg-success border border-2 border-white avatar avatar-2xs rounded-circle mb-0">
@@ -27,7 +27,7 @@
27
27
  <div class="d-flex align-items-center">
28
28
  <div class="position-relative me-3">
29
29
  <div class="avatar avatar-md rounded-circle bg-secondary bg-opacity-10 border d-flex align-items-center justify-content-center overflow-hidden">
30
- <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.photoURL" alt="{{ resolved.config.brand.name }} profile picture"/>
30
+ <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.profile.photoURL" alt="{{ resolved.config.brand.name }} profile picture"/>
31
31
  </div>
32
32
  <!-- Active status indicator -->
33
33
  <span class="position-absolute bottom-0 end-0 p-1 bg-success border border-2 border-white avatar avatar-2xs rounded-circle mb-0">
@@ -35,7 +35,7 @@
35
35
  </span>
36
36
  </div>
37
37
  <div class="flex-grow-1 overflow-hidden">
38
- <div class="fw-semibold text-truncate text-body" data-omega-bind="@text auth.user.displayName">User</div>
38
+ <div class="fw-semibold text-truncate text-body" data-omega-bind="@text auth.user.profile.displayName">User</div>
39
39
  <div class="small text-muted text-truncate" data-omega-bind="@text auth.user.email">email@example.com</div>
40
40
  </div>
41
41
  </div>
@@ -223,24 +223,24 @@
223
223
  <div class="omega-side__ad omega-shell__label">
224
224
  <div class="d-flex align-items-center justify-content-between mb-2">
225
225
  <span class="omega-chip">Sponsored</span>
226
- <a href="/pricing" class="omega-footer__link" data-omega-bind="@show !auth.resolved.active" hidden aria-label="Remove ads with Pro">
226
+ <a href="/pricing" class="omega-footer__link" data-omega-bind="@show !auth.user.active" hidden aria-label="Remove ads with Pro">
227
227
  <i class="fa-solid fa-xmark fa-xs"></i>
228
228
  </a>
229
229
  </div>
230
230
  {% section "verts/unit", type: "in-article", size: "rectangle" %}
231
- <a href="/pricing" class="d-block text-center omega-footer__link small mt-2 text-decoration-none" data-omega-bind="@show !auth.resolved.active" hidden>
231
+ <a href="/pricing" class="d-block text-center omega-footer__link small mt-2 text-decoration-none" data-omega-bind="@show !auth.user.active" hidden>
232
232
  Remove with <span class="text-primary">Pro</span>
233
233
  </a>
234
234
  </div>
235
235
  {% endif %}
236
236
 
237
237
  <!-- User row -->
238
- <div class="omega-side__user" data-omega-bind="@show auth.user" hidden>
238
+ <div class="omega-side__user" data-omega-bind="@show auth.user.authenticated" hidden>
239
239
  <span class="avatar avatar-sm rounded-circle overflow-hidden d-inline-flex flex-shrink-0">
240
- <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.photoURL" alt="{{ resolved.config.brand.name }} profile picture"/>
240
+ <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.profile.photoURL" alt="{{ resolved.config.brand.name }} profile picture"/>
241
241
  </span>
242
242
  <span class="omega-shell__label flex-grow-1 overflow-hidden">
243
- <span class="omega-side__user-name d-block text-truncate" data-omega-bind="@text auth.user.displayName">User</span>
243
+ <span class="omega-side__user-name d-block text-truncate" data-omega-bind="@text auth.user.profile.displayName">User</span>
244
244
  <span class="omega-side__user-email d-block text-truncate" data-omega-bind="@text auth.user.email">email@example.com</span>
245
245
  </span>
246
246
  <a href="/dashboard/account" class="btn-icon omega-shell__label" aria-label="Account settings">
@@ -163,9 +163,9 @@ config:
163
163
  <div class="mb-4">
164
164
  <div class="d-flex align-items-center">
165
165
  <div id="avatar-container" class="me-3 position-relative d-flex align-items-center">
166
- <!-- Avatar always available from getUser() -->
166
+ <!-- Avatar always available from the User's profile -->
167
167
  <div class="avatar avatar-lg rounded-circle overflow-hidden border">
168
- <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.photoURL" class="object-fit-cover w-100 h-100" alt="{{ resolved.config.brand.name }} profile picture"/>
168
+ <img src="{{ site.omega.placeholder.src }}" data-omega-bind="@attr src auth.user.profile.photoURL" class="object-fit-cover w-100 h-100" alt="{{ resolved.config.brand.name }} profile picture"/>
169
169
  </div>
170
170
  <!-- Active status indicator -->
171
171
  <span class="position-absolute bottom-0 end-0 p-1 bg-success border border-2 border-white avatar avatar-2xs rounded-circle mb-0">
@@ -173,7 +173,7 @@ config:
173
173
  </span>
174
174
  </div>
175
175
  <div>
176
- <h5 class="mb-1" data-omega-bind="@text auth.user.displayName">Loading...</h5>
176
+ <h5 class="mb-1" data-omega-bind="@text auth.user.profile.displayName">Loading...</h5>
177
177
  <small class="text-muted" id="profile-join-date">Member since Loading...</small>
178
178
  </div>
179
179
  </div>
@@ -121,7 +121,7 @@ bands below keep the reveal lane. {% endcomment %}
121
121
  {% endif %}
122
122
  <a href="{{ item.url }}" class="omega-rowlist__item omega-rowlist__item--link" data-omega-reveal>
123
123
  {%- comment %} The competitor's own description rides UNDER the
124
- row title (#563, legacy UJM parity): every _alternatives doc
124
+ row title (#563): every _alternatives doc
125
125
  authors it, and the hub was the only place it could land.
126
126
  Unauthored, the row is exactly what it always was. {% endcomment -%}
127
127
  <span>
@@ -9,7 +9,7 @@ hero:
9
9
  <!-- ═══ Masthead ═══ -->
10
10
  {% comment %} The term as it DISPLAYS: the aggregation humanizes the winning
11
11
  spelling ("Growth Hacks", #457); the tag cloud on /blog/tags title-cases the
12
- RAW spelling ("Growth-hacks") — a split legacy UJM shipped too (#294). {% endcomment %}
12
+ RAW spelling ("Growth-hacks") (#294). {% endcomment %}
13
13
  {% assign tag_name = resolved.tag.name | omega_title_case %}
14
14
  {% comment %} #467 (after #749): this masthead IS the page's first viewport, so
15
15
  the band paints with the document — data-omega-first-paint on the section, no
@@ -4,7 +4,7 @@ layout: frontend/core/cover
4
4
  # ═══ Payment confirmation — reimagined 2026-07-16: the receipt moment.
5
5
  # Serif headline + ok-chip, the order as a RECEIPT panel (mono order id,
6
6
  # hairline rows), next steps as the numbered ritual, quiet support foot.
7
- # All web-manager bindings preserved (confirmation.order.*, subscription.*);
7
+ # Bindings: confirmation.order.*, subscription.*;
8
8
  # the celebration confetti rides the page JS as before.
9
9
  ---
10
10
 
@@ -12,13 +12,12 @@
12
12
  * the Google script). No site key configured → the request still sends;
13
13
  * the backend decides.
14
14
  */
15
- import omega from '@omega.js/client';
16
15
  import { WAKEUP_ROUTE } from '@omega.js/client/modules/request.js';
17
16
  import { FormManager } from '@omega.js/client/modules/form-manager.js';
18
17
  import { initializeRecaptcha, getRecaptchaToken } from '__main_assets__/js/libs/recaptcha.js';
19
18
  import { event } from '__main_assets__/js/libs/analytics.js';
20
19
 
21
- export default (el) => {
20
+ export default (el, { omega }) => {
22
21
  const $form = el.querySelector('form.newsletter-form');
23
22
  if (!$form) {
24
23
  return;
@@ -41,7 +40,7 @@ export default (el) => {
41
40
  warmup();
42
41
  }, { once: true });
43
42
 
44
- const formManager = new FormManager($form, {
43
+ const formManager = new FormManager(omega, $form, {
45
44
  allowResubmit: false,
46
45
  resetOnSuccess: true,
47
46
  submittingText: 'Subscribing...',
@@ -3,5 +3,5 @@
3
3
  {%- if args.size != blank %} data-omega-vert-size="{{ args.size }}"{% endif %}
4
4
  {%- if args.vert_id != blank %} data-omega-vert-id="{{ args.vert_id }}"{% endif %}
5
5
  {%- if args.tags != blank %} data-omega-vert-tags="{{ args.tags | join: ',' }}"{% endif %}
6
- data-omega-bind="@hide auth.resolved.active"></div>
6
+ data-omega-bind="@hide auth.user.active"></div>
7
7
  </section>
@@ -8,15 +8,14 @@
8
8
  * renders empty). One implementation
9
9
  * across web/desktop/extension (the data-omega-vert vocabulary). Paying users
10
10
  * never see the unit: the host carries the standard
11
- * `@hide auth.resolved.active` binding.
11
+ * `@hide auth.user.active` binding.
12
12
  */
13
- import omega from '@omega.js/client';
14
13
 
15
- export default (el) => {
14
+ export default (el, { omega }) => {
16
15
  const $host = el.querySelector('.omega-vert-unit');
17
16
  if (!$host) {
18
17
  return;
19
18
  }
20
19
 
21
- omega.verts().mount($host);
20
+ omega.verts.mount($host);
22
21
  };
@@ -1,4 +1,5 @@
1
- // Base ships structure, not look — and no behavior of its own. This file
1
+ // A theme module: the host calls the default export with { omega, options }.
2
+ // Base ships structure, not look, and no behavior of its own. This file
2
3
  // exists for the same reason `_theme.scss` does: so the chain always
3
4
  // RESOLVES. `core/js/main.js` dynamically imports `__theme__/_theme.js`, and
4
5
  // the alias walks the theme roots and falls back to the FIRST one when no
@@ -6,8 +7,8 @@
6
7
  // theme, a tokens-only rung-1 fork) used to fail the bundle with an ENOENT on
7
8
  // a path it never claimed to own ([#773](https://github.com/Omega-JS-Stack/omega/issues/773)).
8
9
  // Base is the floor that catches it: every theme chain ends here, so the
9
- // import always lands on a real module.
10
+ // import always lands on a real module whose default export the host can call.
10
11
  //
11
12
  // A theme with behavior ships its own `_theme.js` and wins the walk ahead of
12
13
  // this one; nothing here is meant to be extended.
13
- export {};
14
+ export default async function ({ omega, options }) {}
@@ -1,4 +1,4 @@
1
- // Import the theme entry point
1
+ // A theme module: the host calls the default export with { omega, options }.
2
2
  import bootstrap from './js/index.umd.js';
3
3
 
4
4
  // Make Bootstrap available globally
@@ -12,5 +12,5 @@ window.bootstrap = bootstrap;
12
12
  /* @dev-only:end */
13
13
 
14
14
  // Add any custom code here
15
- // ...
15
+ export default async function ({ omega, options }) {}
16
16
 
@@ -22,5 +22,5 @@
22
22
  }
23
23
  }
24
24
 
25
- // (The UJM-era forced underline on .nav-link.active is gone — every nav
25
+ // (No forced underline on .nav-link.active — every nav
26
26
  // component owns its active look: pills fill, tabs border, classy fills.)
@@ -1,4 +1,4 @@
1
- // Import the theme entry point
1
+ // A theme module: the host calls the default export with { omega, options }.
2
2
  // __main_assets__ is a build alias that resolves to the framework's core assets
3
3
  import bootstrap from '__main_assets__/themes/bootstrap/js/index.umd.js';
4
4
  import { ready as domReady } from '@omega.js/client/modules/dom.js';
@@ -14,18 +14,20 @@ window.bootstrap = bootstrap;
14
14
  /* @dev-only:end */
15
15
 
16
16
  // Nav glassiness, marquees, reveals, count-ups, and rotators all ride the
17
- // shared motion engine (core/js/core/motion.js) — no theme JS needed.
17
+ // shared motion engine (core/js/core/motion.js), so no theme JS is needed.
18
18
 
19
- // Import tooltip initialization (the shared core-layer helper — #99)
19
+ // Import tooltip initialization (the shared core-layer helper, #99)
20
20
  import initializeTooltips from '__main_assets__/js/libs/initialize-tooltips.js';
21
21
  // Import hero demo form initialization
22
22
  import initHeroDemoForm from './js/hero-demo-form.js';
23
23
 
24
24
  // Initialize theme components when DOM is ready
25
- domReady().then(() => {
25
+ export default async function ({ omega, options }) {
26
+ await domReady();
27
+
26
28
  // Generic Bootstrap initializations
27
29
  initializeTooltips();
28
30
 
29
31
  // Initialize hero demo form if present
30
- initHeroDemoForm();
31
- });
32
+ initHeroDemoForm(omega);
33
+ }
@@ -31,8 +31,7 @@
31
31
  }
32
32
  }
33
33
 
34
- // Real combomarks (Ian 2026-07-16: the legacy UJM wordmark set, ported to
35
- // core/logos): full-color originals inlined, muted to a uniform wall by the
34
+ // Real combomarks (core/logos): full-color originals inlined, muted to a uniform wall by the
36
35
  // item's grayscale — dark mode luminance-flips them so ink-dark marks stay
37
36
  // legible on charcoal. Hover restores the brand color (the item drops its
38
37
  // filter; the invert must go with it).
@@ -19,8 +19,9 @@ function safeRedirect(raw) {
19
19
 
20
20
  /**
21
21
  * Initialize the hero demo form if present
22
+ * @param {object} omega - the host's instance, handed down by the theme module
22
23
  */
23
- export default async function initHeroDemoForm() {
24
+ export default async function initHeroDemoForm(omega) {
24
25
  const $form = document.querySelector('#hero-demo-form');
25
26
 
26
27
  if (!$form) {
@@ -30,7 +31,7 @@ export default async function initHeroDemoForm() {
30
31
  // Dynamic import FormManager only when needed
31
32
  const { FormManager } = await import('@omega.js/client/modules/form-manager.js');
32
33
 
33
- const formManager = new FormManager($form, {
34
+ const formManager = new FormManager(omega, $form, {
34
35
  submittingText: 'Processing...',
35
36
  });
36
37
 
@@ -1,6 +1,4 @@
1
- // Neobrutalism Theme — JS entry point
2
- // Loaded at runtime via webpack's __theme__ alias (import('__theme__/_theme.js')).
3
- // Exposes Bootstrap globally and wires up theme behaviors on DOM ready.
1
+ // Neobrutalism Theme: JS entry point. A theme module: the host calls the default export with { omega, options }.
4
2
  import bootstrap from '__main_assets__/themes/bootstrap/js/index.umd.js';
5
3
  import { ready as domReady } from '@omega.js/client/modules/dom.js';
6
4
 
@@ -18,7 +16,9 @@ window.bootstrap = bootstrap;
18
16
  import initializeTooltips from '__main_assets__/js/libs/initialize-tooltips.js';
19
17
 
20
18
  // Initialize when DOM is ready
21
- domReady().then(() => {
19
+ export default async function ({ omega, options }) {
20
+ await domReady();
21
+
22
22
  // Generic Bootstrap initializations
23
23
  initializeTooltips();
24
- });
24
+ }
@@ -1,6 +1,6 @@
1
1
  // /test — Theme (neobrutalism) page JS — the #theme layer.
2
2
  // Runs AFTER #main, BEFORE #project. Turns the "js-theme" dot green.
3
- export default ({ manager, options }) => {
3
+ export default ({ omega, options }) => {
4
4
  const dot = document.querySelector('.layer-dot[data-layer="js-theme"]');
5
5
  if (dot) {
6
6
  dot.style.background = '#30a46c'; // green
@@ -1,6 +1,4 @@
1
- // Newsflash Theme — JS entry point
2
- // Loaded at runtime via webpack's __theme__ alias (import('__theme__/_theme.js')).
3
- // Exposes Bootstrap globally and wires up theme behaviors on DOM ready.
1
+ // Newsflash Theme: JS entry point. A theme module: the host calls the default export with { omega, options }.
4
2
  import bootstrap from '__main_assets__/themes/bootstrap/js/index.umd.js';
5
3
  import { ready as domReady } from '@omega.js/client/modules/dom.js';
6
4
 
@@ -14,11 +12,13 @@ window.bootstrap = bootstrap;
14
12
  /* @dev-only:end */
15
13
 
16
14
  // Theme behaviors (masthead scroll state rides the shared motion engine's
17
- // data-omega-scroll-watch — no theme JS)
15
+ // data-omega-scroll-watch, no theme JS)
18
16
  import initializeTooltips from '__main_assets__/js/libs/initialize-tooltips.js';
19
17
 
20
18
  // Initialize when DOM is ready
21
- domReady().then(() => {
19
+ export default async function ({ omega, options }) {
20
+ await domReady();
21
+
22
22
  // Generic Bootstrap initializations
23
23
  initializeTooltips();
24
- });
24
+ }
@@ -1,6 +1,6 @@
1
1
  // /test — Theme (newsflash) page JS — the #theme layer.
2
2
  // Runs AFTER #main, BEFORE #project. Turns the "js-theme" dot green.
3
- export default ({ manager, options }) => {
3
+ export default ({ omega, options }) => {
4
4
  const dot = document.querySelector('.layer-dot[data-layer="js-theme"]');
5
5
  if (dot) {
6
6
  dot.style.background = '#30a46c'; // green