@roots/bud-client 0.0.0

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 (77) hide show
  1. package/LICENSE.md +19 -0
  2. package/README.md +77 -0
  3. package/lib/hot/client.d.ts +6 -0
  4. package/lib/hot/client.d.ts.map +1 -0
  5. package/lib/hot/client.js +143 -0
  6. package/lib/hot/components/index.d.ts +2 -0
  7. package/lib/hot/components/index.d.ts.map +1 -0
  8. package/lib/hot/components/index.js +32 -0
  9. package/lib/hot/components/indicator/index.d.ts +4 -0
  10. package/lib/hot/components/indicator/index.d.ts.map +1 -0
  11. package/lib/hot/components/indicator/index.js +17 -0
  12. package/lib/hot/components/indicator/indicator.component.d.ts +84 -0
  13. package/lib/hot/components/indicator/indicator.component.d.ts.map +1 -0
  14. package/lib/hot/components/indicator/indicator.component.js +175 -0
  15. package/lib/hot/components/indicator/indicator.controller.d.ts +45 -0
  16. package/lib/hot/components/indicator/indicator.controller.d.ts.map +1 -0
  17. package/lib/hot/components/indicator/indicator.controller.js +54 -0
  18. package/lib/hot/components/indicator/indicator.pulse.d.ts +9 -0
  19. package/lib/hot/components/indicator/indicator.pulse.d.ts.map +1 -0
  20. package/lib/hot/components/indicator/indicator.pulse.js +36 -0
  21. package/lib/hot/components/overlay/index.d.ts +4 -0
  22. package/lib/hot/components/overlay/index.d.ts.map +1 -0
  23. package/lib/hot/components/overlay/index.js +17 -0
  24. package/lib/hot/components/overlay/overlay.component.d.ts +20 -0
  25. package/lib/hot/components/overlay/overlay.component.d.ts.map +1 -0
  26. package/lib/hot/components/overlay/overlay.component.js +146 -0
  27. package/lib/hot/components/overlay/overlay.controller.d.ts +46 -0
  28. package/lib/hot/components/overlay/overlay.controller.d.ts.map +1 -0
  29. package/lib/hot/components/overlay/overlay.controller.js +70 -0
  30. package/lib/hot/events.d.ts +98 -0
  31. package/lib/hot/events.d.ts.map +1 -0
  32. package/lib/hot/events.js +89 -0
  33. package/lib/hot/index.cjs +5 -0
  34. package/lib/hot/index.d.cts +2 -0
  35. package/lib/hot/index.d.cts.map +1 -0
  36. package/lib/hot/index.d.mts +2 -0
  37. package/lib/hot/index.d.mts.map +1 -0
  38. package/lib/hot/index.mjs +17 -0
  39. package/lib/hot/log.d.ts +11 -0
  40. package/lib/hot/log.d.ts.map +1 -0
  41. package/lib/hot/log.js +37 -0
  42. package/lib/hot/options.d.ts +17 -0
  43. package/lib/hot/options.d.ts.map +1 -0
  44. package/lib/hot/options.js +33 -0
  45. package/lib/index.cjs +3 -0
  46. package/lib/index.d.cts +13 -0
  47. package/lib/index.d.cts.map +1 -0
  48. package/lib/index.d.mts +13 -0
  49. package/lib/index.d.mts.map +1 -0
  50. package/lib/index.mjs +3 -0
  51. package/lib/intercept/index.d.ts +3 -0
  52. package/lib/intercept/index.d.ts.map +1 -0
  53. package/lib/intercept/index.js +18 -0
  54. package/lib/intercept/proxy-click-interceptor.d.ts +2 -0
  55. package/lib/intercept/proxy-click-interceptor.d.ts.map +1 -0
  56. package/lib/intercept/proxy-click-interceptor.js +26 -0
  57. package/package.json +79 -0
  58. package/src/hot/client.test.ts +78 -0
  59. package/src/hot/client.ts +156 -0
  60. package/src/hot/components/index.ts +33 -0
  61. package/src/hot/components/indicator/index.ts +11 -0
  62. package/src/hot/components/indicator/indicator.component.ts +216 -0
  63. package/src/hot/components/indicator/indicator.controller.ts +76 -0
  64. package/src/hot/components/indicator/indicator.pulse.ts +43 -0
  65. package/src/hot/components/overlay/index.ts +12 -0
  66. package/src/hot/components/overlay/overlay.component.ts +165 -0
  67. package/src/hot/components/overlay/overlay.controller.ts +86 -0
  68. package/src/hot/events.ts +93 -0
  69. package/src/hot/index.cts +7 -0
  70. package/src/hot/index.mts +9 -0
  71. package/src/hot/log.ts +42 -0
  72. package/src/hot/options.ts +40 -0
  73. package/src/index.cts +16 -0
  74. package/src/index.mts +16 -0
  75. package/src/intercept/index.ts +33 -0
  76. package/src/intercept/proxy-click-interceptor.ts +18 -0
  77. package/src/types/index.d.ts +54 -0
