dsh-model-proxy-switch 0.0.0-stage → 1.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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +76 -2
  3. package/client.js +473 -0
  4. package/cordis.patch.yml +7 -0
  5. package/icon.svg +13 -0
  6. package/index.js +341 -0
  7. package/locale/en.json +25 -0
  8. package/locale/zh.json +25 -0
  9. package/package.json +55 -4
  10. package/vendor/http-proxy.js +542 -0
  11. package/vendor/node_modules/undici/LICENSE +21 -0
  12. package/vendor/node_modules/undici/README.md +741 -0
  13. package/vendor/node_modules/undici/docs/docs/api/Agent.md +84 -0
  14. package/vendor/node_modules/undici/docs/docs/api/BalancedPool.md +99 -0
  15. package/vendor/node_modules/undici/docs/docs/api/CacheStorage.md +30 -0
  16. package/vendor/node_modules/undici/docs/docs/api/CacheStore.md +164 -0
  17. package/vendor/node_modules/undici/docs/docs/api/Client.md +290 -0
  18. package/vendor/node_modules/undici/docs/docs/api/ClientStats.md +27 -0
  19. package/vendor/node_modules/undici/docs/docs/api/Connector.md +115 -0
  20. package/vendor/node_modules/undici/docs/docs/api/ContentType.md +57 -0
  21. package/vendor/node_modules/undici/docs/docs/api/Cookies.md +128 -0
  22. package/vendor/node_modules/undici/docs/docs/api/Debug.md +62 -0
  23. package/vendor/node_modules/undici/docs/docs/api/DiagnosticsChannel.md +317 -0
  24. package/vendor/node_modules/undici/docs/docs/api/Dispatcher.md +1393 -0
  25. package/vendor/node_modules/undici/docs/docs/api/EnvHttpProxyAgent.md +159 -0
  26. package/vendor/node_modules/undici/docs/docs/api/Errors.md +49 -0
  27. package/vendor/node_modules/undici/docs/docs/api/EventSource.md +45 -0
  28. package/vendor/node_modules/undici/docs/docs/api/Fetch.md +60 -0
  29. package/vendor/node_modules/undici/docs/docs/api/GlobalInstallation.md +139 -0
  30. package/vendor/node_modules/undici/docs/docs/api/H2CClient.md +263 -0
  31. package/vendor/node_modules/undici/docs/docs/api/MockAgent.md +603 -0
  32. package/vendor/node_modules/undici/docs/docs/api/MockCallHistory.md +197 -0
  33. package/vendor/node_modules/undici/docs/docs/api/MockCallHistoryLog.md +43 -0
  34. package/vendor/node_modules/undici/docs/docs/api/MockClient.md +81 -0
  35. package/vendor/node_modules/undici/docs/docs/api/MockErrors.md +12 -0
  36. package/vendor/node_modules/undici/docs/docs/api/MockPool.md +555 -0
  37. package/vendor/node_modules/undici/docs/docs/api/Pool.md +84 -0
  38. package/vendor/node_modules/undici/docs/docs/api/PoolStats.md +35 -0
  39. package/vendor/node_modules/undici/docs/docs/api/ProxyAgent.md +229 -0
  40. package/vendor/node_modules/undici/docs/docs/api/RedirectHandler.md +93 -0
  41. package/vendor/node_modules/undici/docs/docs/api/RetryAgent.md +50 -0
  42. package/vendor/node_modules/undici/docs/docs/api/RetryHandler.md +118 -0
  43. package/vendor/node_modules/undici/docs/docs/api/RoundRobinPool.md +145 -0
  44. package/vendor/node_modules/undici/docs/docs/api/SnapshotAgent.md +616 -0
  45. package/vendor/node_modules/undici/docs/docs/api/Socks5ProxyAgent.md +275 -0
  46. package/vendor/node_modules/undici/docs/docs/api/Util.md +25 -0
  47. package/vendor/node_modules/undici/docs/docs/api/WebSocket.md +141 -0
  48. package/vendor/node_modules/undici/docs/docs/api/api-lifecycle.md +91 -0
  49. package/vendor/node_modules/undici/docs/docs/best-practices/client-certificate.md +64 -0
  50. package/vendor/node_modules/undici/docs/docs/best-practices/crawling.md +58 -0
  51. package/vendor/node_modules/undici/docs/docs/best-practices/mocking-request.md +190 -0
  52. package/vendor/node_modules/undici/docs/docs/best-practices/proxy.md +127 -0
  53. package/vendor/node_modules/undici/docs/docs/best-practices/undici-vs-builtin-fetch.md +224 -0
  54. package/vendor/node_modules/undici/docs/docs/best-practices/writing-tests.md +63 -0
  55. package/vendor/node_modules/undici/index-fetch.js +65 -0
  56. package/vendor/node_modules/undici/index.d.ts +3 -0
  57. package/vendor/node_modules/undici/index.js +234 -0
  58. package/vendor/node_modules/undici/lib/api/abort-signal.js +59 -0
  59. package/vendor/node_modules/undici/lib/api/api-connect.js +110 -0
  60. package/vendor/node_modules/undici/lib/api/api-pipeline.js +252 -0
  61. package/vendor/node_modules/undici/lib/api/api-request.js +214 -0
  62. package/vendor/node_modules/undici/lib/api/api-stream.js +209 -0
  63. package/vendor/node_modules/undici/lib/api/api-upgrade.js +111 -0
  64. package/vendor/node_modules/undici/lib/api/index.js +7 -0
  65. package/vendor/node_modules/undici/lib/api/readable.js +580 -0
  66. package/vendor/node_modules/undici/lib/cache/memory-cache-store.js +279 -0
  67. package/vendor/node_modules/undici/lib/cache/sqlite-cache-store.js +467 -0
  68. package/vendor/node_modules/undici/lib/core/connect.js +159 -0
  69. package/vendor/node_modules/undici/lib/core/constants.js +143 -0
  70. package/vendor/node_modules/undici/lib/core/diagnostics.js +227 -0
  71. package/vendor/node_modules/undici/lib/core/errors.js +477 -0
  72. package/vendor/node_modules/undici/lib/core/request.js +485 -0
  73. package/vendor/node_modules/undici/lib/core/socks5-client.js +422 -0
  74. package/vendor/node_modules/undici/lib/core/socks5-utils.js +212 -0
  75. package/vendor/node_modules/undici/lib/core/symbols.js +76 -0
  76. package/vendor/node_modules/undici/lib/core/tree.js +160 -0
  77. package/vendor/node_modules/undici/lib/core/util.js +992 -0
  78. package/vendor/node_modules/undici/lib/dispatcher/agent.js +162 -0
  79. package/vendor/node_modules/undici/lib/dispatcher/balanced-pool.js +221 -0
  80. package/vendor/node_modules/undici/lib/dispatcher/client-h1.js +1744 -0
  81. package/vendor/node_modules/undici/lib/dispatcher/client-h2.js +1056 -0
  82. package/vendor/node_modules/undici/lib/dispatcher/client.js +669 -0
  83. package/vendor/node_modules/undici/lib/dispatcher/dispatcher-base.js +196 -0
  84. package/vendor/node_modules/undici/lib/dispatcher/dispatcher.js +48 -0
  85. package/vendor/node_modules/undici/lib/dispatcher/env-http-proxy-agent.js +146 -0
  86. package/vendor/node_modules/undici/lib/dispatcher/fixed-queue.js +135 -0
  87. package/vendor/node_modules/undici/lib/dispatcher/h2c-client.js +51 -0
  88. package/vendor/node_modules/undici/lib/dispatcher/pool-base.js +214 -0
  89. package/vendor/node_modules/undici/lib/dispatcher/pool.js +118 -0
  90. package/vendor/node_modules/undici/lib/dispatcher/proxy-agent.js +319 -0
  91. package/vendor/node_modules/undici/lib/dispatcher/retry-agent.js +35 -0
  92. package/vendor/node_modules/undici/lib/dispatcher/round-robin-pool.js +137 -0
  93. package/vendor/node_modules/undici/lib/dispatcher/socks5-proxy-agent.js +260 -0
  94. package/vendor/node_modules/undici/lib/encoding/index.js +33 -0
  95. package/vendor/node_modules/undici/lib/global.js +59 -0
  96. package/vendor/node_modules/undici/lib/handler/cache-handler.js +824 -0
  97. package/vendor/node_modules/undici/lib/handler/cache-revalidation-handler.js +124 -0
  98. package/vendor/node_modules/undici/lib/handler/decorator-handler.js +67 -0
  99. package/vendor/node_modules/undici/lib/handler/deduplication-handler.js +504 -0
  100. package/vendor/node_modules/undici/lib/handler/redirect-handler.js +245 -0
  101. package/vendor/node_modules/undici/lib/handler/retry-handler.js +504 -0
  102. package/vendor/node_modules/undici/lib/handler/unwrap-handler.js +106 -0
  103. package/vendor/node_modules/undici/lib/handler/wrap-handler.js +105 -0
  104. package/vendor/node_modules/undici/lib/interceptor/cache.js +621 -0
  105. package/vendor/node_modules/undici/lib/interceptor/decompress.js +561 -0
  106. package/vendor/node_modules/undici/lib/interceptor/deduplicate.js +117 -0
  107. package/vendor/node_modules/undici/lib/interceptor/dns.js +571 -0
  108. package/vendor/node_modules/undici/lib/interceptor/dump.js +99 -0
  109. package/vendor/node_modules/undici/lib/interceptor/redirect.js +21 -0
  110. package/vendor/node_modules/undici/lib/interceptor/response-error.js +95 -0
  111. package/vendor/node_modules/undici/lib/interceptor/retry.js +19 -0
  112. package/vendor/node_modules/undici/lib/llhttp/.gitkeep +0 -0
  113. package/vendor/node_modules/undici/lib/llhttp/constants.d.ts +195 -0
  114. package/vendor/node_modules/undici/lib/llhttp/constants.js +531 -0
  115. package/vendor/node_modules/undici/lib/llhttp/llhttp-wasm.js +15 -0
  116. package/vendor/node_modules/undici/lib/llhttp/llhttp_simd-wasm.js +15 -0
  117. package/vendor/node_modules/undici/lib/llhttp/utils.d.ts +2 -0
  118. package/vendor/node_modules/undici/lib/llhttp/utils.js +12 -0
  119. package/vendor/node_modules/undici/lib/mock/mock-agent.js +232 -0
  120. package/vendor/node_modules/undici/lib/mock/mock-call-history.js +248 -0
  121. package/vendor/node_modules/undici/lib/mock/mock-client.js +68 -0
  122. package/vendor/node_modules/undici/lib/mock/mock-errors.js +29 -0
  123. package/vendor/node_modules/undici/lib/mock/mock-interceptor.js +209 -0
  124. package/vendor/node_modules/undici/lib/mock/mock-pool.js +68 -0
  125. package/vendor/node_modules/undici/lib/mock/mock-symbols.js +32 -0
  126. package/vendor/node_modules/undici/lib/mock/mock-utils.js +486 -0
  127. package/vendor/node_modules/undici/lib/mock/pending-interceptors-formatter.js +43 -0
  128. package/vendor/node_modules/undici/lib/mock/snapshot-agent.js +353 -0
  129. package/vendor/node_modules/undici/lib/mock/snapshot-recorder.js +588 -0
  130. package/vendor/node_modules/undici/lib/mock/snapshot-utils.js +158 -0
  131. package/vendor/node_modules/undici/lib/util/cache.js +676 -0
  132. package/vendor/node_modules/undici/lib/util/date.js +670 -0
  133. package/vendor/node_modules/undici/lib/util/promise.js +28 -0
  134. package/vendor/node_modules/undici/lib/util/runtime-features.js +124 -0
  135. package/vendor/node_modules/undici/lib/util/stats.js +32 -0
  136. package/vendor/node_modules/undici/lib/util/timers.js +425 -0
  137. package/vendor/node_modules/undici/lib/web/cache/cache.js +864 -0
  138. package/vendor/node_modules/undici/lib/web/cache/cachestorage.js +152 -0
  139. package/vendor/node_modules/undici/lib/web/cache/util.js +45 -0
  140. package/vendor/node_modules/undici/lib/web/cookies/constants.js +12 -0
  141. package/vendor/node_modules/undici/lib/web/cookies/index.js +201 -0
  142. package/vendor/node_modules/undici/lib/web/cookies/parse.js +315 -0
  143. package/vendor/node_modules/undici/lib/web/cookies/util.js +371 -0
  144. package/vendor/node_modules/undici/lib/web/eventsource/eventsource-stream.js +575 -0
  145. package/vendor/node_modules/undici/lib/web/eventsource/eventsource.js +504 -0
  146. package/vendor/node_modules/undici/lib/web/eventsource/util.js +29 -0
  147. package/vendor/node_modules/undici/lib/web/fetch/LICENSE +21 -0
  148. package/vendor/node_modules/undici/lib/web/fetch/body.js +509 -0
  149. package/vendor/node_modules/undici/lib/web/fetch/constants.js +131 -0
  150. package/vendor/node_modules/undici/lib/web/fetch/data-url.js +596 -0
  151. package/vendor/node_modules/undici/lib/web/fetch/formdata-parser.js +586 -0
  152. package/vendor/node_modules/undici/lib/web/fetch/formdata.js +259 -0
  153. package/vendor/node_modules/undici/lib/web/fetch/global.js +40 -0
  154. package/vendor/node_modules/undici/lib/web/fetch/headers.js +719 -0
  155. package/vendor/node_modules/undici/lib/web/fetch/index.js +2413 -0
  156. package/vendor/node_modules/undici/lib/web/fetch/request.js +1115 -0
  157. package/vendor/node_modules/undici/lib/web/fetch/response.js +641 -0
  158. package/vendor/node_modules/undici/lib/web/fetch/util.js +1522 -0
  159. package/vendor/node_modules/undici/lib/web/infra/index.js +243 -0
  160. package/vendor/node_modules/undici/lib/web/subresource-integrity/Readme.md +9 -0
  161. package/vendor/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +307 -0
  162. package/vendor/node_modules/undici/lib/web/webidl/index.js +1006 -0
  163. package/vendor/node_modules/undici/lib/web/websocket/connection.js +339 -0
  164. package/vendor/node_modules/undici/lib/web/websocket/constants.js +126 -0
  165. package/vendor/node_modules/undici/lib/web/websocket/events.js +331 -0
  166. package/vendor/node_modules/undici/lib/web/websocket/frame.js +133 -0
  167. package/vendor/node_modules/undici/lib/web/websocket/permessage-deflate.js +105 -0
  168. package/vendor/node_modules/undici/lib/web/websocket/receiver.js +520 -0
  169. package/vendor/node_modules/undici/lib/web/websocket/sender.js +109 -0
  170. package/vendor/node_modules/undici/lib/web/websocket/stream/websocketerror.js +104 -0
  171. package/vendor/node_modules/undici/lib/web/websocket/stream/websocketstream.js +496 -0
  172. package/vendor/node_modules/undici/lib/web/websocket/util.js +347 -0
  173. package/vendor/node_modules/undici/lib/web/websocket/websocket.js +758 -0
  174. package/vendor/node_modules/undici/package.json +152 -0
  175. package/vendor/node_modules/undici/scripts/strip-comments.js +10 -0
  176. package/vendor/node_modules/undici/types/README.md +6 -0
  177. package/vendor/node_modules/undici/types/agent.d.ts +32 -0
  178. package/vendor/node_modules/undici/types/api.d.ts +43 -0
  179. package/vendor/node_modules/undici/types/balanced-pool.d.ts +30 -0
  180. package/vendor/node_modules/undici/types/cache-interceptor.d.ts +179 -0
  181. package/vendor/node_modules/undici/types/cache.d.ts +36 -0
  182. package/vendor/node_modules/undici/types/client-stats.d.ts +15 -0
  183. package/vendor/node_modules/undici/types/client.d.ts +153 -0
  184. package/vendor/node_modules/undici/types/connector.d.ts +36 -0
  185. package/vendor/node_modules/undici/types/content-type.d.ts +21 -0
  186. package/vendor/node_modules/undici/types/cookies.d.ts +30 -0
  187. package/vendor/node_modules/undici/types/diagnostics-channel.d.ts +74 -0
  188. package/vendor/node_modules/undici/types/dispatcher.d.ts +275 -0
  189. package/vendor/node_modules/undici/types/env-http-proxy-agent.d.ts +22 -0
  190. package/vendor/node_modules/undici/types/errors.d.ts +177 -0
  191. package/vendor/node_modules/undici/types/eventsource.d.ts +66 -0
  192. package/vendor/node_modules/undici/types/fetch.d.ts +231 -0
  193. package/vendor/node_modules/undici/types/formdata.d.ts +114 -0
  194. package/vendor/node_modules/undici/types/global-dispatcher.d.ts +9 -0
  195. package/vendor/node_modules/undici/types/global-origin.d.ts +7 -0
  196. package/vendor/node_modules/undici/types/h2c-client.d.ts +73 -0
  197. package/vendor/node_modules/undici/types/handlers.d.ts +14 -0
  198. package/vendor/node_modules/undici/types/header.d.ts +160 -0
  199. package/vendor/node_modules/undici/types/index.d.ts +91 -0
  200. package/vendor/node_modules/undici/types/interceptors.d.ts +82 -0
  201. package/vendor/node_modules/undici/types/mock-agent.d.ts +68 -0
  202. package/vendor/node_modules/undici/types/mock-call-history.d.ts +111 -0
  203. package/vendor/node_modules/undici/types/mock-client.d.ts +27 -0
  204. package/vendor/node_modules/undici/types/mock-errors.d.ts +12 -0
  205. package/vendor/node_modules/undici/types/mock-interceptor.d.ts +94 -0
  206. package/vendor/node_modules/undici/types/mock-pool.d.ts +27 -0
  207. package/vendor/node_modules/undici/types/patch.d.ts +29 -0
  208. package/vendor/node_modules/undici/types/pool-stats.d.ts +19 -0
  209. package/vendor/node_modules/undici/types/pool.d.ts +41 -0
  210. package/vendor/node_modules/undici/types/proxy-agent.d.ts +29 -0
  211. package/vendor/node_modules/undici/types/readable.d.ts +68 -0
  212. package/vendor/node_modules/undici/types/retry-agent.d.ts +8 -0
  213. package/vendor/node_modules/undici/types/retry-handler.d.ts +125 -0
  214. package/vendor/node_modules/undici/types/round-robin-pool.d.ts +41 -0
  215. package/vendor/node_modules/undici/types/snapshot-agent.d.ts +109 -0
  216. package/vendor/node_modules/undici/types/socks5-proxy-agent.d.ts +25 -0
  217. package/vendor/node_modules/undici/types/util.d.ts +18 -0
  218. package/vendor/node_modules/undici/types/utility.d.ts +7 -0
  219. package/vendor/node_modules/undici/types/webidl.d.ts +347 -0
  220. package/vendor/node_modules/undici/types/websocket.d.ts +188 -0
