Skip to content

[2.x] Fix realtime extender load order for tags & sticky (TypeError: not a constructor)#4699

Merged
imorland merged 2 commits into
2.xfrom
im/realtime-consumer-ordering
Jun 9, 2026
Merged

[2.x] Fix realtime extender load order for tags & sticky (TypeError: not a constructor)#4699
imorland merged 2 commits into
2.xfrom
im/realtime-consumer-ordering

Conversation

@imorland

@imorland imorland commented Jun 9, 2026

Copy link
Copy Markdown
Member

Fixes the flarum-tags failed to initialize / TypeError: mt(...) is not a constructor error reported in https://discuss.flarum.org/d/39359 when flarum/tags and flarum/realtime are enabled together.

Root cause

flarum/realtime registers its Realtime JS extender on the export registry at module-evaluation time (flarum.reg.add('flarum-realtime', 'forum/extenders/Realtime', ...)), and consumer extensions read it back via flarum.reg.get(...). The combined forum.js concatenates extensions in the order returned by ExtensionManager::resolveExtensionOrder(), so realtime must be ordered before any consumer — otherwise the consumer's reg.get runs before realtime's reg.add and instantiates undefined.

With no dependency edge, that order falls back to reverse-alphabetical by id (Kahn's output is reversed). Extensions whose id sorts after flarum-realtime are therefore emitted before it — the broken order. That's flarum-tags and flarum-sticky. The other realtime consumers (flags, likes, lock, messages) already declare flarum/realtime as an optional dependency, which is why they were unaffected.

Fix

Declare flarum/realtime as an optional dependency on the two consumers that were missing it, so realtime is always ordered ahead of them:

  • tags — added optional-dependencies: ["flarum/realtime"] (had none)
  • sticky — added flarum/realtime to its existing list (also normalised flarum-tagsflarum/tags)

Tests

Added a regression test to ExtensionDependencyResolutionTest proving the ordering: without the edge, [tags, realtime] resolves to the broken order; with it, realtime is placed first.

@imorland imorland added this to the 2.0.0-rc.3 milestone Jun 9, 2026
imorland added 2 commits June 9, 2026 19:07
flarum/realtime registers its Realtime JS extender on the export registry
at module-evaluation time, and consumers read it back via flarum.reg.get().
The combined forum.js concatenates extensions in resolveExtensionOrder()
order, so realtime must be ordered before any consumer — otherwise the
consumer's reg.get runs before realtime's reg.add and instantiates
undefined (TypeError: mt(...) is not a constructor).

Without a dependency edge that order is reverse-alphabetical by id, so
consumers whose id sorts after flarum-realtime (tags, sticky) are emitted
before it. flags/likes/lock/messages already declare flarum/realtime as an
optional dependency; declare it on tags and sticky too (and normalise
sticky's flarum-tags to flarum/tags).

Fixes https://discuss.flarum.org/d/39359
@imorland imorland force-pushed the im/realtime-consumer-ordering branch from a133a04 to 26c2e93 Compare June 9, 2026 18:07
@imorland imorland marked this pull request as ready for review June 9, 2026 18:08
@imorland imorland requested a review from a team as a code owner June 9, 2026 18:08
@imorland imorland merged commit 5f24a94 into 2.x Jun 9, 2026
25 checks passed
@imorland imorland deleted the im/realtime-consumer-ordering branch June 9, 2026 18:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant