Commit Graph
22 Commits
Author SHA1 Message Date
37210ead25 perf(web): run the renderer zoneless and drop the zone.js polyfill (#1929)
* perf(web): run the renderer zoneless and drop the zone.js polyfill

Plan item C6 step 5. app.config.ts provides
provideZonelessChangeDetection() directly and apps/web builds without the
zone.js polyfill, so a tick runs only when a signal, markForCheck, an
Angular event or a render hook asks for one, not after every macrotask.
The flag from #1824 (change-detection.providers*.ts and the *-zoneless
configurations) goes away; a build-config test fails if the polyfill or a
zone provider comes back.

NgZone.run/runOutsideAngular calls that only mattered with zone.js are
removed from the dashboard data services, the settings unload guard and
the embedded MPV position poll (with the spec case asserting it), and
the unused polyfills.ts, polyfills-test.ts and setup-jest.ts are deleted.
Unit tests keep zone.js/testing for fakeAsync and waitForAsync;
apps/remote-control-web still bootstraps with zone.js.

renderer.initialBytes: 1,596,201 -> 1,545,931 bytes (-50,270) on a local
production build of this base; the baseline is lowered to the measured
value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(web): cite #1929 as the initial-bytes baseline evidence

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(web): ratchet the change-detection ticks that zoneless made deterministic

On the canonical runner (Performance ratchet run 38359088033, three runs
of this branch, five iterations each) renderer.cdTicksToFirstCard read 5,
renderer.cdTicksIdle30s 3 and renderer.cdTicksToFirstPage 9 in all 15
iterations, against 31, 1 to 4 and 22 with zone.js. They become baselines
with zero slack and the Performance journeys job checks them. J3 and J4
tick counts still vary by one and stay unenforced; J3 wall clock is in
master's range, so the local rise measured on #1824 was machine load.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(web): allow J1's one-tick lazy-chunk race in the first-card tick baseline

After merging #1931 (Angular Material off the startup path) the
Performance journeys job read renderer.cdTicksToFirstCard 5, 5, 5, 5, 6:
the lazily loaded chunk resolves on either side of a render. All 15
iterations before it read 5. The baseline stays 5 with one tick of slack
and a note; a return towards zone.js levels (31) still fails, and the
idle and first-page tick baselines stayed exact in the same run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(e2e): find a finished programme for the phone dialog after UTC midnight

