effect 4.0.3 → 4.0.4

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 (207) hide show
  1. package/AGENTS.md +24 -0
  2. package/CLAUDE.md +24 -0
  3. package/ai-docs/package.json +2 -2
  4. package/ai-docs/src/52_graphql/10_basics.ts +111 -0
  5. package/ai-docs/src/52_graphql/20_testing.ts +45 -0
  6. package/ai-docs/src/52_graphql/30_batching.ts +116 -0
  7. package/ai-docs/src/52_graphql/40_aliased-batching.ts +122 -0
  8. package/ai-docs/src/52_graphql/50_errors-and-retries.ts +74 -0
  9. package/ai-docs/src/52_graphql/index.md +6 -0
  10. package/dist/Context.d.ts.map +1 -1
  11. package/dist/Context.js +9 -0
  12. package/dist/Context.js.map +1 -1
  13. package/dist/RequestResolver.d.ts.map +1 -1
  14. package/dist/RequestResolver.js +4 -10
  15. package/dist/RequestResolver.js.map +1 -1
  16. package/dist/Scheduler.d.ts +9 -0
  17. package/dist/Scheduler.d.ts.map +1 -1
  18. package/dist/Scheduler.js +9 -0
  19. package/dist/Scheduler.js.map +1 -1
  20. package/dist/Schema.d.ts +8 -0
  21. package/dist/Schema.d.ts.map +1 -1
  22. package/dist/Schema.js +7 -0
  23. package/dist/Schema.js.map +1 -1
  24. package/dist/SchemaGetter.d.ts +4 -0
  25. package/dist/SchemaGetter.d.ts.map +1 -1
  26. package/dist/SchemaGetter.js +52 -33
  27. package/dist/SchemaGetter.js.map +1 -1
  28. package/dist/Sink.d.ts.map +1 -1
  29. package/dist/Sink.js +38 -17
  30. package/dist/Sink.js.map +1 -1
  31. package/dist/Stream.d.ts +11 -0
  32. package/dist/Stream.d.ts.map +1 -1
  33. package/dist/Stream.js +16 -1
  34. package/dist/Stream.js.map +1 -1
  35. package/dist/Utils.js +8 -3
  36. package/dist/Utils.js.map +1 -1
  37. package/dist/ai/AnthropicStructuredOutput.js +0 -2
  38. package/dist/ai/AnthropicStructuredOutput.js.map +1 -1
  39. package/dist/ai/Chat.d.ts +2 -2
  40. package/dist/ai/Chat.d.ts.map +1 -1
  41. package/dist/ai/LanguageModel.d.ts +38 -7
  42. package/dist/ai/LanguageModel.d.ts.map +1 -1
  43. package/dist/ai/LanguageModel.js +25 -7
  44. package/dist/ai/LanguageModel.js.map +1 -1
  45. package/dist/ai/McpServer.d.ts +55 -0
  46. package/dist/ai/McpServer.d.ts.map +1 -1
  47. package/dist/ai/McpServer.js +132 -22
  48. package/dist/ai/McpServer.js.map +1 -1
  49. package/dist/ai/Prompt.d.ts.map +1 -1
  50. package/dist/ai/Prompt.js +28 -5
  51. package/dist/ai/Prompt.js.map +1 -1
  52. package/dist/ai/Response.d.ts +4 -3
  53. package/dist/ai/Response.d.ts.map +1 -1
  54. package/dist/ai/Response.js.map +1 -1
  55. package/dist/cluster/ClusterWorkflowEngine.d.ts.map +1 -1
  56. package/dist/cluster/ClusterWorkflowEngine.js +46 -8
  57. package/dist/cluster/ClusterWorkflowEngine.js.map +1 -1
  58. package/dist/cluster/Sharding.d.ts.map +1 -1
  59. package/dist/cluster/Sharding.js +6 -4
  60. package/dist/cluster/Sharding.js.map +1 -1
  61. package/dist/encoding/Sse.d.ts +6 -0
  62. package/dist/encoding/Sse.d.ts.map +1 -1
  63. package/dist/encoding/Sse.js +62 -70
  64. package/dist/encoding/Sse.js.map +1 -1
  65. package/dist/graphql/GraphQL.d.ts +349 -0
  66. package/dist/graphql/GraphQL.d.ts.map +1 -0
  67. package/dist/graphql/GraphQL.js +207 -0
  68. package/dist/graphql/GraphQL.js.map +1 -0
  69. package/dist/graphql/GraphQLClient.d.ts +562 -0
  70. package/dist/graphql/GraphQLClient.d.ts.map +1 -0
  71. package/dist/graphql/GraphQLClient.js +498 -0
  72. package/dist/graphql/GraphQLClient.js.map +1 -0
  73. package/dist/graphql/GraphQLClientError.d.ts +445 -0
  74. package/dist/graphql/GraphQLClientError.d.ts.map +1 -0
  75. package/dist/graphql/GraphQLClientError.js +479 -0
  76. package/dist/graphql/GraphQLClientError.js.map +1 -0
  77. package/dist/graphql/GraphQLGroup.d.ts +118 -0
  78. package/dist/graphql/GraphQLGroup.d.ts.map +1 -0
  79. package/dist/graphql/GraphQLGroup.js +109 -0
  80. package/dist/graphql/GraphQLGroup.js.map +1 -0
  81. package/dist/graphql/GraphQLMiddleware.d.ts +249 -0
  82. package/dist/graphql/GraphQLMiddleware.d.ts.map +1 -0
  83. package/dist/graphql/GraphQLMiddleware.js +130 -0
  84. package/dist/graphql/GraphQLMiddleware.js.map +1 -0
  85. package/dist/graphql/GraphQLProtocol.d.ts +731 -0
  86. package/dist/graphql/GraphQLProtocol.d.ts.map +1 -0
  87. package/dist/graphql/GraphQLProtocol.js +719 -0
  88. package/dist/graphql/GraphQLProtocol.js.map +1 -0
  89. package/dist/graphql/GraphQLResolver.d.ts +453 -0
  90. package/dist/graphql/GraphQLResolver.d.ts.map +1 -0
  91. package/dist/graphql/GraphQLResolver.js +552 -0
  92. package/dist/graphql/GraphQLResolver.js.map +1 -0
  93. package/dist/graphql/index.d.ts +40 -0
  94. package/dist/graphql/index.d.ts.map +1 -0
  95. package/dist/graphql/index.js +41 -0
  96. package/dist/graphql/index.js.map +1 -0
  97. package/dist/http/HttpClient.d.ts +15 -0
  98. package/dist/http/HttpClient.d.ts.map +1 -1
  99. package/dist/http/HttpClient.js +24 -10
  100. package/dist/http/HttpClient.js.map +1 -1
  101. package/dist/http/HttpEffect.d.ts.map +1 -1
  102. package/dist/http/HttpEffect.js +14 -7
  103. package/dist/http/HttpEffect.js.map +1 -1
  104. package/dist/http/HttpMiddleware.d.ts.map +1 -1
  105. package/dist/http/HttpMiddleware.js +31 -32
  106. package/dist/http/HttpMiddleware.js.map +1 -1
  107. package/dist/http/HttpRouter.d.ts +35 -0
  108. package/dist/http/HttpRouter.d.ts.map +1 -1
  109. package/dist/http/HttpRouter.js +35 -0
  110. package/dist/http/HttpRouter.js.map +1 -1
  111. package/dist/http/HttpServerResponse.d.ts +8 -6
  112. package/dist/http/HttpServerResponse.d.ts.map +1 -1
  113. package/dist/http/HttpServerResponse.js +27 -16
  114. package/dist/http/HttpServerResponse.js.map +1 -1
  115. package/dist/http/Multipart.d.ts.map +1 -1
  116. package/dist/http/Multipart.js +15 -1
  117. package/dist/http/Multipart.js.map +1 -1
  118. package/dist/http-api/HttpApiScalar.d.ts +5 -0
  119. package/dist/http-api/HttpApiScalar.d.ts.map +1 -1
  120. package/dist/http-api/HttpApiScalar.js.map +1 -1
  121. package/dist/internal/dateTime.js +40 -35
  122. package/dist/internal/dateTime.js.map +1 -1
  123. package/dist/internal/effect.js +8 -3
  124. package/dist/internal/effect.js.map +1 -1
  125. package/dist/internal/graphql.d.ts +2 -0
  126. package/dist/internal/graphql.d.ts.map +1 -0
  127. package/dist/internal/graphql.js +195 -0
  128. package/dist/internal/graphql.js.map +1 -0
  129. package/dist/internal/graphqlHeaders.d.ts +4 -0
  130. package/dist/internal/graphqlHeaders.d.ts.map +1 -0
  131. package/dist/internal/graphqlHeaders.js +11 -0
  132. package/dist/internal/graphqlHeaders.js.map +1 -0
  133. package/dist/internal/request.js +20 -1
  134. package/dist/internal/request.js.map +1 -1
  135. package/dist/internal/schema/toCodeDocument.js +4 -1
  136. package/dist/internal/schema/toCodeDocument.js.map +1 -1
  137. package/dist/internal/schema/toJsonSchemaDocument.js +29 -5
  138. package/dist/internal/schema/toJsonSchemaDocument.js.map +1 -1
  139. package/dist/internal/version.js +1 -1
  140. package/dist/net/Host.d.ts +49 -0
  141. package/dist/net/Host.d.ts.map +1 -1
  142. package/dist/net/Host.js +55 -0
  143. package/dist/net/Host.js.map +1 -1
  144. package/dist/net/NetAddress.d.ts +8 -0
  145. package/dist/net/NetAddress.d.ts.map +1 -1
  146. package/dist/net/NetAddress.js +8 -0
  147. package/dist/net/NetAddress.js.map +1 -1
  148. package/dist/rpc/RpcServer.d.ts.map +1 -1
  149. package/dist/rpc/RpcServer.js +36 -9
  150. package/dist/rpc/RpcServer.js.map +1 -1
  151. package/dist/socket/Socket.d.ts +6 -0
  152. package/dist/socket/Socket.d.ts.map +1 -1
  153. package/dist/socket/Socket.js.map +1 -1
  154. package/dist/workflow/DurableDeferred.d.ts.map +1 -1
  155. package/dist/workflow/DurableDeferred.js +32 -3
  156. package/dist/workflow/DurableDeferred.js.map +1 -1
  157. package/dist/workflow/WorkflowEngine.d.ts +24 -2
  158. package/dist/workflow/WorkflowEngine.d.ts.map +1 -1
  159. package/dist/workflow/WorkflowEngine.js +11 -2
  160. package/dist/workflow/WorkflowEngine.js.map +1 -1
  161. package/package.json +6 -3
  162. package/src/Context.ts +9 -0
  163. package/src/RequestResolver.ts +4 -10
  164. package/src/Scheduler.ts +9 -0
  165. package/src/Schema.ts +8 -0
  166. package/src/SchemaGetter.ts +47 -35
  167. package/src/Sink.ts +45 -18
  168. package/src/Stream.ts +33 -4
  169. package/src/Utils.ts +8 -5
  170. package/src/ai/AnthropicStructuredOutput.ts +2 -2
  171. package/src/ai/Chat.ts +2 -2
  172. package/src/ai/LanguageModel.ts +96 -24
  173. package/src/ai/McpServer.ts +244 -90
  174. package/src/ai/Prompt.ts +24 -10
  175. package/src/ai/Response.ts +6 -3
  176. package/src/cluster/ClusterWorkflowEngine.ts +51 -12
  177. package/src/cluster/Sharding.ts +12 -9
  178. package/src/encoding/Sse.ts +69 -79
  179. package/src/graphql/GraphQL.ts +494 -0
  180. package/src/graphql/GraphQLClient.ts +912 -0
  181. package/src/graphql/GraphQLClientError.ts +542 -0
  182. package/src/graphql/GraphQLGroup.ts +167 -0
  183. package/src/graphql/GraphQLMiddleware.ts +253 -0
  184. package/src/graphql/GraphQLProtocol.ts +1286 -0
  185. package/src/graphql/GraphQLResolver.ts +1010 -0
  186. package/src/graphql/index.ts +48 -0
  187. package/src/http/HttpClient.ts +54 -10
  188. package/src/http/HttpEffect.ts +11 -5
  189. package/src/http/HttpMiddleware.ts +33 -34
  190. package/src/http/HttpRouter.ts +35 -0
  191. package/src/http/HttpServerResponse.ts +28 -16
  192. package/src/http/Multipart.ts +17 -1
  193. package/src/http-api/HttpApiScalar.ts +5 -0
  194. package/src/internal/dateTime.ts +13 -10
  195. package/src/internal/effect.ts +8 -3
  196. package/src/internal/graphql.ts +263 -0
  197. package/src/internal/graphqlHeaders.ts +11 -0
  198. package/src/internal/request.ts +31 -3
  199. package/src/internal/schema/toCodeDocument.ts +7 -1
  200. package/src/internal/schema/toJsonSchemaDocument.ts +34 -2
  201. package/src/internal/version.ts +1 -1
  202. package/src/net/Host.ts +72 -0
  203. package/src/net/NetAddress.ts +9 -0
  204. package/src/rpc/RpcServer.ts +55 -15
  205. package/src/socket/Socket.ts +6 -0
  206. package/src/workflow/DurableDeferred.ts +43 -5
  207. package/src/workflow/WorkflowEngine.ts +48 -4
