Repository navigation
fix(web): load mqtt.js only when Push connects - #1943
Conversation
push.ts imported mqtt and buffer statically, so every bundle carried them even without Push. They now load through a dynamic import on the first connect; the IIFE build inlines them.
|
| this.fallbackClientId; | ||
|
|
||
| const generation = this.generation; | ||
| const { connect, Buffer } = await loadTransport(); |
There was a problem hiding this comment.
Lazy-load cancellation lacks coverage
The new cancellation check runs after MQTT loads, but no behavioral test exercises closing Push during that load. The browser Push test uses the IIFE bundle, which inlines the import, and the Node test never connects Push. An ESM or CJS consumer test should verify that closing during the pending load does not open a connection; build and lint checks cannot catch a regression here.
Prompt To Fix With AI
This is a comment left during a code review.
Path: templates/web/src/services/push.ts.twig
Line: 543
Comment:
**Lazy-load cancellation lacks coverage**
The new cancellation check runs after MQTT loads, but no behavioral test exercises closing Push during that load. The browser Push test uses the IIFE bundle, which inlines the import, and the Node test never connects Push. An ESM or CJS consumer test should verify that closing during the pending load does not open a connection; build and lint checks cannot catch a regression here.
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly.Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
The browser build (dist/mqtt.esm.js) exports only a default, so the namespace had no connect and Push never opened in the browser.
What does this PR do?
The web
Pushservice importedmqttandbufferat module scope, so every app that bundles the web or console SDK carried mqtt.js, even when it never uses Push. mqtt.js has side effects, so bundlers could not tree-shake it.push.tskeeps onlyimport typefrommqtt.mqttandbufferload through a dynamicimport()on the first connect, cached, and reset if the load fails.close()during that load now stops the pending connect instead of opening an orphaned connection.connectis read off mqtt.js's default export, since its browser build (dist/mqtt.esm.js) exports only a default.atob+TextDecoder, becauseuserTopic()needs them before connecting.tsconfig:"module": "ES2020", sotscacceptsimport().inlineDynamicImports, since a script tag has no module loader. ESM/CJS keepmqttexternal and lazy.React Native is unchanged: Metro does not split dynamic imports by default, so a lazy import would gain nothing there.
Test Plan
php example.php web console, thennpm ci,format:check,lint,analyseandbuildinexamples/weball pass.dist/esmanddist/cjscontainimport('mqtt')and no static mqtt import.vite build):@appwrite.io/consoleindexchunkThat is −387,418 B raw and −108,208 B gzip, back within 4 KB of 17.0.0 (the difference is the new SDK methods). vibes does not use Push, so Push and mqtt.js drop out entirely.
Push: its main chunk is 102 KB (35 KB gzip), and mqtt.js (366 KB, 110 KB gzip) andbufferare separate chunks loaded byimport(). Against 18.0.0 the same app is one 495 KB chunk.WebChromium(the IIFE bundle subscribing through the mock MQTT broker) andWebNodepass in CI. A Node probe ofPush.subscribeagainst a closed port rejects withconnect ECONNREFUSED, so mqtt.js loads and attempts the connect.Related PRs and Issues
Console SDK 18.0.0 (appwrite/sdk-for-console#114) introduced the static import.