Skip to content

Fix Intermittent Load Error#568

Merged
cubap merged 9 commits into
mainfrom
541-intermittent-load-error
May 13, 2026
Merged

Fix Intermittent Load Error#568
cubap merged 9 commits into
mainfrom
541-intermittent-load-error

Conversation

@thehabes
Copy link
Copy Markdown
Member

@thehabes thehabes commented May 12, 2026

Summary

Fixes #541. Project sub-pages intermittently failed to wire up footer buttons (Identify Lines, Transcribe Text, Manage Collaborators, etc.) and missed permission-based DOM gating. The root cause is a race: inline <script type="module"> blocks were registering tpen-project-loaded listeners after Project.fetch() had already dispatched the event, so the listener never fired.

This PR introduces a whenProjectReady utility that checks TPEN.activeProject synchronously first and falls back to a listener only when the project has not yet loaded. Every inline-script consumer that was racing the dispatch has been migrated to it.

Root cause

Project.fetch() in api/Project.js calls Object.assign(this, data) then immediately eventDispatcher.dispatch("tpen-project-loaded", this). When a cached/fast response resolves before module scripts evaluate, the dispatch happens before any inline eventDispatcher.on('tpen-project-loaded', …) runs, and the handler is registered against an event that already fired. EventTarget does not replay past events, so the inline script silently never executes — buttons stay unwired, permission attributes go unprocessed.

The intermittency matches the bug report: less frequent after a warm load, rare on jekyll s, common in production with fast responses.

Changes

New: utilities/projectReady.jswhenProjectReady(handler)

Context-free variant of onProjectReady for inline <script type="module"> blocks that have no element to bind to.

  • If TPEN.activeProject is already loaded, the handler is invoked synchronously with a synthetic { detail: TPEN.activeProject } event so existing ev.detail.* handler bodies keep working.
  • Otherwise it subscribes for the next tpen-project-loaded dispatch.
  • Sync and listener paths are mutually exclusive — handler fires exactly once per load.
  • Returns an unsubscribe function (no-op on the sync path).

onProjectReady was updated to follow the same exactly-once contract and to log handler exceptions via console.error instead of swallowing them silently.

Migrated consumers

Every inline <script type="module"> and module that was registering a raw tpen-project-loaded listener:

  • components/check-permissions/checkPermissions.js
  • components/check-permissions/permission-match.js — wrapped in queueMicrotask(...) so sibling module scripts that add tpen-view/tpen-edit markup during their own synchronous evaluation are in the DOM before the scan
  • components/update-metadata/index.html
  • interfaces/manage-layers/index.html
  • interfaces/manage-project/collaborators.html
  • interfaces/manage-project/index.html
  • interfaces/manage-project/index.js
  • interfaces/project/index.html
  • interfaces/project/metadata.html
  • interfaces/project/options.html
  • interfaces/quicktype/index.html

Tests

utilities/__tests__/projectReady.test.js covers both functions: listener subscription, sync invocation when project already loaded, no-op on missing handler, unsubscribe, the exactly-once contract, and sync-error logging. 11/11 pass via node --test utilities/__tests__/projectReady.test.js.

Follow-ups

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 12, 2026

@thehabes thehabes temporarily deployed to github-pages May 13, 2026 17:18 — with GitHub Pages Inactive
@thehabes thehabes marked this pull request as ready for review May 13, 2026 17:20
@thehabes thehabes requested a review from cubap May 13, 2026 17:24
Copy link
Copy Markdown
Member

@cubap cubap left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this solution. I know it feels like a bit of a heavy touch, btu it is really just an extraction.

@cubap cubap merged commit b74f1a2 into main May 13, 2026
6 checks passed
@cubap cubap deleted the 541-intermittent-load-error branch May 13, 2026 20:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

'Manage Project' Intermittent Page Load Error

2 participants