@@ -692,6 +692,12 @@ const make = Effect.gen(function*() {
692
692
  const storageReadLatch = yield* Latch.make(true)
693
693
  const openStorageReadLatch = constant(Effect.asVoid(storageReadLatch.open))
694
694
 
695
+ type PendingNotification = {
696
+ resume: (_: Effect.Effect<void, EntityNotAssignedToRunner>) => void
697
+ readonly message: Message.IncomingRequest<any>
698
+ }
699
+ const pendingNotifications = new Map<Snowflake.Snowflake, PendingNotification>()
700
+
695
701
  const storageReadLock = Semaphore.makeUnsafe(1)
696
702
  const withStorageReadLock = storageReadLock.withPermits(1)
697
703
 
@@ -725,7 +731,7 @@ const make = Effect.gen(function*() {
725
731
  if (storageEnabled && initialRunnerAddress) {
726
732
  const selfAddress = initialRunnerAddress
727
733
 
728
- yield* Effect.gen(function*() {
734
+ const storageReadLoop = Effect.gen(function*() {
729
735
  yield* Effect.logDebug("Starting")
730
736
  yield* Effect.addFinalizer(() => Effect.logDebug("Shutting down"))
731
737
 
@@ -982,8 +988,7 @@ const make = Effect.gen(function*() {
982
988
  module: "effect/cluster/Sharding",
983
989
  fiber: "Storage read loop",
984
990
  runner: selfAddress
985
- }),
986
- Effect.forkIn(shardingScope)
991
+ })
987
992
  )
988
993
 
989
994
  // open the storage latch every poll interval
@@ -1110,6 +1115,9 @@ const make = Effect.gen(function*() {
1110
1115
  ),
1111
1116
  Effect.forkIn(shardingScope)
1112
1117
  )
1118
+
1119
+ // fork after the state the loop reads has been initialized
1120
+ yield* Effect.forkIn(storageReadLoop, shardingScope)
1113
1121
  }
1114
1122
 
1115
1123
  // --- Sending messages ---
@@ -1150,11 +1158,6 @@ const make = Effect.gen(function*() {
1150
1158
  return isRequest ? Effect.andThen(awaitShardLock(address.shardId), send) : send
1151
1159
  }
1152
1160
 
1153
- type PendingNotification = {
1154
- resume: (_: Effect.Effect<void, EntityNotAssignedToRunner>) => void
1155
- readonly message: Message.IncomingRequest<any>
1156
- }
1157
- const pendingNotifications = new Map<Snowflake.Snowflake, PendingNotification>()
1158
1161
  const notifyLocal = <M extends Message.Outgoing<any> | Message.Incoming<any>>(
1159
1162
  message: M,
1160
1163
  discard: boolean,
@@ -1172,7 +1175,7 @@ const make = Effect.gen(function*() {
1172
1175
  const state = entityManagers.get(address.entityType)
1173
1176
  if (!state) {
1174
1177
  return Effect.flatMap(waitForEntityManager(address.entityType), loop)
1175
- } else if (state.status === "closed" || !isEntityOnLocalShards(address)) {
1178
+ } else if (state.status === "closed") {
1176
1179
  return Effect.fail(new EntityNotAssignedToRunner({ address }))
1177
1180
  }
1178
1181
 
@@ -92,6 +92,12 @@ export interface DecodeOptions {
92
92
  * Maximum number of string code units retained for a pending event. The default is 10 MiB.
93
93
  */
94
94
  readonly maxEventSize?: number | undefined
95
+ /**
96
+ * Also dispatch an event that sets an `event:` name but has no `data:`
97
+ * line, with empty `data`. The WHATWG algorithm drops such events, but some
98
+ * protocols use them, such as graphql-sse's `complete`. Defaults to `false`.
99
+ */
100
+ readonly dispatchEmptyNamedEvents?: boolean | undefined
95
101
  }
96
102
 
97
103
  const defaultMaxEventSize = 10 * 1024 * 1024
@@ -270,13 +276,16 @@ export const decodeDataSchema = <Type, DecodingServices, IE, Done>(
270
276
  */
271
277
  export function makeParser(onParse: (event: AnyEvent) => void, options?: DecodeOptions): Parser {
272
278
  const maxEventSize = options?.maxEventSize ?? defaultMaxEventSize
279
+ const dispatchEmptyNamedEvents = options?.dispatchEmptyNamedEvents === true
273
280
 
274
281
  // Processing state
275
282
  let isFirstChunk: boolean
276
- let buffer: string
277
- let startingPosition: number
278
- let startingFieldLength: number
283
+ // Pieces of the unterminated line, joined once when the line ends
284
+ let pending: Array<string>
285
+ let pendingLength: number
279
286
  let discardTrailingNewline: boolean
287
+ // Incremented by `reset`, so `feed` can stop if `onParse` resets the parser
288
+ let generation = 0
280
289
 
281
290
  // Event state
282
291
  let lastEventId: string | undefined
@@ -287,10 +296,10 @@ export function makeParser(onParse: (event: AnyEvent) => void, options?: DecodeO
287
296
  return { feed, reset }
288
297
 
289
298
  function reset(): void {
299
+ generation++
290
300
  isFirstChunk = true
291
- buffer = ""
292
- startingPosition = 0
293
- startingFieldLength = -1
301
+ pending = []
302
+ pendingLength = 0
294
303
  discardTrailingNewline = false
295
304
 
296
305
  lastEventId = undefined
@@ -299,120 +308,98 @@ export function makeParser(onParse: (event: AnyEvent) => void, options?: DecodeO
299
308
  }
300
309
 
301
310
  function feed(chunk: string): SseError | undefined {
302
- buffer = buffer ? buffer + chunk : chunk
303
-
304
311
  // Strip any UTF-8 byte order mark (BOM) at the start of the stream.
305
312
  // Note that we do not strip any non - UTF8 BOM, as eventsource streams are
306
313
  // always decoded as UTF8 as per the specification.
307
- if (isFirstChunk && buffer.startsWith(BOM)) {
308
- buffer = buffer.slice(BOM.length)
314
+ if (isFirstChunk && chunk.startsWith(BOM)) {
315
+ chunk = chunk.slice(BOM.length)
309
316
  }
310
317
 
311
318
  isFirstChunk = false
312
319
 
313
- // Set up chunk-specific processing state
314
- const length = buffer.length
320
+ const length = chunk.length
321
+ const currentGeneration = generation
315
322
  let position = 0
316
323
 
317
- // Read the current buffer byte by byte
318
324
  while (position < length) {
319
- // EventSource allows for carriage return + line feed, which means we
320
- // need to ignore a linefeed character if the previous character was a
321
- // carriage return
322
- // @todo refactor to reduce nesting, consider checking previous byte?
323
- // @todo but consider multiple chunks etc
325
+ // Skip the LF of a CRLF, whose CR may have ended the previous chunk
324
326
  if (discardTrailingNewline) {
325
- if (buffer[position] === "\n") {
327
+ discardTrailingNewline = false
328
+ if (chunk.charCodeAt(position) === LF) {
326
329
  ++position
330
+ continue
327
331
  }
328
- discardTrailingNewline = false
329
332
  }
330
333
 
331
- let lineLength = -1
332
- let fieldLength = startingFieldLength
333
- let character: string
334
-
335
- for (let index = position + startingPosition; lineLength < 0 && index < length; ++index) {
336
- character = buffer[index]
337
- if (character === ":" && fieldLength < 0) {
338
- fieldLength = index - position
339
- } else if (character === "\r") {
340
- discardTrailingNewline = true
341
- lineLength = index - position
342
- } else if (character === "\n") {
343
- lineLength = index - position
344
- }
334
+ let lineEnd = position
335
+ while (lineEnd < length) {
336
+ const code = chunk.charCodeAt(lineEnd)
337
+ if (code === CR || code === LF) break
338
+ ++lineEnd
345
339
  }
346
340
 
347
- if (lineLength < 0) {
348
- startingPosition = length - position
349
- startingFieldLength = fieldLength
341
+ if (lineEnd === length) {
342
+ pending.push(chunk.slice(position))
343
+ pendingLength += length - position
350
344
  break
351
- } else {
352
- startingPosition = 0
353
- startingFieldLength = -1
354
345
  }
355
346
 
356
- parseEventStreamLine(buffer, position, fieldLength, lineLength)
347
+ discardTrailingNewline = chunk.charCodeAt(lineEnd) === CR
357
348
 
358
- position += lineLength + 1
359
- }
349
+ let line = chunk.slice(position, lineEnd)
350
+ if (pending.length > 0) {
351
+ pending.push(line)
352
+ line = pending.join("")
353
+ pending = []
354
+ pendingLength = 0
355
+ }
356
+ parseLine(line)
357
+
358
+ if (generation !== currentGeneration) {
359
+ // `onParse` reset the parser, so drop the rest of this chunk
360
+ return
361
+ }
360
362
 
361
- if (position === length) {
362
- // If we consumed the entire buffer to read the event, reset the buffer
363
- buffer = ""
364
- } else if (position > 0) {
365
- // If there are bytes left to process, set the buffer to the unprocessed
366
- // portion of the buffer only
367
- buffer = buffer.slice(position)
363
+ position = lineEnd + 1
368
364
  }
369
365
 
370
- if (buffer.length + data.length > maxEventSize) {
366
+ if (pendingLength + data.length > maxEventSize) {
371
367
  const error = new SseError({ reason: new EventTooLarge({ maxEventSize }) })
372
368
  reset()
373
369
  return error
374
370
  }
375
371
  }
376
372
 
377
- function parseEventStreamLine(
378
- lineBuffer: string,
379
- index: number,
380
- fieldLength: number,
381
- lineLength: number
382
- ) {
383
- if (lineLength === 0) {
384
- // We reached the last line of this event
385
- if (data.length > 0) {
373
+ function parseLine(line: string) {
374
+ if (line.length === 0) {
375
+ // End of event. Clear the state first so a throwing `onParse` cannot
376
+ // leak it into the next event
377
+ const named = eventName !== undefined && eventName !== ""
378
+ const event = eventName || "message"
379
+ const eventData = data
380
+ eventName = undefined
381
+ data = ""
382
+ if (eventData.length > 0 || (dispatchEmptyNamedEvents && named)) {
386
383
  onParse({
387
384
  _tag: "Event",
388
385
  id: lastEventId,
389
- event: eventName || "message",
390
- data: data.slice(0, -1) // remove trailing newline
386
+ event,
387
+ data: eventData.slice(0, -1) // remove trailing newline
391
388
  })
392
- data = ""
393
389
  }
394
- eventName = undefined
395
390
  return
396
391
  }
397
392
 
398
- const noValue = fieldLength < 0
399
- const field = lineBuffer.slice(index, index + (noValue ? lineLength : fieldLength))
400
- let step = 0
401
-
402
- if (noValue) {
403
- step = lineLength
404
- } else if (lineBuffer[index + fieldLength + 1] === " ") {
405
- step = fieldLength + 2
406
- } else {
407
- step = fieldLength + 1
393
+ const colon = line.indexOf(":")
394
+ let field = line
395
+ let value = ""
396
+ if (colon >= 0) {
397
+ field = line.slice(0, colon)
398
+ value = line.slice(line.charCodeAt(colon + 1) === SPACE ? colon + 2 : colon + 1)
408
399
  }
409
400
 
410
- const position = index + step
411
- const valueLength = lineLength - step
412
- const value = lineBuffer.slice(position, position + valueLength).toString()
413
-
414
401
  if (field === "data") {
415
- data += value ? `${value}\n` : "\n"
402
+ data += value + "\n"
416
403
  } else if (field === "event") {
417
404
  eventName = value
418
405
  } else if (field === "id" && !value.includes("\u0000")) {
@@ -425,6 +412,9 @@ export function makeParser(onParse: (event: AnyEvent) => void, options?: DecodeO
425
412
  }
426
413
 
427
414
  const BOM = "\uFEFF"
415
+ const LF = 10
416
+ const CR = 13
417
+ const SPACE = 32
428
418
 
429
419
  /**
430
420
  * Stateful Server-Sent Events parser returned by `makeParser`.