Skip to content

Commit 6d33592

Browse files
committed
POC for fix, only on the /project/ interface
1 parent 06ed862 commit 6d33592

2 files changed

Lines changed: 27 additions & 1 deletion

File tree

interfaces/project/index.html

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ <h2 slot="header">Project Details <a id="projectManagementBtn" title="Manage Pro
9292
<script type="module">
9393
import TPEN from '../../api/TPEN.js'
9494
import CheckPermissions from '../../components/check-permissions/checkPermissions.js'
95+
import { whenProjectReady } from '../../utilities/projectReady.js'
9596

9697
// [tpen-race C] /project inline-script about to register listener. Issue #541 diagnostic.
9798
const _alreadyLoaded = !!TPEN.activeProject?._createdAt
9899
console.log(`%c[tpen-race C]%c /project inline-script registering tpen-project-loaded listener; activeProject._createdAt=${_alreadyLoaded ? TPEN.activeProject._createdAt : 'UNSET'} @${performance.now().toFixed(1)}ms`, _alreadyLoaded ? 'color:#cc0000;font-weight:bold' : 'color:#008800;font-weight:bold', 'color:inherit')
99100
let _listenerFired = false
100101

101-
TPEN.eventDispatcher.on('tpen-project-loaded', (ev) => {
102+
whenProjectReady((ev) => {
102103
_listenerFired = true
103104
console.log(`%c[tpen-race D]%c /project listener fired @${performance.now().toFixed(1)}ms`, 'color:#008800;font-weight:bold', 'color:inherit')
104105
const goParse = document.getElementById("goParse")

utilities/projectReady.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,28 @@ export const onProjectReady = (ctx, handler, eventName = 'tpen-project-loaded')
1111
TPEN.eventDispatcher.on(eventName, bound)
1212
return () => TPEN.eventDispatcher.off(eventName, bound)
1313
}
14+
15+
/**
16+
* Context-free variant of {@link onProjectReady} for inline `<script type="module">`
17+
* blocks that have no element to bind to. If the project is already loaded when
18+
* called, the handler is invoked synchronously with a synthetic
19+
* `{ detail: TPEN.activeProject }` event so existing `ev.detail.*` handler bodies
20+
* keep working. Also subscribes for any future `tpen-project-loaded` dispatch.
21+
*
22+
* Closes the race described in issue #541, where the dispatch can complete before
23+
* an inline-script's `eventDispatcher.on(...)` registration runs.
24+
*
25+
* @param {(ev: { detail: any }) => void} handler
26+
* @param {string} [eventName='tpen-project-loaded']
27+
* @returns {() => void} unsubscribe
28+
*/
29+
export const whenProjectReady = (handler, eventName = 'tpen-project-loaded') => {
30+
if (typeof handler !== 'function') return () => {}
31+
try {
32+
if (TPEN.activeProject?._createdAt) {
33+
handler({ detail: TPEN.activeProject })
34+
}
35+
} catch (_) {}
36+
TPEN.eventDispatcher.on(eventName, handler)
37+
return () => TPEN.eventDispatcher.off(eventName, handler)
38+
}

0 commit comments

Comments
 (0)