The Xtream mock lays its 30-minute EPG slots out relative to now, and the
list view shows the programmes that overlap the selected day. In the
first half hour after midnight (the spec pins TZ=UTC) today holds only
the programme on air, so 'stacks the programme dialog actions on a phone'
found no data-when=past row and failed every retry on #1929's Windows
shard (00:18-00:23 UTC). The spec now waits for the list, and steps back
a day when today has no finished programme yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(architecture): record the zoneless renderer in the workspace contract

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-14 21:21:16 +02:00
8581bddcaf perf(web): keep the NgRx store devtools out of production bundles (#1810)
* perf(web): keep the NgRx store devtools out of production bundles

app.config.ts imported @ngrx/store-devtools statically and gated it on
AppConfig.production at runtime, so the optimizer kept the module in
main.js for the production, PWA and performance builds. The providers now
come from environments/store-devtools.providers.ts, an empty list in every
build; only the development and electron-e2e configurations swap in the
devtools through fileReplacements. A build-config test keeps it that way.

renderer.initialBytes: 1,608,610 -> 1,596,045 bytes (-12,565) on a local
production build; the baseline is lowered to the measured value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* perf(web): cite #1810 as the initial-bytes baseline evidence

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-07 21:19:34 +02:00
22a9c1f1e5 perf(web): add an opt-in zoneless change-detection build flag (#1824)
* perf(web): add an opt-in zoneless change-detection build flag

Plan item C6 step 4. app.config.ts takes its change-detection providers
from environments/change-detection.providers.ts, which keeps
provideZoneChangeDetection({ eventCoalescing: true }) for every existing
build. The new electron-performance-zoneless and electron-e2e-zoneless
web configurations are their base configuration plus one fileReplacements
swap to provideZonelessChangeDetection(), so the journeys and the Electron
E2E suite can run zoneless while nothing ships it. zone.js stays in the
polyfills until the flip.

A build-config test pins each *-zoneless configuration to its base plus
the swap and refuses the swap anywhere else.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(epg): schedule the guide's post-render scroll without zone.js

The programme guide jumps to now once the virtual list first renders rows,
and focuses cells after keyboard scrolls, from afterNextRender hooks
registered in CDK and RxJS callbacks. zone.js followed those callbacks
with a tick; under zoneless change detection a render hook schedules no
render, so the guide opened at midnight (epg-guide.e2e.ts on the zoneless
build). The guide now marks itself when it registers one, which is
harmless with zone.js.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(performance): record the zoneless flag measurements and E2E run

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* docs(performance): say the zoneless flag ran with the three implemented journeys

Review follow-up (Greptile): J4 search is still planned, so the flag was
validated with J1-J3 and the Electron E2E suite, not all four journeys.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-06 17:52:47 +02:00
e4cf48fdc2 test(perf): count change-detection ticks in the electron-performance build (#1776)
* test(perf): count change-detection ticks in the electron-performance build

J1 renderer.cdTicksToFirstCard, J2 renderer.cdTicksToFirstPage and the
J1 idle baseline renderer.cdTicksIdle30s. Angular's ɵsetProfiler is only
reachable through the dev-mode window.ng global, so the electron-performance
configuration alone swaps environment.ts for environment.performance.ts,
which re-exports the production AppConfig and wraps ApplicationRef._tick.
Production and PWA sources and output are unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(perf): refuse a J1 idle window that opened late after the settle point

Addresses review: the idle window opens in the settle timer's callback while
the settle point is that timer's deadline, so a late callback left ticks
uncounted between the two.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------

Co-authored-by: 4gray <fourgray@proton.me>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-01 14:23:15 +02:00
4grayandClaude Opus 5.5 5dbad2383f perf(web): keep channel lists, EPG views and the Stalker layer off the initial path (#1712)
The root shell imported WindowControlsComponent and DialogService through the @iptvnator/ui/components barrel, and esbuild keeps every Angular component module a barrel re-exports, so channel lists, EPG views, @angular/forms, date-fns and the whole Stalker data layer sat in main.js. The shell now uses file-level entries, the Stalker connection editor is a lazy proxy, and the release-notes and external-player info dialogs load on demand with a handled failure path.

renderer.initialBytes 2,714,336 -> 1,626,019 bytes (-40%); the baseline is lowered to the ubuntu ratchet measurement and the production/PWA initial budgets drop to 1.8/2 MB. J1: did-finish-load about -16 ms, first card within noise.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 08:48:01 +02:00
4gray 2cc7d0acb1 fix(perf): declare renderer cache output path 2026-07-26 22:37:52 +02:00
4gray 28ed38906d test(perf): add production renderer benchmark build 2026-07-26 22:37:52 +02:00
4gray bb4e386c6c fix(pwa): avoid CSP-blocked stylesheet deferral 2026-05-24 14:59:08 +03:00
4gray 32cc0b74e8 feat: add self-hosted PWA backend runtime (#944)
* feat(web-backend): add self-hosted proxy app

* feat(web): enable runtime PWA configuration

* test(web-e2e): cover self-hosted backend proxy

* test(web-e2e): clean self-hosted lint warnings

* fix(web-backend): validate proxied provider URLs

* fix(web-backend): proxy through registered provider targets

* fix(web-backend): document CodeQL SSRF validation boundary

* test(web-e2e): mock provider target registration

* fix(web): address self-hosted review feedback
2026-05-16 00:10:03 +02:00
4gray d24c77a143 chore(nx): enforce scoped workspace boundaries (#942) 2026-05-15 09:59:06 +02:00
4gray 973423a2b5 test(e2e): enhance Electron E2E tests with new build configurations and clear favorites functionality
Entire-Checkpoint: c6e522b4276c
2026-04-19 23:09:17 +02:00
4gray 545dfd8c67 feat(stalker): refactor epg handling to use get_epg_info
- Implemented unit tests for StalkerCollectionChannelsListComponent to verify EPG program loading and state management.
- Created unit tests for StalkerLiveStreamLayoutComponent to ensure proper rendering of EPG lists and handling of channel playback.
- Refactored EPG loading logic in StalkerLiveStreamLayoutComponent to improve performance and maintainability.
- Updated HTML template in StalkerLiveStreamLayoutComponent to replace deprecated components with new EPG list component.
- Enhanced EPG program handling by introducing methods for timestamp parsing and current program detection.
2026-04-11 10:43:50 +02:00
4gray 4a7855895b feat(tests): update Jest configuration for ESM support and add new test setups for playlist-shared-ui 2026-03-28 15:44:17 +01:00
4gray 7ac2fd66b8 refactor: update nx monorepo structure 2026-03-09 23:24:34 +01:00
4gray 256f0e0136 refactor(nx): update repository structure
Introduce new libraries to improve the boundaries and dependencies in mono repo
2026-03-08 20:01:42 +01:00
4gray 99b5ad161f feat(ui): improve info overlay and add EPG header search styles
Update info-overlay template to read simplified EPG fields and
avoid indexing into arrays for title, icon and description so bindings
are resilient and clearer:
- Use epgProgram?.iconUrl instead of epgProgram?.icon?.[0]?.src
- Use epgProgram?.title instead of epgProgram?.title?.[0]?.value
- Use epgProgram?.desc instead of epgProgram?.desc?.[0]?.value
- Guard description rendering with epgProgram?.desc

Adjust multi-epg header layout and add search UI styles to support
desktop window chrome and draggable regions:
- Add left padding to #epg-navigation for macOS traffic lights, enable
  backdrop drag via -webkit-app-region: drag and set z-index to keep
  header above content.
- Exclude interactive elements (buttons, search inputs) from drag by
  applying -webkit-app-region: no-drag to maintain native interactions.
- Add extensive styles for a channel search container (search input,
  icons, clear button, filter count, animations) and scaffold a program
  search container.

These changes improve robustness of EPG data rendering and add styled
search controls while ensuring proper window dragging behavior on
desktop builds.
2026-01-02 17:22:09 +01:00
4gray 3e2afe11e3 feat(ui): add remote-control URLs + fix header typos and env
Add support for displaying local remote-control URLs and QR code in the
Settings UI, including styles for URL list, row layout, monospaced links,
and a QR container. Expose a new global API signature getLocalIpAddresses
for retrieving local IPs.

Fix several UI issues:
- Correct typo in header method name (opedAddPlaylistDialog -> openAddPlaylistDialog).
- Fix malformed GitHub URL and collapse img tag formatting.
- Reformat imports and viewChild usage for readability.

Change local development backend URL to localhost:3000 in the local
environment to point to the running local API during development.

These changes improve developer ergonomics (local backend), add a remote
control discovery UX for users on the same network, and tidy up header
bugs and formatting.
2025-12-06 21:46:35 +01:00
4gray c5ddbde305 chore: increase component CSS size error threshold
Raise the maximumError for anyComponentStyle from 8kb to
kb in the web app build configuration. This relaxes the
build-size enforcement for component styles to accommodate
slightly larger CSS bundles and avoid spurious build failures.
2025-12-06 21:44:25 +01:00
4gray 837849ee57 refactor: code style improvements 2025-11-08 10:24:41 +01:00
4gray 7487738a7d refactor(nx): remove packages, fix build issues 2025-10-14 23:44:33 +02:00
4gray 7028ff4049 refactor(nx): app restructuring 2025-10-13 00:24:54 +02:00
4gray 99ed5df404 chore: back to electron + nx 2025-10-07 18:02:13 +02:00