Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Node Hangs indefinelty on tmi.Client() - Newer version of Node 21+ #555

Open
2chivi opened this issue Jul 28, 2024 · 1 comment
Open

Node Hangs indefinelty on tmi.Client() - Newer version of Node 21+ #555

2chivi opened this issue Jul 28, 2024 · 1 comment

Comments

@2chivi
Copy link

2chivi commented Jul 28, 2024

Actual behaviour:
Node Hangs indefinelty on tmi.Client() - Newer version of Node 21+ on Linux Ubuntu LTE

Noticed some dependencies are out of date. Could that have to do with it? Not sure if tmiV1 is abandoned? Or if we are supposed to switch to v2?

Thanks

Expected behaviour:

Error log:
No errors

Insert your error log here

Configuration

  • tmi.js version:
  • Node version (if applicable):22.5.1 Ubuntu LTE 20
  • Browser and version (if applicable):
  • Operating system:
@AlcaDesign
Copy link
Member

Related to your issue's problem:
What version of tmi.js are you using? Node will hang if there are timers, open socket connections, etc., so can you give me minimal code that replicates this hang? Since all you said was "on tmi.Client()": no timeouts or intervals should be started before calling the connect method.

Is tmi.js@v1.x abandoned?

v1.x hasn't received an update in a while. With the v1.9.0-wip branch, I'd like to bring necessary updates like new events, replying, removing lots of dead code, and more. You can see the changes here: main...v1.9.0-wip.

If you'd like to try it as is, you can install the branch from GitHub using this and require/import tmi.js as normal:

npm i tmijs/tmi.js#v1.9.0-wip

Warning

Not meant for production

This does involve breaking changes but it's mostly dead features and things I wouldn't expect people to be using.

Potentially breaking changes

  • Removed client.api. cef6988
  • Removed commands. Only action (/me messages) remains per Twitch. 902a736
  • Removed options, timers, and methods related to emote sets. Just the normal event emotesets remains to allow for a consumer to update them with the Helix API. 3edc540
  • Using newer syntax like the nullish coalescing operator (??) and optional chaining (?.). a03ace3 7195714
    • With this, tmi.js will only be supporting versions of Node.js that are receiving maintenance. Currently that's v18 until roughly June of 2025 per the release schedule. f8ff1a5
  • Convert to class syntax instead of the old style of classes. new is required when instantiating tmi.Client. 807fa56
  • Replaced the included EventEmitter (a very old version of Node's EventEmitter) with a custom EventEmitter class implementing almost the same API. f727b28
    • Does not implement setMaxListeners or its features. tmi.js called this.setMaxListeners(0) in the constructor anyways so almost no one was probably using it.

Removed

  • Removed dependency on node-fetch. 8e4970b
  • Removed ritual and hosting code, as per Twitch. 2852190 748bd92

Changes

  • Updated ws to ^8.17.1 from 8.2.0. cf5ab00 3e6e096
  • The option identity.username was removed because it's not needed to authenticate. identity.password is still expected as either a string or a function that returns string | Promise<string>. 73127e1 66c5800
    • The anonymous username will always be "justinfan123456" instead of random numbers.
  • New reward types for the redeem event. 3216180
client.on('redeem', (channel: string, username: string, rewardType: string, tags: PrivmsgTags, message: string) => {
    switch(rewardType) {
        case 'highlighted-message':
        case 'skip-subs-mode-message':
        // *New* Power-ups:
        case 'gigantified-emote-message': // Big emote
        case 'animated-message': // Message effect
            break;
        default: // Like a custom reward ID or unknown, official reward type
            break;
    }
});
  • The say, action, and reply methods will now wait until Twitch responds. a389fc3
    • The return type will include the related Userstate tags meaning the client will have access to the ID of the message it sent (useful for deleting or replying to its own messages).
    • The original return type of client.say is Promise<[ channel: string, message: string ]> so the tags were added after for backwards compatibility. The self value is always true to mirror the message event, but it might be removed before publish.
    • I'm still working on behavior where the message is dropped, but it's still raced against a timeout that will result in throwing the string 'No response from Twitch.'. I would prefer this would be an Error, but some level of backwards compatibility means I probably won't change it just yet. I feel this could easily be a justified breaking change that betters the experience with this package.
const [ _channel, _message, tags, self ] = await client.say(channel, message);
console.log('Sent message ID', tags.id);

Additions

  • The build process was changed to use esbuild. 881f9e0
    • Browser builds are included in the repository and eventually on npm allowing for usage through services like unpkg.com.
  • Added the reply method. 6b6d529
client.on('message', (channel, tags, message, self) => {
    if(self) return;
    if(message.toLowerCase() === 'hi') {
        const parentMessageId = tags.id;
        client.reply(channel, 'Hello', parentMessageId);
    }
});
  • Added the userstate event. Emitted on joining a channel and after every message sent except for when the message is dropped (AutoMod, etc.). 6f0a2b9
/** @see https://dev.twitch.tv/docs/irc/tags/#userstate-tags */
interface UserstateTags {
    'badge-info': Record<string, string>;
    'badge-info-raw': string;
    badges: Record<string, string>;
    'badges-raw': string;
    color: string;
    'client-nonce': string;
    'display-name': string;
    'emote-sets': string;
    id: string;
    mod: boolean;
    subscriber: boolean;
    turbo: boolean;
    'user-type': '' | 'admin' | 'global_mod' | 'staff';
    username: string;
}
client.on('userstate', (channel: string, tags: UserstateTags) => {});

Other changes can be seen here, as linked previously.

Other possible changes

This is an opportunity to make big changes to tmi.js.

Breaking changes

  • Alternate badge parsing. Currently the way badges are parsed is strange and not necessarily predictable with a glance. This might include a switch to camelCase keys everywhere.
  • Include types instead of relying on DefinitelyTyped (@types/tmi.js).
  • Use Error instead of throwing strings (i.e. reject('No response from Twitch.') that exists in several locations).
  • Change the message event for self messages to also wait for the USERSTATE command response. This would allow for it to have the correct message ID.

Changes

  • Include the client-nonce value in the message event for self messages.
  • Remove "self" from client.say return type (currently Promise<[ channel: string, message: string, tags: UserstateTags, self: true ]>). This is only part of v1.9.0-wip and it's not necessary to be included because it can be assumed.

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

No branches or pull requests

2 participants