Fix TopstepX login loop on bundled builds: signalr's dynamic require
@microsoft/signalr does an unconditional require('ws')/require('eventsource')
when constructing a connection; bundled (turbopack) builds throw 'dynamic
usage of require is not supported', which the login chain mislabelled as a
login failure and retried every 60s. Externalize the package and never let
hub setup fail the login — REST polling covers everything the hub does.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
153b1273c3
commit
4edb771701
+14
-1
@@ -172,7 +172,14 @@ export class TopstepXClient implements PlatformClient {
|
|||||||
if (this.syncInterval) { clearInterval(this.syncInterval); this.syncInterval = null; }
|
if (this.syncInterval) { clearInterval(this.syncInterval); this.syncInterval = null; }
|
||||||
this.syncComplete = false;
|
this.syncComplete = false;
|
||||||
|
|
||||||
await this.startHub();
|
// Hub failure must never read as a login failure: REST polling
|
||||||
|
// carries every feature (slower), and subscribeAll retries the
|
||||||
|
// hub on each sync tick.
|
||||||
|
try {
|
||||||
|
await this.startHub();
|
||||||
|
} catch (err) {
|
||||||
|
console.error('[topstepx] hub setup failed — running on REST polling only', err instanceof Error ? err.message : err);
|
||||||
|
}
|
||||||
|
|
||||||
await this.requestSync();
|
await this.requestSync();
|
||||||
this.syncInterval = setInterval(() => void this.requestSync(), 60_000);
|
this.syncInterval = setInterval(() => void this.requestSync(), 60_000);
|
||||||
@@ -240,6 +247,12 @@ export class TopstepXClient implements PlatformClient {
|
|||||||
}
|
}
|
||||||
this.subscribedAccountIds.clear();
|
this.subscribedAccountIds.clear();
|
||||||
|
|
||||||
|
// signalr's Node path does an unconditional dynamic require('ws') /
|
||||||
|
// require('eventsource') when constructing the connection — bundled
|
||||||
|
// builds throw "dynamic usage of require is not supported" on it, so
|
||||||
|
// the package is listed in next.config serverExternalPackages and any
|
||||||
|
// residual failure here is caught by the caller (REST polling covers
|
||||||
|
// everything the hub does, just slower).
|
||||||
const hub = new signalR.HubConnectionBuilder()
|
const hub = new signalR.HubConnectionBuilder()
|
||||||
.withUrl(USER_HUB, {
|
.withUrl(USER_HUB, {
|
||||||
skipNegotiation: true,
|
skipNegotiation: true,
|
||||||
|
|||||||
+4
-1
@@ -1,7 +1,10 @@
|
|||||||
import type { NextConfig } from "next";
|
import type { NextConfig } from "next";
|
||||||
|
|
||||||
const nextConfig: NextConfig = {
|
const nextConfig: NextConfig = {
|
||||||
serverExternalPackages: ['better-sqlite3'],
|
// @microsoft/signalr does dynamic require('ws')/require('eventsource') for
|
||||||
|
// its Node transports — bundling it (turbopack production builds) throws
|
||||||
|
// "dynamic usage of require is not supported" the moment a hub is built.
|
||||||
|
serverExternalPackages: ['better-sqlite3', '@microsoft/signalr'],
|
||||||
};
|
};
|
||||||
|
|
||||||
export default nextConfig;
|
export default nextConfig;
|
||||||
|
|||||||
Reference in New Issue
Block a user