@@ -0,0 +1,216 @@
1
+ import {pulse} from './indicator.pulse.js'
2
+
3
+ /**
4
+ * Indicator web component
5
+ * @public
6
+ */
7
+ export class Component extends HTMLElement {
8
+ /**
9
+ * Has component rendered
10
+ * @public
11
+ */
12
+ public rendered: boolean
13
+
14
+ /**
15
+ * Component name
16
+ * @public
17
+ */
18
+ public name: string = `bud-activity-indicator`
19
+
20
+ /**
21
+ * Root div querySelector selector
22
+ * @public
23
+ */
24
+ public get selector() {
25
+ return `.${this.name}`
26
+ }
27
+
28
+ /**
29
+ * Timer
30
+ * @public
31
+ */
32
+ public hideTimeout: NodeJS.Timer
33
+
34
+ /**
35
+ * Get accessor: has errors
36
+ * @public
37
+ */
38
+ public get hasErrors(): boolean {
39
+ return this.getAttribute(`has-errors`) == `true`
40
+ }
41
+
42
+ /**
43
+ * Get accessor: has warnings
44
+ * @public
45
+ */
46
+ public get hasWarnings(): boolean {
47
+ return this.getAttribute(`has-warnings`) == `true`
48
+ }
49
+
50
+ /**
51
+ * Status indicator colors
52
+ * @public
53
+ */
54
+ public colors: Record<string, [number, number, number, number]> = {
55
+ success: [4, 120, 87, 1],
56
+ error: [220, 38, 38, 1],
57
+ warn: [252, 211, 77, 1],
58
+ pending: [59, 130, 246, 1],
59
+ }
60
+
61
+ /**
62
+ * Class constructor
63
+ * @public
64
+ */
65
+ public constructor() {
66
+ super()
67
+ this.renderShadow()
68
+ }
69
+
70
+ /**
71
+ * Render status indicator
72
+ * @public
73
+ */
74
+ public renderShadow() {
75
+ const container = document.createElement(`div`)
76
+ container.classList.add(this.name)
77
+ container.innerHTML = `
78
+ <style>
79
+ .bud-activity-indicator {
80
+ position: fixed;
81
+ width: 10px;
82
+ height: 10px;
83
+ left: 10px;
84
+ bottom: 10px;
85
+ z-index: 9999;
86
+ margin: 5px;
87
+ padding: 5px;
88
+ -webkit-transition:
89
+ all .6s ease-in-out,
90
+ transition:
91
+ all .6s ease-in-out;
92
+ animation-fill-mode: forwards;
93
+ pointer-events: none;
94
+ border-radius: 50%;
95
+ transform: scale(0);
96
+ opacity: 0;
97
+ }
98
+
99
+ .show {
100
+ opacity: 1;
101
+ background-color: rgba(255, 255, 255, 1);
102
+ transform: scale(1);
103
+ transition:
104
+ all .6s ease-in-out;
105
+ }
106
+
107
+ ${pulse(`success`, this.colors.success)}
108
+ ${pulse(`error`, this.colors.error)}
109
+ ${pulse(`warning`, this.colors.warn)}
110
+ ${pulse(`pending`, this.colors.pending)}
111
+
112
+ </style>
113
+ `
114
+
115
+ this.attachShadow({mode: `open`}).appendChild(container)
116
+ }
117
+
118
+ /**
119
+ * Show status indicator
120
+ * @public
121
+ */
122
+ public show() {
123
+ this.hideTimeout && clearTimeout(this.hideTimeout)
124
+ this.shadowRoot.querySelector(this.selector).classList.add(`show`)
125
+ }
126
+
127
+ /**
128
+ * Hide status indicator
129
+ */
130
+ public hide() {
131
+ this.hideTimeout = setTimeout(() => {
132
+ this.shadowRoot.querySelector(this.selector).classList.remove(`show`)
133
+ }, 2000)
134
+ }
135
+
136
+ /**
137
+ * Status is pending
138
+ * @public
139
+ */
140
+ public onPending() {
141
+ this.show()
142
+
143
+ this.shadowRoot
144
+ .querySelector(this.selector)
145
+ .classList.remove(`error`, `warning`, `success`)
146
+
147
+ this.shadowRoot.querySelector(this.selector).classList.add(`pending`)
148
+
149
+ this.hide()
150
+ }
151
+
152
+ /**
153
+ * Status is success
154
+ * @public
155
+ */
156
+ public onSuccess() {
157
+ this.show()
158
+
159
+ this.shadowRoot
160
+ .querySelector(this.selector)
161
+ .classList.remove(`error`, `warning`, `pending`)
162
+
163
+ this.shadowRoot.querySelector(this.selector).classList.add(`success`)
164
+
165
+ this.hide()
166
+ }
167
+
168
+ /**
169
+ * Status is error
170
+ * @public
171
+ */
172
+ public onError() {
173
+ this.show()
174
+
175
+ this.shadowRoot
176
+ .querySelector(this.selector)
177
+ .classList.remove(`warning`, `success`, `pending`)
178
+ this.shadowRoot.querySelector(this.selector).classList.add(`error`)
179
+ }
180
+
181
+ /**
182
+ * Status is warning
183
+ * @public
184
+ */
185
+ public onWarning() {
186
+ this.show()
187
+
188
+ this.shadowRoot
189
+ .querySelector(this.selector)
190
+ .classList.remove(`error`, `success`, `pending`)
191
+
192
+ this.shadowRoot.querySelector(this.selector).classList.add(`warning`)
193
+ }
194
+
195
+ public static get observedAttributes() {
196
+ return [`has-errors`, `has-warnings`, `action`]
197
+ }
198
+
199
+ public attributeChangedCallback() {
200
+ if (this.hasAttribute(`has-errors`)) return this.onError()
201
+ if (this.hasAttribute(`has-warnings`)) return this.onWarning()
202
+
203
+ if (
204
+ !this.hasAttribute(`has-errors`) &&
205
+ !this.hasAttribute(`has-warnings`) &&
206
+ this.getAttribute(`action`) === `built`
207
+ )
208
+ return this.onSuccess()
209
+
210
+ if (
211
+ this.getAttribute(`action`) == `building` ||
212
+ this.getAttribute(`action`) == `sync`
213
+ )
214
+ return this.onPending()
215
+ }
216
+ }
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Activity indicator controller
3
+ * @public
4
+ */
5
+ export class Controller {
6
+ /**
7
+ * DOM node
8
+ * @public
9
+ */
10
+ public node: HTMLElement
11
+
12
+ /**
13
+ * Active WHM payload
14
+ * @public
15
+ */
16
+ public payload = null
17
+
18
+ /**
19
+ * Timer handler
20
+ * @public
21
+ */
22
+ public timer: NodeJS.Timeout
23
+
24
+ /**
25
+ * Initialization
26
+ * @public
27
+ */
28
+ public constructor() {
29
+ this.node = document.createElement(`bud-activity-indicator`)
30
+ this.update = this.update.bind(this)
31
+ }
32
+
33
+ /**
34
+ * Append `bud-error` element to the DOM
35
+ *
36
+ * @public
37
+ */
38
+ public addNode() {
39
+ if (document.body.querySelector(`bud-activity-indicator`)) {
40
+ if (typeof this.timer.unref === `function`) this.timer.unref()
41
+ this.removeNode()
42
+ }
43
+
44
+ document.body?.appendChild(this.node)
45
+ this.timer = setTimeout(this.removeNode, 3000)
46
+ }
47
+
48
+ /**
49
+ * Remove `bud-error` element from the DOM (if present)
50
+ *
51
+ * @public
52
+ */
53
+ public removeNode() {
54
+ document.body.querySelector(`bud-activity-indicator`)?.remove()
55
+ }
56
+
57
+ /**
58
+ * Update activity indicator
59
+ * @public
60
+ */
61
+ public update(payload: Payload) {
62
+ this.node.toggleAttribute(
63
+ `has-errors`,
64
+ payload.errors?.length ? true : false,
65
+ )
66
+
67
+ this.node.toggleAttribute(
68
+ `has-warnings`,
69
+ payload.warnings?.length ? true : false,
70
+ )
71
+
72
+ this.node.setAttribute(`action`, payload.action)
73
+
74
+ this.addNode()
75
+ }
76
+ }
@@ -0,0 +1,43 @@
1
+ export interface pulse {
2
+ (name: string, color: [number, number, number]): string
3
+ }
4
+
5
+ /**
6
+ * CSS animation for reload indicator
7
+ * @public
8
+ */
9
+ export const pulse = (
10
+ name: string,
11
+ color: [number, number, number, number],
12
+ ): string => `
13
+ .${name} {
14
+ box-shadow: 0 0 0 0 rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3]});
15
+ animation: ${name}__pulse 2s infinite;
16
+ transition: all 0.4s ease-in-out;
17
+ }
18
+
19
+ .${name}:not(.show) {
20
+ background-color: rgba(${color[0]}, ${color[1]}, ${color[2]}, 0);
21
+ }
22
+
23
+ .${name}.show {
24
+ background-color: rgba(${color[0]}, ${color[1]}, ${color[2]}, ${color[3]});
25
+ }
26
+
27
+ @keyframes ${name}__pulse {
28
+ 0% {
29
+ transform: scale(0.95);
30
+ box-shadow: 0 0 0 0 rgba(${color[0]}, ${color[1]}, ${color[2]}, 0.7);
31
+ }
32
+
33
+ 70% {
34
+ transform: scale(1);
35
+ box-shadow: 0 0 0 10px rgba(${color[0]}, ${color[1]}, ${color[2]}, 0);
36
+ }
37
+
38
+ 100% {
39
+ transform: scale(0.95);
40
+ box-shadow: 0 0 0 0 rgba(${color[0]}, ${color[1]}, ${color[2]}, 0);
41
+ }
42
+ }
43
+ `
@@ -0,0 +1,12 @@
1
+ import {Component} from './overlay.component.js'
2
+ import {Controller} from './overlay.controller.js'
3
+
4
+ export const make = async (): Promise<{
5
+ update: (data: Payload) => void
6
+ }> => {
7
+ if (customElements.get(`bud-error`)) return
8
+
9
+ customElements.define(`bud-error`, Component)
10
+
11
+ return new Controller()
12
+ }
@@ -0,0 +1,165 @@
1
+ /**
2
+ * Component container
3
+ */
4
+ export class Component extends HTMLElement {
5
+ public name: string = `bud-overlay`
6
+
7
+ /**
8
+ * WHM payload
9
+ *
10
+ * @public
11
+ */
12
+ public payload: any
13
+
14
+ public documentBodyStyle: any
15
+
16
+ public get message() {
17
+ return this.getAttribute(`message`)
18
+ }
19
+
20
+ public constructor() {
21
+ super()
22
+ this.renderShadow()
23
+ }
24
+
25
+ public renderShadow(): void {
26
+ const container = document.createElement(`div`)
27
+ container.classList.add(`overlay`)
28
+ container.innerHTML = `
29
+ <style>
30
+ .overlay {
31
+ width: 100vw;
32
+ backdrop-filter: blur(10px);
33
+ display: flex;
34
+ height: 100vh;
35
+ border-top: 2px solid transparent;
36
+ overflow-x: hidden;
37
+ overflow-y: scroll;
38
+ position: absolute;
39
+ top: -1000px;
40
+ left: 0;
41
+ right: 0;
42
+ bottom: 0;
43
+ opacity: 0;
44
+ transition: opacity 0.2s ease-in-out, border 0.4s ease-in-out;
45
+ justify-content: center;
46
+ }
47
+
48
+ .visible {
49
+ position: fixed;
50
+ top: 0;
51
+ z-index: 9998;
52
+ opacity: 1;
53
+ border-top: 5px solid red;
54
+ transition: opacity 0.2s ease-in-out, border 0.4s ease-in-out;
55
+ max-width: 100vw;
56
+ }
57
+
58
+ .messages {
59
+ background-color: white;
60
+ border-radius: 5px;
61
+ filter: drop-shadow(0 1px 2px rgb(0 0 0 / 0.1)) drop-shadow(0 1px 1px rgb(0 0 0 / 0.06));
62
+ display: flex;
63
+ align-self: center;
64
+ width: 800px;
65
+ max-width: 90vw;
66
+ margin-left: auto;
67
+ margin-right: auto;
68
+ flex-direction: column;
69
+ flex-wrap: wrap;
70
+ align-items: center;
71
+ align-content: center;
72
+ padding: 2rem 2rem 0rem 2rem;
73
+ }
74
+
75
+ .visible .messages > div {
76
+ position: relative;
77
+ top: 0;
78
+ opacity: 1;
79
+ transition: all: 0.2s ease-in-out;
80
+ }
81
+
82
+ .messages > div {
83
+ position: relative;
84
+ top: 20px;
85
+ opacity: 0;
86
+ transition: all: 0.2s ease-in-out;
87
+ align-items: center;
88
+ align-content: center;
89
+ color: rgba(0, 0, 0, 0.87);
90
+ flex-direction: column;
91
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol";
92
+ padding: 0rem 2rem 2rem 2rem;
93
+ width: 100%;
94
+ max-width:95vw;
95
+ }
96
+
97
+ .messages > div > pre {
98
+ font-weight: 300;
99
+ font-size: 0.8rem;
100
+ overflow-x: scroll;
101
+ }
102
+
103
+ pre {
104
+ background: #303030;
105
+ color: #f1f1f1;
106
+ padding: 10px 16px;
107
+ border-radius: 2px;
108
+ border-top: 4px solid #dd0303;
109
+ -moz-box-shadow: inset 0 0 10px #000;
110
+ box-shadow: inset 0 0 10px #000;
111
+ counter-reset: line;
112
+ }
113
+
114
+ pre span {
115
+ display: block;
116
+ line-height: 1.5rem;
117
+ }
118
+
119
+ pre span:before {
120
+ counter-increment: line;
121
+ content: counter(line);
122
+ display: inline-block;
123
+ border-right: 1px solid #ddd;
124
+ padding: 0 .5em;
125
+ margin-right: .5em;
126
+ color: #888;
127
+ width: 30px;
128
+ }
129
+ </style>
130
+ <div class="messages"></div>
131
+ `
132
+
133
+ this.attachShadow({mode: `open`}).appendChild(container)
134
+ }
135
+
136
+ public static get observedAttributes() {
137
+ return [`message`]
138
+ }
139
+
140
+ public attributeChangedCallback() {
141
+ if (!this.documentBodyStyle)
142
+ this.documentBodyStyle = document.body?.style
143
+
144
+ if (this.getAttribute(`message`)) {
145
+ document.body.style.overflow = `hidden`
146
+
147
+ this.shadowRoot.querySelector(`.overlay`).classList.add(`visible`)
148
+
149
+ this.shadowRoot.querySelector(`.messages`).innerHTML =
150
+ this.getAttribute(`message`)
151
+
152
+ return
153
+ }
154
+
155
+ if (this.documentBodyStyle?.overflow && document?.body?.style) {
156
+ document.body.style.overflow = this.documentBodyStyle.overflow
157
+ }
158
+
159
+ this.shadowRoot.querySelector(`.overlay`).classList.remove(`visible`)
160
+ }
161
+
162
+ public connectedCallback() {
163
+ if (document.body?.style) this.documentBodyStyle = document.body.style
164
+ }
165
+ }
@@ -0,0 +1,86 @@
1
+ const ansiPattern = [
2
+ `[\\u001B\\u009B][[\\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]+)*|[a-zA-Z\\d]+(?:;[-a-zA-Z\\d\\/#&.:=?%@~_]*)*)?\\u0007)`,
3
+ `(?:(?:\\d{1,4}(?:;\\d{0,4})*)?[\\dA-PR-TZcf-ntqry=><~]))`,
4
+ ].join(`|`)
5
+
6
+ const stripAnsi = (body: string) =>
7
+ body?.replace?.(new RegExp(ansiPattern, `g`), ``) ?? body
8
+
9
+ /**
10
+ * Overlay controller
11
+ * @public
12
+ */
13
+ export class Controller {
14
+ /**
15
+ * Element
16
+ * @public
17
+ */
18
+ public element: HTMLElement
19
+
20
+ /**
21
+ * HMR update
22
+ * @public
23
+ */
24
+ public payload: Payload
25
+
26
+ /**
27
+ * Formatted error message
28
+ * @public
29
+ */
30
+ public get message(): string {
31
+ return this.payload.errors?.reduce((a, c) => {
32
+ const msg = c?.message ?? c?.error ?? c
33
+ if (!msg) return a
34
+ return `${a}
35
+ <div>
36
+ <pre>${stripAnsi(msg)}</pre>
37
+ </div>`
38
+ }, ``)
39
+ }
40
+
41
+ /**
42
+ * Class constructor
43
+ *
44
+ * @public
45
+ */
46
+ public constructor() {
47
+ this.update = this.update.bind(this)
48
+ this.element = document.createElement(`bud-error`)
49
+ }
50
+
51
+ /**
52
+ * Append `bud-error` element to the DOM
53
+ *
54
+ * @public
55
+ */
56
+ public createError() {
57
+ !document.body.querySelector(`bud-error`) &&
58
+ document.body?.appendChild(this.element)
59
+ }
60
+
61
+ /**
62
+ * Remove `bud-error` element from the DOM (if present)
63
+ *
64
+ * @public
65
+ */
66
+ public removeError() {
67
+ document.body.querySelector(`bud-error`)?.remove()
68
+ }
69
+
70
+ /**
71
+ * Update DOM
72
+ *
73
+ * @public
74
+ */
75
+ public update(payload: Payload): void {
76
+ this.payload = payload
77
+
78
+ this.element.setAttribute(`message`, this.message ?? ``)
79
+
80
+ if (this.payload.errors?.length > 0) {
81
+ return this.createError()
82
+ }
83
+
84
+ this.removeError()
85
+ }
86
+ }
@@ -0,0 +1,93 @@
1
+ /* eslint-disable no-console */
2
+
3
+ export const injectEvents = (
4
+ eventSource: new (path: string) => EventSource,
5
+ ) => {
6
+ /**
7
+ * EventSource wrapper
8
+ *
9
+ * @remarks
10
+ * wraps EventSource in a function to allow for
11
+ * mocking in tests
12
+ *
13
+ * @public
14
+ */
15
+ return class Events extends eventSource {
16
+ /**
17
+ * Registered listeners
18
+ *
19
+ * @public
20
+ */
21
+ public listeners: Set<Listener> = new Set<Listener>()
22
+
23
+ /**
24
+ * Class constructor
25
+ *
26
+ * @remarks
27
+ * Singleton interface, so this is private.
28
+ *
29
+ * @public
30
+ */
31
+ private constructor(
32
+ public options: Partial<Options> & {name: string; path: string},
33
+ ) {
34
+ super(options.path)
35
+
36
+ this.onopen = this.onopen.bind(this)
37
+ this.onmessage = this.onmessage.bind(this)
38
+ this.addListener = this.addListener.bind(this)
39
+ }
40
+
41
+ /**
42
+ * Singleton constructor
43
+ *
44
+ * @public
45
+ */
46
+ public static make(
47
+ options: Partial<Options> & {name: string; path: string},
48
+ ): Events {
49
+ if (typeof window.bud.hmr[options.name] === `undefined`)
50
+ Object.assign(window.bud.hmr, {
51
+ [options.name]: new Events(options),
52
+ })
53
+
54
+ return window.bud.hmr[options.name]
55
+ }
56
+
57
+ /**
58
+ * EventSource `onopen` handler
59
+ * @public
60
+ */
61
+ public override onopen = function () {}
62
+
63
+ /**
64
+ * EventSource `onmessage` handler
65
+ * @public
66
+ */
67
+ public override onmessage = async function (payload: MessageEvent) {
68
+ if (!payload?.data || payload.data == `\uD83D\uDC93`) {
69
+ return
70
+ }
71
+
72
+ try {
73
+ const data = JSON.parse(payload.data)
74
+ if (!data) return
75
+
76
+ await Promise.all(
77
+ [...this.listeners].map(async listener => {
78
+ return await listener(data)
79
+ }),
80
+ )
81
+ } catch (ex) {}
82
+ }
83
+
84
+ /**
85
+ * EventSource `addMessageListener` handler
86
+ * @public
87
+ */
88
+ public addListener(listener: Listener): this {
89
+ this.listeners.add(listener)
90
+ return this
91
+ }
92
+ }
93
+ }
@@ -0,0 +1,7 @@
1
+ /* eslint-disable no-console */
2
+ /* global __resourceQuery */
3
+ /* global module */
4
+
5
+ import {client} from './client.js'
6
+
7
+ client(__resourceQuery, module.hot)
@@ -0,0 +1,9 @@
1
+ /* eslint-disable no-console */
2
+ /* global __resourceQuery */
3
+ /* global module */
4
+
5
+ ;(async () =>
6
+ await import(`./client.js`).then(
7
+ async module =>
8
+ await module.client(__resourceQuery, import.meta.webpackHot),
9
+ ))()