Frooodle patch 1 - #1
Merged
Merged
Conversation
Frooodle
pushed a commit
that referenced
this pull request
Jul 27, 2023
Update messages_es_ES.properties
Frooodle
pushed a commit
that referenced
this pull request
Aug 10, 2023
Update messages_pt_BR.properties
Merged
aancw
added a commit
to aancw/Stirling-PDF
that referenced
this pull request
Dec 26, 2023
Frooodle
pushed a commit
that referenced
this pull request
Jun 7, 2024
fr messages: more translations
cimoing
added a commit
to cimoing/Stirling-PDF
that referenced
this pull request
Mar 24, 2026
…c8ccf7454e86a9b635f59604ad0693d change gradle distribution url * cherry-pick-81252436bc8ccf7454e86a9b635f59604ad0693d: (1 commits) change gradle distribution url Signed-off-by: 郭建超 <cimoing@gmail.com> Merged-by: 郭建超 <cimoing@gmail.com> CR-link: https://codeup.aliyun.com/668bab850f814d966b67a440/tools/Stirling-PDF/change/1
shya827
pushed a commit
to shya827/Stirling-PDF
that referenced
this pull request
Apr 16, 2026
…on-labels change left menu 'Merge' to 'Merge PDFs'
9 tasks
Frooodle
added a commit
that referenced
this pull request
May 19, 2026
Two issues the user reported plus my own audit found while sweeping widths from 360 to 1280: 1. At <=800px (where the inline right-aside details panel was display:none-d) selecting a file silently swallowed all file info: no thumbnail, no version journey, no actions. The aside hid but no replacement existed. 2. At every width >=900px when a file was selected, the bulk-action group (Add to workspace, Quick view, Move to, Remove, X) plus 2 filter selects plus the view toggle was wider than the main content area (~616px when both side panels are showing at 1280px). The overflow bled across the right edge into the details panel - 'All sources' and 'Recent first' literally rendered on top of the details panel's badges and tool history. Fix #1: render FileDetailsPanel inside a Mantine Drawer (position=right, size=sm) when useMediaQuery('(max-width: 800px)') is true. Same component, same props, same content - just hosted in a slide-in drawer with backdrop instead of as an inline aside. Removed the CSS rule that hid .files-page-details at <=800px (the JSX gate now controls visibility, and the CSS rule would otherwise also hide the panel inside the Drawer's portaled overlay tree). Fix #2: bulk-action button labels now hidden at every viewport (was previously only hidden at <=900px). The icons + Tooltips + aria-labels were already in place, so this is a CSS-only change. Added overflow-x:hidden on .files-page-toolbar as a defence-in-depth so any future toolbar overflow can't bleed into the details panel area again.
ConnorYoh
added a commit
that referenced
this pull request
May 29, 2026
…iene Six concerns from the 2026-05-29 review, all in one commit. Defers concern #7 (ddl-auto=update with Flyway) to a separate cleanup PR — it's a pre-existing setting whose flip carries OSS-entity-validation risk that needs its own focused change. #1 (HIGH) content_hash widened to VARCHAR(128) at the source - V11: CHAR(64) → VARCHAR(128) (with comment explaining the type:value storage key encoding) - Entity JobArtifactHashId.contentHash: length=64 → 128 + javadoc - Folds the change from #6464's stacked "schema fix" commit down here so #6460 is internally consistent and the Supabase #296 migration's "counterpart to the V11 widen" stops being aspirational. After this lands, the corresponding edit on #6464 becomes a no-op and gets squashed during rebase. #2 (HIGH) Restore @Profile("saas") on DefaultDocumentClassifier - The earlier removal was based on a hypothetical "future paid deployment without the saas profile". Concrete consistency with the 38 other @Profile("saas") beans in the module wins over speculative flexibility. - Class javadoc now documents the choice and the path to broadening (@Profile({"saas", "selfhosted-payg"})) when PR-X1 lands. #3 (MEDIUM, but materially worse than the review noted) Wire payg.* into the JPA scan paths - SaasJpaConfig was scanning saas.repository / .billing.repository / .ai.repository for repos and saas.model / .billing.model / .ai.model for entities — NOT saas.payg.*. The entire PAYG layer was inert: repos weren't beans, entities weren't managed types, every @Autowired PaygSomethingRepository would have failed at startup. Mockito-based unit tests never noticed. - Knock-on: my own stacked PR #6469 (PricingPolicyService) wouldn't have started either. Fixing here fixes both. - Added saas.payg.repository to @EnableJpaRepositories.basePackages and saas.payg (covers payg.policy / payg.job / payg.wallet / payg.entitlement / payg.shadow recursively) to @EntityScan. - New SaasJpaConfigScanTest reads the annotations via reflection and asserts every expected package is present — catches the next time someone adds a payg.X sub-package without wiring the scan. Reflection rather than @DataJpaTest because the production schema uses partial unique indexes that H2 doesn't fully support; standing up Testcontainers for one guard test is disproportionate. #4 (MEDIUM) Document the minChargeUnits flow - Per design § 3.4 the charge formula is unitsForProcess = max(policy.min_charge_units, docUnits), applied at process-open time in JobChargeService — NOT at classify time. The classifier's hardcoded floor of 1 is a separate "non-empty input → ≥1 unit" invariant. - Renamed the literal 1 to MIN_UNITS_PER_NONEMPTY_FILE constant with javadoc. - Added javadoc paragraphs on both the DocumentClassifier interface and DefaultDocumentClassifier explaining the two-floor design so the next reader doesn't conclude minChargeUnits is silently inert. #6 (LOW) Math.toIntExact on the multi-file group cap cast - Replaces (int) Math.max(1L, Math.min(groupCap, rawUnitsSum)) with Math.toIntExact(...). Theoretical (HTTP body limits make 2.15M files impossible) but matches the saturatedAdd care taken everywhere else. Single-file path got the same treatment. #8 (LOW) Document the @Version asymmetry + INTEGER-vs-BIGINT widths - WalletPolicy and WalletEntitlementSnapshot now carry javadoc explaining why no @Version: admin-only writes (wallet_policy) or full-row recomputation (entitlement snapshot) — no read-modify-write race exists. - V11 wallet_ledger section now carries a comment block explaining the width split: amount_units INTEGER (per-row delta, always small), but cap_units / period_spend_units / period_cap_units BIGINT (accumulate across a period, headroom matters). #5 (LOW) — PR description drift — handled separately via gh pr edit. #7 (LOW) — ddl-auto=update with Flyway — deferred to its own PR. Full :saas:test BUILD SUCCESSFUL with the new SaasJpaConfigScanTest passing 2/2.
5 tasks
anhvt3
added a commit
to anhvt3/Stirling-PDF
that referenced
this pull request
Jun 2, 2026
… diagonal text resize Review findings from /plan-ceo-review (commit 66e3153): - Stirling-Tools#1 HIGH: /pdf/text-editor now rejects inlineImages requests over 40MB input with a clear PAYLOAD_TOO_LARGE message instead of base64-inlining every image into one JSON (which could OOM/freeze the browser on large scanned PDFs). Overlay surfaces the backend message. Falling back to lazy was rejected — it would drop images on re-export. - Stirling-Tools#2 MED: imageBoxPt + resizeImageTransformSE now handle vertically flipped images (negative-d CTM): top edge is f + max(d,0), not f + |d|. Box placement + resize anchor correct for flipped placements. - Stirling-Tools#4 LOW: text resize handle uses the diagonal (dx+dy)/2 delta instead of vertical- only, so a down-right drag always grows (fixes the momentary shrink-on-drag-start). vitest 24/24, tsc clean (src/core), ConvertPdfJsonControllerTest 10/10, roundtrip harness 7/7. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
ConnorYoh
added a commit
that referenced
this pull request
Jun 9, 2026
…tor were short-circuiting before reading @RequiresFeature C4 review surfaced two interlocking bugs: both interceptors gated on `@AutoJobPostMapping` BEFORE consulting `@RequiresFeature`, so the AI controllers' class-level `@RequiresFeature(AI_SUPPORT)` had no effect (AI controllers carry no `@AutoJobPostMapping` — they are JSON-bodied proxies, not multipart tool POSTs). EntitlementGuard (major #2 — functional entitlement gap): - A team without AI entitlement could hit `/api/v1/ai/*` freely because the guard's scope check returned early on routes lacking `@AutoJobPostMapping`. - Fix: in-scope == (`@AutoJobPostMapping` present) OR (`@RequiresFeature` present, method- or class-level). Routes with neither still skip (admin / info / config endpoints). PaygChargeInterceptor (major #1 — billing classification gap): - Same short-circuit, same root cause. `determineCategory` was never reached for AI controllers, so the AI billing category would never be set even if those routes did carry multipart payloads. - Fix: same gate widening. Routes without multipart inputs still short-circuit inside `doPreHandle` without touching the charge service — the multipart materialisation logic only runs when actual file parts are present. Tests: - `EntitlementGuardTest`: two new tests covering (a) method-level `@RequiresFeature` without `@AutoJobPostMapping` returns 402 when entitlement is missing, and (b) class-level `@RequiresFeature` (AiCreateController shape) returns 401 for anonymous users. - `PaygChargeInterceptorTest`: three new tests — `@RequiresFeature`-only endpoint with no multipart body short-circuits without counting as BYPASSED; same shape with multipart body lands in `BillingCategory.AI`; class-level `@RequiresFeature` is resolved via beanType lookup. Build + verification: - `STIRLING_FLAVOR=saas :saas:compileJava :saas:compileTestJava` — clean. - `:saas:test --tests stirling.software.saas.payg.*` — PASS, JaCoCo thresholds met (line 25.78%, instruction 27.14%, branch 24.40%).
ConnorYoh
added a commit
that referenced
this pull request
Jun 11, 2026
Security came back clean; this is the dead/unwired cleanup. - #1 Per-member sub-caps enforced nothing (cap was read for display, never gated), so the control read as functional when it wasn't. Removed the sub-cap editor, the PATCH /api/v1/payg/sub-caps endpoint, and the dead CapEvaluator.combineTeamAndMember/allEnabled. Kept the per-member usage display (MemberUsage); team_memberships.cap_units retained but dormant. Re-adding real enforcement is tracked in notes/payg-followups.md. - #2 Deleted the unused WalletCategorySummaryDao and dropped its V16 view via a NEW migration (V21) rather than editing V16 — preserves Flyway checksums on already-migrated DBs. - #3 Removed dead methods: EntitlementService.anonymousFull, CapEvaluator.allEnabled, WalletLedgerRepository.findByTeamIdOrderByOccurredAtDesc (+ their tests). - #4 reserved enums left as forward-compat placeholders; the API/AI chaining billing model + ProcessType decision are captured in the follow-ups note. :saas:test + spotlessCheck green; FE saas typecheck clean.
ConnorYoh
added a commit
that referenced
this pull request
Jun 29, 2026
…red, no behaviour change) Phase 2, PR #1 (slice 1/3). Move the pure doc-unit calculation out of the SaaS DefaultDocumentClassifier into a new stirling.software.proprietary.billing package (UnitCalcPolicy value object + DocumentUnitCalculator) so a linked self-hosted instance can cost operations with identical logic. :saas depends on :proprietary so the SaaS classifier delegates; the community core build (which excludes :proprietary) never ships EE billing logic. PricingPolicy (JPA) + the jpdfium/IO inspection stay in :saas. Behaviour-preserving — existing DefaultDocumentClassifier{,More}Test pass.
ConnorYoh
added a commit
that referenced
this pull request
Jul 7, 2026
- Keep the Keygen response body out of thrown exception messages (it can echo owner emails/metadata and reaches warn-level logs); log it at debug instead, and throw status-only. (review #3) - Fail fast when stirling.keygen.enabled=true but creds are missing — KeygenEnterpriseLicenseService now throws at construction instead of soft-starting and failing at first use. (review #4) - Gate the offline .lic download on the ACCEPTED quote's offline add-on, not the latest quote, so toggling the add-on on an unaccepted draft can't unlock the file before it's bought. (review #5) Not changed: review #1 (key-vs-id) is a false positive — Keygen addresses licences by UUID *or* URL-safe key, and the shipping self-hosted edge (keygenService.ts) uses the key in the path for every GET/PATCH/suspend; this client mirrors that. Verify against live Keygen before flag-on remains a tracked pre-flag task. Review #2 (immediate licence, no auto-revoke; offline .lic unrevocable) is by-design and tracked for GA (needs the deferred invoice.paid webhook + a bridge-term for the offline case).
ConnorYoh
added a commit
that referenced
this pull request
Jul 9, 2026
…air-gapped .lic, cleanup - #1 Flyway collision: renumber procurement_deal_setup off the duplicated V32 (clashed with V32__policy_processed_files on main) to V34; V33 invoice_pdf unchanged. (The remaining V30/V31 dups are main-owned — the #6871 schema-authority workstream.) - #2 Persist the renewal figure: new renewal_annual_minor column (V35) set at buildQuote from the breakdown; the snapshot echoes the persisted value (fallback to a live projection for pre-existing rows) instead of recomputing from defaults() every read. - #3a Air-gapped .lic for trials + quotes: gate the offline licence file on the deal's deployment==airgap (chosen at trial setup), so the .lic is generated from the current trial-or-annual licence — not only after a committed accept. FE surfaces the download in the licence-key modal from the trial onward (offlineAvailable keyed off data.deployment). - #3b Remove the vestigial offlineLicense field from QuoteRequest/QuoteConfig/QuoteConfigEcho/ ProcurementQuote + buildQuote + tests (the offline gate is deployment==airgap now). Left currency as USD-only and the offline_license DB column orphaned (no drop migration). Supabase twins updated (deal_setup twin now references V34; new renewal twin) in the SaaS repo. Verified: saas compile + procurement pricing tests, portal typecheck, eslint, prettier, en-US TOML (valid, no dup keys), procurement vitest (9/9).
ConnorYoh
added a commit
that referenced
this pull request
Jul 10, 2026
- Gate the run-id header (#1): PaygChargeInterceptor now honours X-Stirling-Run-Id only when the internal-dispatch marker (X-Stirling-Automation) is also present. A raw external API call can no longer pin a constant run id to collapse separate same-content charges into one, which would defeat "charge per API call". InternalApiClient stamps both headers on every loopback sub-step, so legitimate automation is unaffected. Extracts hasAutomationHeader() (DRY across category/source determination) + two interceptor tests (honoured-with / ignored-without). - Usage card cost (#3): show "avg per PDF" as a formatted currency amount (meter units x per-unit rate / input files) instead of raw units, matching the requested cents-per-PDF; omitted when the rate is unknown. - Empty-state (#4): don't show "No processing yet" when there is unsynced instance-local (units-only) usage but zero synced PDFs. - Style (#7): import AutomationRunContext / UUID instead of fully-qualified inline references in PipelineProcessor, PolicyEngine, AiWorkflowService. - Refresh the now-stale PdfsProcessedCard class javadoc.
This was referenced Jul 17, 2026
palacios22c
pushed a commit
to palacios22c/Stirling-PDF
that referenced
this pull request
Jul 20, 2026
…ing) (Stirling-Tools#6967) Small follow-up to Stirling-Tools#6957 addressing the three non-blocker findings from its review. **Draft / stacked on Stirling-Tools#6957** — the diff shows Stirling-Tools#6957's changes until it merges, then auto-narrows to just these 5 files. Mark ready + rebase onto `main` once Stirling-Tools#6957 lands. ### 1. avg-per-PDF no longer blends unsynced units over synced-only docs `avgCostMinor` now divides **synced** units (`spendUnitsThisPeriod`) by synced docs, so numerator and denominator cover the same population. Combined-billing `pendingUnits` (units-only, no doc count) previously inflated the average for linked-instance teams. The "meter units" figure still shows synced+pending (total current usage) — only the *average* is synced-only. ### 2. Empty-state: unsynced-only reads cleanly When `docs == 0` but there are pending meter units (combined-billing, nothing synced yet), the card showed a bare **"0 PDFs"** headline with a count-less summary and no split. It now shows a **"{n} meter units pending sync from linked instances"** note instead. New `unitsPending` i18n key + a `UnsyncedOnly` story. (Only reachable on the combined-billing path; pure-SaaS teams are unaffected.) ### 3. uniquePdfs wording is now accurate `document_fingerprint` is a hash of a charge's whole **input set**, so the same file reused across *different* groupings (standalone, then later in a merge `{A,B}`) counts per grouping — a close approximation of "unique PDFs", exact for the single-input common case. Softened the FE type doc + the `WalletLedgerEntry.document_fingerprint` javadoc to say so (no behaviour change; counting model unchanged). ### Verification FE typecheck / test / lint / format all clean; `:saas:compileJava` green. No behaviour change beyond Stirling-Tools#1 (avg) and Stirling-Tools#2 (empty-state copy); Stirling-Tools#3 is doc-only.
dinodinu
pushed a commit
to dinodinu/Stirling-PDF
that referenced
this pull request
Jul 21, 2026
## What this PR does Removes the **Flyway** migration system from the SaaS build: - drops `flyway-core` + `flyway-database-postgresql` from `app/saas/build.gradle` - deletes all `Vxx__*.sql` files under `app/saas/src/main/resources/db/migration/` - removes the `spring.flyway.*` config from `application-saas.properties` - clears the now-inert `SPRING_FLYWAY_ENABLED` override and stale Flyway comments in `testing/compose/docker-compose-saas.yml` `ddl-auto` is **left on `update`** (unchanged) — that's a separate decision (see "Not in this PR"). ## Why — Flyway never actually ran anywhere From a full schema-management review (`notes/FLYWAY_MIGRATION_REVIEW.md`), verified against the live databases: - **Prod & dev (v3):** no `flyway_schema_history` table exists in any schema → Flyway has never executed. Schema is authored by the Supabase migrations in `Stirling-PDF-SaaS` and applied by that repo's **GitHub integration** (merge to `main` → prod). - **Tests:** the saas module has zero `@SpringBootTest`; the only real-DB integration tests (in `proprietary`) use `ddl-auto=create-drop` and don't have Flyway on the classpath. - **The mock-DB harness** (`testing/compose/docker-compose-saas.yml`, PAYG cucumber) *explicitly disabled* Flyway, because the `Vxx` migrations can't run against a clean Postgres — they assume Supabase has already provisioned `users`/`teams` (`V2` ALTERs `users`, `V5` references `teams`). So Flyway was dead weight, and its 4 duplicate versions (`V25/V26/V30/V31`) were a latent trap: re-enabling it would crash boot on the collision. Everything it contained (schema + seeds like the default pricing policy) is already mirrored by the Supabase migrations, and by `saas-seed.sql` for the cucumber stack. ##⚠️ Required follow-up (item Stirling-Tools#1) — capture the Flyway-only tables into Supabase migrations **This is documentation of the next step, not done in this PR.** Seven tables were defined in Flyway with **no matching Supabase migration**. They exist in prod today only because `ddl-auto=update` created them from their entities. Before `ddl-auto` is ever tightened to `validate` (see Stirling-Tools#3 below), and so any fresh Supabase branch is complete, they must be added as Supabase migrations in `Stirling-PDF-SaaS/supabase/migrations/`. **Capture (CREATE) — 6 live tables** (definitions are visible in the deleted files in this PR's diff): | Table | Source (deleted here) | Backing entity | |---|---|---| | `resource_grants` | `V25__resource_grants.sql` | `ResourceGrant` | | `integration_configs` | `V26__integration_configs.sql` | `IntegrationConfig` | | `policy_sources` | `V22__policy_engine_tables.sql` | `SourceEntity` | | `policy_source_doc_counts` | `V23__policy_source_doc_counts.sql` | `SourceDocCountEntity` | | `policy_source_doc_totals` | `V23__policy_source_doc_counts.sql` | `SourceDocTotalEntity` | | `saas_user_extensions` | `V9__saas_user_team_extensions.sql` | `SaasUserExtensions` | Write them as `CREATE TABLE IF NOT EXISTS stirling_pdf.<name> (...)` (idempotent — no-op against the existing prod/v3 tables). Preserve column types/defaults/constraints from the deleted `Vxx` files. **Drop (do NOT recreate) — 1 orphaned table:** - `classification_labels` — created by `V30` and dropped by `V39` within Flyway; its `ClassificationLabel` is now a plain `record`, not a JPA entity. It lingers in prod only because Flyway's `V39` drop never ran. The follow-up should emit a `DROP TABLE IF EXISTS stirling_pdf.classification_labels` (mirroring `V39`'s intent), after confirming nothing reads it. ## Not in this PR (deliberately) - **Stirling-Tools#3 — flip saas `ddl-auto` `update` → `validate`.** Held pending team confirmation; it has boot-risk and should be gated by a CI "validate-boot against a fresh Supabase branch" first. Self-hosted stays on `update` regardless. - **Stirling-Tools#4 — `billing_subscriptions` split-brain** (prod `public` has 23,164 rows, `stirling_pdf` has 0, Java reads the empty one). Tracked separately. ## Verification - `:saas:compileJava` succeeds with Flyway removed (no code imports `org.flywaydb.*`). - No test or ArchUnit rule references Flyway or the migration files. - No runtime/data impact: Flyway never ran against any live database. --------- Co-authored-by: James Brunton <jbrunton96@gmail.com>
This was referenced Jul 23, 2026
4 tasks
tuke-code
referenced
this pull request
in tuke-code/Stirling-PDF
Aug 13, 2026
…rowser CI (Stirling-Tools#7366) # Description of Changes Follow-up to Stirling-Tools#7314, which fixed the IndexedDB blob rejection itself. This one fixes the remaining WebKit engine gaps, fixes the ways that class of failure surfaced to the user, and adds the cross-browser signal that would have caught them on the PR instead of six weeks later. ## Why this exists Two total WebKit outages sat on `main` for weeks: 1. pdf.js reads its text stream with `for await (… of readableStream)`, and WebKit has no `ReadableStream[Symbol.asyncIterator]`. **All** pdf.js text extraction threw `TypeError: undefined is not a function` — Compare, read-aloud and the PDF text editor were dead on Safari. 2. IndexedDB in WebKit rejects Blob/File values with `UnknownError: Error preparing Blob/File data to be stored in object store`, so nothing persisted and every reload came back empty. Neither was caught, because the existing specs never did the work. The Compare specs filled both slots and asserted the button was enabled; none of them clicked it. The persistence specs asserted a *filename* reappeared after a reload, which only needs the metadata record, not the bytes. Every failure here **looked like success** — empty panes, blank thumbnails, a `src` that was set but empty. That shapes the tests more than the fixes. ## WebKit engine gaps - **`ReadableStream[Symbol.asyncIterator]`**, installed at the entry point before any PDF work starts. The lock discipline is the subtle part: releasing is idempotent, is *not* done after a successful read, and *is* done in the read's error steps — `for await` never calls `return()` when `next()` rejects, so nothing else would ever unlock an errored stream. - **`requestIdleCallback`**, installed once instead of guarded at each call site. This one wasn't broken, it was mistimed: the local fallbacks fired at 200ms and 1000ms, landing the pdfium WASM compile on top of the app's first renders. The shim honours the caller's full timeout, so `{timeout: 2000}` means 2000ms. - **`convertToBlob()` does not fail on a format it can't encode.** Per spec it silently serialises to PNG, so asking for WebP and getting PNG back looks like success. Canvas output now probes what the engine really produced (once per realm) and uses the best lossy format it honours. PNG of a rendered page is several times the size of the equivalent WebP or JPEG, held as object URLs for every page on screen, on the engine with the tightest renderer memory budget. ## WebKit storage failures These read as generic transaction hygiene. They aren't — a refused blob write **aborts its transaction**, which is the mechanism that turned a WebKit rejection into a hang. - **Blob refusal is remembered from any write**, not just the initial `add`. WebKit reports it when it can't write the blob's *backing file*, which is per-operation — an engine that accepted the add can still refuse the rewrite, and every read-modify-write rewrites the record with its body attached. - **Aborted transactions no longer hang.** Read-modify-write moves to a single `updateRecord` helper that owns its transaction, guards it once, and resolves on **commit** rather than on the put's `onsuccess`. The previous shape — two promises over one shared transaction, with an `await` between the get and the put — put the abort guard on the read, leaving the write with no handler at all. `persistVersionedOutputs` awaits that, and `.catch` can't rescue a promise that never settles, so tool outputs could silently stop persisting. - **Stored blobs are no longer re-wrapped on read.** Since Stirling-Tools#7175 the record holds the `File` itself; wrapping it in `new Blob([record.data])` can cost WebKit the backing handle, giving you an object that looks valid and reads as empty. - **The file sidebar reaches a resting state** when the library can't be read, instead of spinning forever on a rejection nobody observes. It carries on with the in-memory workbench files: an unreadable library should cost the user their history, not the file they're working on. - **Thumbnail failures are logged.** Three `catch {}` blocks returned `""`, and an empty thumbnail is indistinguishable from "this file has no preview" — which is how outage #1 hid as a cosmetic nicety. ## CI `main` now runs the whole stubbed suite once per engine (Stirling-Tools#7304), so the new `@engine-capability` specs get chromium, firefox and webkit for free. They assert the primitives actually work — a **counted** comparison, a raster thumbnail data URL with real payload, and a page rendered from a file restored by a reload — rather than that the UI rendered. Deliberately small: anything added there is paid for three times per PR, so add depth, not breadth. Run them alone with `task e2e:cross-browser -- --grep @engine-capability`. The cross-browser projects now share the stubbed project's viewport. At the device presets' default 1280x720 a layout difference would fail these specs on Firefox/WebKit only, which reads as an engine outage. `vite.config.ts` gains a `worker.plugins` entry so `@app/*` resolves inside worker bundles. Worker bundles are a separate Rollup pass and don't inherit `plugins`, so the alias worked in the app and failed in a worker — previously worked around with a relative import plus a lint exemption, which silently bypasses the layer cascade. ## Verification - `task frontend:check` green: typecheck, oxlint, theme lint, stylelint, prettier, 215 test files / 1841 tests. - The `@engine-capability` suite passes on Chromium and WebKit locally. - **Negative control:** with the `ReadableStream` shim removed, the WebKit comparison spec fails at the Deletions/Additions assertion — the exact reported Safari symptom. Restored, and it passes. Both the fix and the test that guards it are load-bearing. - The worker alias change verified both ways: the build inlines the encoding probe into the worker chunk, and removing `worker.plugins` fails with `Rollup failed to resolve import "@app/utils/canvasImageEncoding"`. - The abort regression test aborts the transaction mid-write and asserts `markFileAsProcessed` settles. Before the fix it never settles and the test times out. ## Split out of this PR Two things in earlier revisions of this branch were engine-agnostic — found via the same symptom, not the same cause — and now have their own PRs: - **Stirling-Tools#7416** — blocked IndexedDB upgrades hanging the file library (multi-tab lifecycle, the concurrent-open race, `onversionchange`). - **Stirling-Tools#7417** — the thumbnail TTL rewriting the whole library on every listing. `FileSidebar`'s try/catch appears in both this PR and Stirling-Tools#7416, identically: a WebKit rejection and a blocked-open rejection both have to stop stranding the spinner. Whichever merges second is a no-op for that file. ## Known gaps - The blob-refused **rewrite** recovery in `updateRecord` isn't unit-tested. `fake-indexeddb` never returns Blob values from a read, so the branch that converts to a copy can't be reached there. Noted in the test file. - For the same reason, `fileFromRecord`'s "hand the stored File back untouched" path is only covered on a real engine, by the reload spec. - Nothing asserts that `src/index.tsx` imports the shims. The unit suite installs the same module via `setupTests.ts` (jsdom has the same gaps WebKit does), so a future regression where the entry point drops the import would still be green under vitest. - `FileSidebar`'s resting-state fix loses its E2E coverage until Stirling-Tools#7416 lands — forcing WebKit's blob refusal from a spec isn't practical, which is why that spec blocks the database instead. --- ## Checklist ### General - [x] I have read the [Contribution Guidelines](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/CONTRIBUTING.md) - [x] I have read the [Stirling-PDF Developer Guide](https://github.com/Stirling-Tools/Stirling-PDF/blob/main/DeveloperGuide.md) (if applicable) - [x] My changes generate no new warnings ### Documentation - [x] I have updated relevant docs on [Stirling-PDF's doc repo](https://github.com/Stirling-Tools/Stirling-Tools.github.io/blob/main/docs/) (if functionality has heavily changed)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.