@@ -0,0 +1,575 @@
1
+ 'use strict'
2
+ const buffer = require('node:buffer')
3
+ const { Transform } = require('node:stream')
4
+ const { isASCIINumber, isValidLastEventId } = require('./util')
5
+
6
+ /**
7
+ * @type {number[]} BOM
8
+ */
9
+ const BOM = [0xEF, 0xBB, 0xBF]
10
+ /**
11
+ * @type {10} LF
12
+ */
13
+ const LF = 0x0A
14
+ /**
15
+ * @type {13} CR
16
+ */
17
+ const CR = 0x0D
18
+ /**
19
+ * @type {58} COLON
20
+ */
21
+ const COLON = 0x3A
22
+ /**
23
+ * @type {32} SPACE
24
+ */
25
+ const SPACE = 0x20
26
+
27
+ const defaultMaxEventSize = buffer.kStringMaxLength
28
+
29
+ const DATA = Buffer.from('data')
30
+ const EVENT = Buffer.from('event')
31
+ const ID = Buffer.from('id')
32
+ const RETRY = Buffer.from('retry')
33
+
34
+ // Each data field creates a string node, and each unconsumed input chunk keeps
35
+ // a Buffer wrapper. The absolute ceiling protects the large default byte limit.
36
+ const minParserItems = 1024
37
+ const maxParserItems = 131072
38
+ const bytesPerParserItem = 128
39
+
40
+ function isASCIINumberBytes (buffer, start) {
41
+ if (start >= buffer.length) {
42
+ return false
43
+ }
44
+
45
+ for (let i = start; i < buffer.length; i++) {
46
+ if (buffer[i] < 0x30 || buffer[i] > 0x39) {
47
+ return false
48
+ }
49
+ }
50
+
51
+ return true
52
+ }
53
+
54
+ function isValidLastEventIdBytes (buffer, start) {
55
+ for (let i = start; i < buffer.length; i++) {
56
+ if (buffer[i] === 0x00) {
57
+ return false
58
+ }
59
+ }
60
+
61
+ return true
62
+ }
63
+
64
+ function isFieldName (line, length, field) {
65
+ if (length !== field.length) {
66
+ return false
67
+ }
68
+
69
+ for (let i = 0; i < length; i++) {
70
+ if (line[i] !== field[i]) {
71
+ return false
72
+ }
73
+ }
74
+
75
+ return true
76
+ }
77
+
78
+ function createMaxEventSizeExceededError () {
79
+ const error = new Error('EventSource message size exceeded')
80
+ error.aborted = false
81
+ return error
82
+ }
83
+
84
+ /**
85
+ * @typedef {object} EventSourceStreamEvent
86
+ * @type {object}
87
+ * @property {string} [event] The event type.
88
+ * @property {string} [data] The data of the message.
89
+ * @property {string} [id] A unique ID for the event.
90
+ * @property {string} [retry] The reconnection time, in milliseconds.
91
+ */
92
+
93
+ /**
94
+ * @typedef eventSourceSettings
95
+ * @type {object}
96
+ * @property {string} [lastEventId] The last event ID received from the server.
97
+ * @property {string} [origin] The origin of the event source.
98
+ * @property {number} [reconnectionTime] The reconnection time, in milliseconds.
99
+ */
100
+
101
+ class EventSourceStream extends Transform {
102
+ /**
103
+ * @type {eventSourceSettings}
104
+ */
105
+ state
106
+
107
+ /**
108
+ * Leading byte-order-mark check.
109
+ * @type {boolean}
110
+ */
111
+ checkBOM = true
112
+
113
+ /**
114
+ * @type {boolean}
115
+ */
116
+ crlfCheck = false
117
+
118
+ /**
119
+ * @type {boolean}
120
+ */
121
+ eventEndCheck = false
122
+
123
+ /**
124
+ * @type {Buffer[]}
125
+ */
126
+ chunks = []
127
+
128
+ chunkIndex = 0
129
+ pos = 0
130
+ lineChunkIndex = 0
131
+ linePos = 0
132
+ lineLength = 0
133
+ eventSize = 0
134
+ eventFieldSizes = { data: 0, event: 0, id: 0, retry: 0 }
135
+ dataLineCount = 0
136
+ maxEventSize
137
+ maxDataLines
138
+ maxBufferedChunks
139
+
140
+ event = {
141
+ data: undefined,
142
+ event: undefined,
143
+ id: undefined,
144
+ retry: undefined
145
+ }
146
+
147
+ /**
148
+ * @param {object} options
149
+ * @param {boolean} [options.readableObjectMode]
150
+ * @param {number} [options.maxEventSize]
151
+ * @param {eventSourceSettings} [options.eventSourceSettings]
152
+ * @param {(chunk: any, encoding?: BufferEncoding | undefined) => boolean} [options.push]
153
+ */
154
+ constructor (options = {}) {
155
+ // Enable object mode as EventSourceStream emits objects of shape
156
+ // EventSourceStreamEvent
157
+ options.readableObjectMode = true
158
+
159
+ super(options)
160
+
161
+ this.state = options.eventSourceSettings || {}
162
+ this.maxEventSize = options.maxEventSize ?? defaultMaxEventSize
163
+ const parserItemLimit = this.maxEventSize > 0
164
+ ? Math.min(maxParserItems, Math.max(minParserItems, Math.floor(this.maxEventSize / bytesPerParserItem)))
165
+ : 0
166
+ this.maxDataLines = parserItemLimit
167
+ this.maxBufferedChunks = parserItemLimit
168
+ if (options.push) {
169
+ this.push = options.push
170
+ }
171
+ }
172
+
173
+ /**
174
+ * @param {Buffer} chunk
175
+ * @param {string} _encoding
176
+ * @param {Function} callback
177
+ * @returns {void}
178
+ */
179
+ _transform (chunk, _encoding, callback) {
180
+ if (chunk.length === 0) {
181
+ callback()
182
+ return
183
+ }
184
+
185
+ // A leading line ending can immediately release the currently buffered
186
+ // line, even when it uses the final allowed chunk slot.
187
+ if (this.maxEventSize > 0 &&
188
+ this.chunks.length >= this.maxBufferedChunks &&
189
+ chunk[0] !== LF && chunk[0] !== CR) {
190
+ callback(createMaxEventSizeExceededError())
191
+ return
192
+ }
193
+ this.chunks.push(chunk)
194
+
195
+ // Strip leading byte-order-mark if we opened the stream and started
196
+ // the processing of the incoming data
197
+ if (this.checkBOM) {
198
+ if (this.handleBOM()) {
199
+ callback()
200
+ return
201
+ }
202
+ }
203
+
204
+ while (this.hasCurrentByte()) {
205
+ const byte = this.currentByte()
206
+
207
+ // If the previous line ended with an end-of-line, we need to check
208
+ // if the next character is also an end-of-line.
209
+ if (this.eventEndCheck) {
210
+ // If the the current character is an end-of-line, then the event
211
+ // is finished and we can process it
212
+
213
+ // If the previous line ended with a carriage return, we need to
214
+ // check if the current character is a line feed and remove it
215
+ // from the buffer.
216
+ if (this.crlfCheck) {
217
+ // If the current character is a line feed, we can remove it
218
+ // from the buffer and reset the crlfCheck flag
219
+ if (byte === LF) {
220
+ this.crlfCheck = false
221
+ this.consumeCurrentByte()
222
+
223
+ // It is possible that the line feed is not the end of the
224
+ // event. We need to check if the next character is an
225
+ // end-of-line character to determine if the event is
226
+ // finished. We simply continue the loop to check the next
227
+ // character.
228
+
229
+ // As we removed the line feed from the buffer and set the
230
+ // crlfCheck flag to false, we basically don't make any
231
+ // distinction between a line feed and a carriage return.
232
+ continue
233
+ }
234
+ this.crlfCheck = false
235
+ }
236
+
237
+ if (byte === LF || byte === CR) {
238
+ // If the current character is a carriage return, we need to
239
+ // set the crlfCheck flag to true, as we need to check if the
240
+ // next character is a line feed so we can remove it from the
241
+ // buffer
242
+ if (byte === CR) {
243
+ this.crlfCheck = true
244
+ }
245
+
246
+ this.consumeCurrentByte()
247
+ if (this.hasPendingEvent()) {
248
+ this.processEvent(this.event)
249
+ }
250
+ this.clearEvent()
251
+ continue
252
+ }
253
+ // If the current character is not an end-of-line, then the event
254
+ // is not finished and we have to reset the eventEndCheck flag
255
+ this.eventEndCheck = false
256
+ continue
257
+ }
258
+
259
+ // If the current character is an end-of-line, we can process the
260
+ // line
261
+ if (byte === LF || byte === CR) {
262
+ // If the current character is a carriage return, we need to
263
+ // set the crlfCheck flag to true, as we need to check if the
264
+ // next character is a line feed
265
+ if (byte === CR) {
266
+ this.crlfCheck = true
267
+ }
268
+
269
+ // In any case, we can process the line as we reached an
270
+ // end-of-line character
271
+ try {
272
+ this.parseLine(this.readLine(), this.event)
273
+ } catch (error) {
274
+ callback(error)
275
+ return
276
+ }
277
+ this.consumeCurrentByte()
278
+ // A line was processed and this could be the end of the event. We need
279
+ // to check if the next line is empty to determine if the event is
280
+ // finished.
281
+ this.eventEndCheck = true
282
+ continue
283
+ }
284
+
285
+ // readLine() is only called after CR or LF. Reject an unfinished line
286
+ // before it can retain an unbounded number of decoded chunks. The seven
287
+ // extra bytes allow the longest field prefix ("event: " or "retry: ").
288
+ if (this.maxEventSize > 0 && ++this.lineLength > this.maxEventSize + 7) {
289
+ callback(createMaxEventSizeExceededError())
290
+ return
291
+ }
292
+ this.advanceCursor()
293
+ }
294
+
295
+ callback()
296
+ }
297
+
298
+ _destroy (error, callback) {
299
+ this.chunks.length = 0
300
+ this.clearEvent()
301
+ super._destroy(error, callback)
302
+ }
303
+
304
+ /**
305
+ * @param {Buffer} line
306
+ * @param {EventSourceStreamEvent} event
307
+ */
308
+ parseLine (line, event) {
309
+ // If the line is empty (a blank line)
310
+ // Dispatch the event, as defined below.
311
+ // This will be handled in the _transform method
312
+ if (line.length === 0) {
313
+ return
314
+ }
315
+
316
+ // If the line starts with a U+003A COLON character (:)
317
+ // Ignore the line.
318
+ const colonPosition = line.indexOf(COLON)
319
+ if (colonPosition === 0) {
320
+ return
321
+ }
322
+
323
+ let fieldLength = line.length
324
+ let valueStart = line.length
325
+
326
+ // If the line contains a U+003A COLON character (:)
327
+ if (colonPosition !== -1) {
328
+ fieldLength = colonPosition
329
+
330
+ // Collect the characters on the line after the first U+003A COLON
331
+ // character (:), and let value be that string.
332
+ // If value starts with a U+0020 SPACE character, remove it from value.
333
+ valueStart = colonPosition + 1
334
+ if (line[valueStart] === SPACE) {
335
+ ++valueStart
336
+ }
337
+ }
338
+
339
+ if (isFieldName(line, fieldLength, DATA)) {
340
+ if (this.maxEventSize > 0 && this.dataLineCount >= this.maxDataLines) {
341
+ throw createMaxEventSizeExceededError()
342
+ }
343
+ const valueBytes = line.length - valueStart
344
+ const dataSize = this.eventFieldSizes.data + (event.data === undefined ? 0 : 1) + valueBytes
345
+ this.setEventFieldSize('data', dataSize)
346
+
347
+ const value = line.toString('utf8', valueStart)
348
+
349
+ if (event.data === undefined) {
350
+ event.data = value
351
+ } else {
352
+ event.data += `\n${value}`
353
+ }
354
+ this.dataLineCount++
355
+ return
356
+ }
357
+
358
+ if (isFieldName(line, fieldLength, RETRY)) {
359
+ if (isASCIINumberBytes(line, valueStart)) {
360
+ this.setEventFieldSize('retry', line.length - valueStart)
361
+ event.retry = line.toString('utf8', valueStart)
362
+ }
363
+ return
364
+ }
365
+
366
+ if (isFieldName(line, fieldLength, ID)) {
367
+ if (isValidLastEventIdBytes(line, valueStart)) {
368
+ this.setEventFieldSize('id', line.length - valueStart)
369
+ event.id = line.toString('utf8', valueStart)
370
+ }
371
+ return
372
+ }
373
+
374
+ if (isFieldName(line, fieldLength, EVENT)) {
375
+ if (valueStart < line.length) {
376
+ this.setEventFieldSize('event', line.length - valueStart)
377
+ event.event = line.toString('utf8', valueStart)
378
+ }
379
+ }
380
+ }
381
+
382
+ setEventFieldSize (field, size) {
383
+ const eventSize = this.eventSize - this.eventFieldSizes[field] + size
384
+ if (this.maxEventSize > 0 && eventSize > this.maxEventSize) {
385
+ throw createMaxEventSizeExceededError()
386
+ }
387
+ this.eventSize = eventSize
388
+ this.eventFieldSizes[field] = size
389
+ }
390
+
391
+ /**
392
+ * @param {EventSourceStreamEvent} event
393
+ */
394
+ processEvent (event) {
395
+ if (event.retry && isASCIINumber(event.retry)) {
396
+ this.state.reconnectionTime = parseInt(event.retry, 10)
397
+ }
398
+
399
+ if (event.id !== undefined && isValidLastEventId(event.id)) {
400
+ this.state.lastEventId = event.id
401
+ }
402
+
403
+ // only dispatch event, when data is provided
404
+ if (event.data !== undefined) {
405
+ this.push({
406
+ type: event.event || 'message',
407
+ options: {
408
+ data: event.data,
409
+ lastEventId: this.state.lastEventId,
410
+ origin: this.state.origin
411
+ }
412
+ })
413
+ }
414
+ }
415
+
416
+ clearEvent () {
417
+ this.event.data = undefined
418
+ this.event.event = undefined
419
+ this.event.id = undefined
420
+ this.event.retry = undefined
421
+ this.eventSize = 0
422
+ this.dataLineCount = 0
423
+ this.eventFieldSizes.data = 0
424
+ this.eventFieldSizes.event = 0
425
+ this.eventFieldSizes.id = 0
426
+ this.eventFieldSizes.retry = 0
427
+ }
428
+
429
+ hasPendingEvent () {
430
+ return this.event.data !== undefined ||
431
+ this.event.event !== undefined ||
432
+ this.event.id !== undefined ||
433
+ this.event.retry !== undefined
434
+ }
435
+
436
+ hasCurrentByte () {
437
+ return this.chunkIndex < this.chunks.length &&
438
+ this.pos < this.chunks[this.chunkIndex].length
439
+ }
440
+
441
+ currentByte () {
442
+ return this.chunks[this.chunkIndex][this.pos]
443
+ }
444
+
445
+ consumeCurrentByte () {
446
+ this.advanceCursor()
447
+ this.syncLineStartToCursor()
448
+ }
449
+
450
+ advanceCursor () {
451
+ this.pos++
452
+
453
+ while (this.chunkIndex < this.chunks.length && this.pos >= this.chunks[this.chunkIndex].length) {
454
+ this.chunkIndex++
455
+ this.pos = 0
456
+ }
457
+ }
458
+
459
+ syncLineStartToCursor () {
460
+ this.lineChunkIndex = this.chunkIndex
461
+ this.linePos = this.pos
462
+ this.lineLength = 0
463
+ this.dropConsumedChunks()
464
+ }
465
+
466
+ dropConsumedChunks () {
467
+ if (this.lineChunkIndex > 0) {
468
+ const consumed = this.lineChunkIndex
469
+ this.chunks.splice(0, consumed)
470
+ this.lineChunkIndex = 0
471
+ this.chunkIndex -= consumed
472
+ }
473
+
474
+ if (this.chunkIndex === this.chunks.length) {
475
+ this.chunks.length = 0
476
+ this.chunkIndex = 0
477
+ this.pos = 0
478
+ this.lineChunkIndex = 0
479
+ this.linePos = 0
480
+ }
481
+ }
482
+
483
+ readLine () {
484
+ if (this.lineChunkIndex === this.chunkIndex) {
485
+ return this.chunks[this.chunkIndex].subarray(this.linePos, this.pos)
486
+ }
487
+
488
+ const chunks = []
489
+ let length = 0
490
+
491
+ for (let i = this.lineChunkIndex; i <= this.chunkIndex; i++) {
492
+ const chunk = this.chunks[i]
493
+ const start = i === this.lineChunkIndex ? this.linePos : 0
494
+ const end = i === this.chunkIndex ? this.pos : chunk.length
495
+ const slice = chunk.subarray(start, end)
496
+ length += slice.length
497
+ chunks.push(slice)
498
+ }
499
+
500
+ return Buffer.concat(chunks, length)
501
+ }
502
+
503
+ peekBufferedByte (offset) {
504
+ let chunkIndex = this.lineChunkIndex
505
+ let pos = this.linePos
506
+
507
+ while (chunkIndex < this.chunks.length) {
508
+ const chunk = this.chunks[chunkIndex]
509
+ const remaining = chunk.length - pos
510
+
511
+ if (offset < remaining) {
512
+ return chunk[pos + offset]
513
+ }
514
+
515
+ offset -= remaining
516
+ chunkIndex++
517
+ pos = 0
518
+ }
519
+ }
520
+
521
+ discardLeadingBytes (count) {
522
+ while (count > 0 && this.lineChunkIndex < this.chunks.length) {
523
+ const chunk = this.chunks[this.lineChunkIndex]
524
+ const remaining = chunk.length - this.linePos
525
+
526
+ if (count < remaining) {
527
+ this.linePos += count
528
+ count = 0
529
+ } else {
530
+ count -= remaining
531
+ this.lineChunkIndex++
532
+ this.linePos = 0
533
+ }
534
+ }
535
+
536
+ this.chunkIndex = this.lineChunkIndex
537
+ this.pos = this.linePos
538
+ this.dropConsumedChunks()
539
+ }
540
+
541
+ handleBOM () {
542
+ const first = this.peekBufferedByte(0)
543
+ const second = this.peekBufferedByte(1)
544
+ const third = this.peekBufferedByte(2)
545
+
546
+ if (second === undefined) {
547
+ if (first === BOM[0]) {
548
+ return true
549
+ }
550
+
551
+ this.checkBOM = false
552
+ return true
553
+ }
554
+
555
+ if (third === undefined) {
556
+ if (first === BOM[0] && second === BOM[1]) {
557
+ return true
558
+ }
559
+
560
+ this.checkBOM = false
561
+ return false
562
+ }
563
+
564
+ if (first === BOM[0] && second === BOM[1] && third === BOM[2]) {
565
+ this.discardLeadingBytes(3)
566
+ }
567
+
568
+ this.checkBOM = false
569
+ return !this.hasCurrentByte()
570
+ }
571
+ }
572
+
573
+ module.exports = {
574
+ EventSourceStream
575
+ }