emotesjs 0.0.16 → 0.0.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/README.md +38 -0
  2. package/index.js +1 -115
  3. package/package.json +31 -25
package/README.md ADDED
@@ -0,0 +1,38 @@
1
+ ![banner](.github/images/banner.png)
2
+
3
+ # EmotesJS
4
+
5
+ Fast, dependency free, and responsive 7TV inline emotes parse
6
+
7
+ ## Usage
8
+
9
+ ### Installation
10
+ ```sh
11
+ pnpm i emotesjs
12
+ ```
13
+
14
+ ### Parsing
15
+ ```js
16
+ import { EmotesJS } from 'emotesjs'
17
+
18
+ let emotes = new EmotesJS({ channelId: 123456, colon: false, height: '1.65rem', format: 'WEBP' })
19
+
20
+ // optional - once fetched, the emotes will be cached in memory
21
+ await emotes.isLoading
22
+
23
+ let html = emotes.parse('this is pretty Pog')
24
+
25
+ console.log(html)
26
+ // this is pretty <img srcset="https://cdn.7tv.app/emote/01EZTCN91800012PTN006Q50PR/4x.webp 128w, https://cdn.7tv.app/emote/01EZTCN91800012PTN006Q50PR/3x.webp 96w, https://cdn.7tv.app/emote/01EZTCN91800012PTN006Q50PR/2x.webp 64w, https://cdn.7tv.app/emote/01EZTCN91800012PTN006Q50PR/1x.webp 32w, " alt="Pog" style="height:1.65rem"/>
27
+ ```
28
+
29
+ ## Configuration
30
+
31
+ ```js
32
+ new EmotesJS({
33
+ channelId: 123456, // twitch channel id (or user id) to load the emotes
34
+ colon: false, // if true, the string must start with : e.g. :Pog
35
+ height: '1.65rem', // the element <img> height
36
+ format: 'WEBP' // or AVIF
37
+ })
38
+ ```
package/index.js CHANGED
@@ -1,115 +1 @@
1
- class EmotesJS {
2
- cachedEmotes = new Map()
3
- isReady = false
4
- isLoading = Promise.resolve()
5
- channelId = 0
6
- requireColon = true
7
- height = "1.65rem"
8
- format = "WEBP"
9
- allowedOrigins = "https://cdn.7tv.app"
10
- static instance
11
-
12
- constructor(opts) {
13
- if (EmotesJS.instance) {
14
- return EmotesJS.instance
15
- }
16
-
17
- if (opts) {
18
- this.channelId = opts.channelId
19
- this.requireColon = opts.requireColon
20
- this.height = opts.height || this.height
21
- this.format = opts.format || this.format
22
- }
23
-
24
- this.isLoading = this.load()
25
- EmotesJS.instance = this
26
- }
27
-
28
- async load() {
29
- let globalProm = fetch("https://7tv.io/v3/emote-sets/global").then(async r => {
30
- if (r.ok) {
31
- return r.json()
32
- }
33
-
34
- throw new Error("fetch unsuccessful")
35
- })
36
-
37
- let chProm = fetch("https://7tv.io/v3/users/twitch/" + this.channelId).then(async r => {
38
- if (r.ok) {
39
- return r.json()
40
- }
41
-
42
- throw new Error("fetch unsuccessful")
43
- })
44
-
45
- let [global, ch] = await Promise.allSettled([globalProm, chProm])
46
-
47
- let rawEmotes = []
48
-
49
- if (ch.status === "fulfilled") {
50
- rawEmotes.push(...ch.value.emote_set.emotes)
51
- }
52
-
53
- if (global.status === "fulfilled") {
54
- rawEmotes.push(...global.value.emotes)
55
- }
56
-
57
- for (let emote of rawEmotes) {
58
- let name = emote.data.name
59
- let url = `https:${emote.data.host.url}`
60
-
61
- if (!url.includes(this.allowedOrigins)) {
62
- continue
63
- }
64
-
65
- let files = emote.data.host.files.filter(x => x.format === this.format)
66
- let srcset = files.reduce((acc, curr) => `${url}/${curr.name} ${curr.width}w, ${acc}`, '')
67
- let elementString = `<img srcset="${srcset}" alt="${name}" style="height:${this.height}"/>`
68
-
69
- this.cachedEmotes.set(name, elementString)
70
- }
71
-
72
- this.isReady = true
73
- }
74
-
75
- parse(text) {
76
- if (!text || !this.isReady) {
77
- console.log('emotes not ready')
78
- return text
79
- }
80
-
81
- if (this.isReady && this.cachedEmotes.size === 0) {
82
- console.log('no emotes loaded')
83
- return text
84
- }
85
-
86
- let words = text.split(' ')
87
-
88
- let fullText = ''
89
- for (let i = 0; i < words.length; i++) {
90
- let word = words[i]
91
-
92
-
93
- if (this.requireColon && !word.startsWith(":")) {
94
- fullText += word + " "
95
- continue
96
- }
97
-
98
- let wordKey = word.replaceAll(':', '')
99
- let emote = this.cachedEmotes.get(wordKey)
100
-
101
- if (emote) {
102
- fullText += emote + ' '
103
- continue;
104
- }
105
-
106
- fullText += word + " "
107
- }
108
-
109
- return fullText.trim()
110
- }
111
-
112
- }
113
-
114
- module.exports.EmotesJS = EmotesJS
115
-
1
+ class EmotesJS{#cachedEmotes=new Map;#isReady=false;#colon=true;#height="1.65rem";#format="WEBP";#allowedOrigins="https://cdn.7tv.app";total=0;channelId=0;isLoading=Promise.resolve();static instance;constructor(opts){if(EmotesJS.instance&&EmotesJS.instance.channelId!==0){return EmotesJS.instance}if(opts){this.channelId=opts.channelId;this.#colon=opts.colon;this.#colon||=false;this.#height=opts.height||this.#height;this.#format=opts.format||this.#format}this.isLoading=this.load();EmotesJS.instance=this}async load(){let globalProm=fetch("https://7tv.io/v3/emote-sets/global").then(async r=>{if(r.ok){return r.json()}throw new Error("fetch unsuccessful")});let chProm=fetch("https://7tv.io/v3/users/twitch/"+this.channelId).then(async r=>{if(r.ok){return r.json()}throw new Error("fetch unsuccessful")});let[global,ch]=await Promise.allSettled([globalProm,chProm]);let rawEmotes=[];if(ch.status==="fulfilled"){rawEmotes.push(...ch.value.emote_set.emotes)}if(global.status==="fulfilled"){rawEmotes.push(...global.value.emotes)}for(let emote of rawEmotes){let name=emote.data.name;let url=`https:${emote.data.host.url}`;if(!url.includes(this.#allowedOrigins)){continue}let files=emote.data.host.files.filter(x=>x.format===this.#format);let srcset=files.reduce((acc,curr)=>`${url}/${curr.name} ${curr.width}w, ${acc}`,"");let elementString=`<img srcset="${srcset}" alt="${name}" style="height:${this.#height}"/>`;this.#cachedEmotes.set(name,elementString)}this.total=this.#cachedEmotes.size;this.#isReady=true}parse(text){if(!text||!this.#isReady){console.log("emotes not ready");return text}if(this.#isReady&&this.#cachedEmotes.size===0){console.log("no emotes loaded");return text}let words=text.split(" ");let fullText="";for(let i=0;i<words.length;i++){let word=words[i];if(this.#colon&&!word.startsWith(":")){fullText+=word+" ";continue}let wordKey=word.replaceAll(":","");let emote=this.#cachedEmotes.get(wordKey);if(emote){fullText+=emote+" ";continue}fullText+=word+" "}return fullText.trim()}}module.exports.EmotesJS=EmotesJS;
package/package.json CHANGED
@@ -1,26 +1,32 @@
1
1
  {
2
- "name": "emotesjs",
3
- "description": "",
4
- "version": "0.0.16",
5
- "license": "MIT",
6
- "author": {
7
- "name": "darckfast"
8
- },
9
- "engines": {
10
- "node": ">=22"
11
- },
12
- "files": [
13
- "index.js"
14
- ],
15
- "main": "index.js",
16
- "repository": {
17
- "type": "git",
18
- "url": "git://github.com/darckfast/emotesjs.git"
19
- },
20
- "keywords": [
21
- "twitch",
22
- "7tv",
23
- "emotes"
24
- ],
25
- "scripts": {}
26
- }
2
+ "name": "emotesjs",
3
+ "description": "",
4
+ "version": "0.0.19",
5
+ "license": "MIT",
6
+ "author": {
7
+ "name": "darckfast"
8
+ },
9
+ "engines": {
10
+ "node": ">=22"
11
+ },
12
+ "files": [
13
+ "index.js"
14
+ ],
15
+ "main": "index.js",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "git://github.com/darckfast/emotesjs.git"
19
+ },
20
+ "keywords": [
21
+ "twitch",
22
+ "7tv",
23
+ "emotes"
24
+ ],
25
+ "devDependencies": {
26
+ "terser": "^5.43.1",
27
+ "vitest": "^3.2.4"
28
+ },
29
+ "scripts": {
30
+ "test": "vitest run"
31
+ }
32
+ }