n8n-nodes-pocketbase 2.3.43 → 2.3.45
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.
package/README.md
CHANGED
|
@@ -46,7 +46,7 @@ Alternatively, you can use your administrator account and the "\_superusers" col
|
|
|
46
46
|
|
|
47
47
|
## Compatibility
|
|
48
48
|
|
|
49
|
-
This was developed for version 2.
|
|
49
|
+
This was developed for version 2.40.5 of n8n and version 0.40.4 of PocketBase.
|
|
50
50
|
|
|
51
51
|
## Development
|
|
52
52
|
|
|
@@ -143,7 +143,7 @@ function createParser(config) {
|
|
|
143
143
|
const { maxBufferSize, onComment, onError, onEvent, onId, onRetry } = config;
|
|
144
144
|
const pendingFragments = [];
|
|
145
145
|
let pendingFragmentsLength = 0;
|
|
146
|
-
let
|
|
146
|
+
let bomPrefix = "";
|
|
147
147
|
let id;
|
|
148
148
|
let data = "";
|
|
149
149
|
let dataLines = 0;
|
|
@@ -155,13 +155,14 @@ function createParser(config) {
|
|
|
155
155
|
if (terminated) {
|
|
156
156
|
throw new Error("Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.");
|
|
157
157
|
}
|
|
158
|
-
if (
|
|
159
|
-
|
|
160
|
-
if (chunk
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
chunk = chunk.slice(3);
|
|
158
|
+
if (bomPrefix !== void 0) {
|
|
159
|
+
chunk = bomPrefix + chunk;
|
|
160
|
+
if (chunk === "" || chunk === "\xEF" || chunk === "\xEF\xBB") {
|
|
161
|
+
bomPrefix = chunk;
|
|
162
|
+
return;
|
|
164
163
|
}
|
|
164
|
+
bomPrefix = void 0;
|
|
165
|
+
chunk = chunk.replace(/^(?:\uFEFF|\xEF\xBB\xBF)/, "");
|
|
165
166
|
}
|
|
166
167
|
if (skippingLine || skipNextLineFeed) {
|
|
167
168
|
chunk = resumeAfterSkip(chunk);
|
|
@@ -426,7 +427,7 @@ ${value}`;
|
|
|
426
427
|
const incompleteLine = pendingFragments.join("");
|
|
427
428
|
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
428
429
|
}
|
|
429
|
-
|
|
430
|
+
bomPrefix = "";
|
|
430
431
|
id = void 0;
|
|
431
432
|
data = "";
|
|
432
433
|
dataLines = 0;
|
|
@@ -795,6 +796,9 @@ var init_EventSource = __esm({
|
|
|
795
796
|
* @internal
|
|
796
797
|
*/
|
|
797
798
|
#onEvent = (event) => {
|
|
799
|
+
if (this.#readyState === this.CLOSED) {
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
798
802
|
const origin = this.#redirectUrl ? this.#redirectUrl.origin : this.#url.origin;
|
|
799
803
|
const lastEventId = this.#lastEventId ?? "";
|
|
800
804
|
const messageEvent = new MessageEvent(event.event || "message", {
|
|
@@ -841,9 +845,7 @@ var init_EventSource = __esm({
|
|
|
841
845
|
* @internal
|
|
842
846
|
*/
|
|
843
847
|
#failConnection(message, code) {
|
|
844
|
-
|
|
845
|
-
this.#readyState = this.CLOSED;
|
|
846
|
-
}
|
|
848
|
+
this.close();
|
|
847
849
|
const errorEvent = new ErrorEvent("error", { code, message });
|
|
848
850
|
this.dispatchEvent(errorEvent);
|
|
849
851
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../node_modules/eventsource/src/errors.ts", "../../../node_modules/eventsource-parser/src/errors.ts", "../../../node_modules/eventsource-parser/src/parse.ts", "../../../node_modules/eventsource-parser/src/index.ts", "../../../node_modules/eventsource/src/EventSource.ts", "../../../node_modules/eventsource/src/index.ts", "../../../nodes/PocketbaseTrigger/PocketbaseTrigger.node.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * An extended version of the `Event` emitted by the `EventSource` object when an error occurs.\n * While the spec does not include any additional properties, we intentionally go beyond the spec\n * and provide some (minimal) additional information to aid in debugging.\n *\n * @public\n */\nexport class ErrorEvent extends Event {\n /**\n * HTTP status code, if this was triggered by an HTTP error\n * Note: this is not part of the spec, but is included for better error handling.\n *\n * @public\n */\n public code?: number | undefined\n\n /**\n * Optional message attached to the error.\n * Note: this is not part of the spec, but is included for better error handling.\n *\n * @public\n */\n public message?: string | undefined\n\n /**\n * Constructs a new `ErrorEvent` instance. This is typically not called directly,\n * but rather emitted by the `EventSource` object when an error occurs.\n *\n * @param type - The type of the event (should be \"error\")\n * @param errorEventInitDict - Optional properties to include in the error event\n */\n constructor(\n type: string,\n errorEventInitDict?: {message?: string | undefined; code?: number | undefined},\n ) {\n super(type)\n this.code = errorEventInitDict?.code ?? undefined\n this.message = errorEventInitDict?.message ?? undefined\n }\n\n /**\n * Node.js \"hides\" the `message` and `code` properties of the `ErrorEvent` instance,\n * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,\n * we explicitly include the properties in the `inspect` method.\n *\n * This is automatically called by Node.js when you `console.log` an instance of this class.\n *\n * @param _depth - The current depth\n * @param options - The options passed to `util.inspect`\n * @param inspect - The inspect function to use (prevents having to import it from `util`)\n * @returns A string representation of the error\n */\n [Symbol.for('nodejs.util.inspect.custom')](\n _depth: number,\n options: {colors: boolean},\n inspect: (obj: unknown, inspectOptions: {colors: boolean}) => string,\n ): string {\n return inspect(inspectableError(this), options)\n }\n\n /**\n * Deno \"hides\" the `message` and `code` properties of the `ErrorEvent` instance,\n * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,\n * we explicitly include the properties in the `inspect` method.\n *\n * This is automatically called by Deno when you `console.log` an instance of this class.\n *\n * @param inspect - The inspect function to use (prevents having to import it from `util`)\n * @param options - The options passed to `Deno.inspect`\n * @returns A string representation of the error\n */\n [Symbol.for('Deno.customInspect')](\n inspect: (obj: unknown, inspectOptions: {colors: boolean}) => string,\n options: {colors: boolean},\n ): string {\n return inspect(inspectableError(this), options)\n }\n}\n\n/**\n * For environments where DOMException may not exist, we will use a SyntaxError instead.\n * While this isn't strictly according to spec, it is very close.\n *\n * @param message - The message to include in the error\n * @returns A `DOMException` or `SyntaxError` instance\n * @internal\n */\nexport function syntaxError(message: string): SyntaxError {\n // If someone can figure out a way to make this work without depending on DOM/Node.js typings,\n // and without casting to `any`, please send a PR \uD83D\uDE4F\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const DomException = (globalThis as any).DOMException\n if (typeof DomException === 'function') {\n return new DomException(message, 'SyntaxError')\n }\n\n return new SyntaxError(message)\n}\n\n/**\n * Flatten an error into a single error message string.\n * Unwraps nested errors and joins them with a comma.\n *\n * @param err - The error to flatten\n * @returns A string representation of the error\n * @internal\n */\nexport function flattenError(err: unknown): string {\n if (!(err instanceof Error)) {\n return `${err}`\n }\n\n if ('errors' in err && Array.isArray(err.errors)) {\n return err.errors.map(flattenError).join(', ')\n }\n\n if ('cause' in err && err.cause instanceof Error) {\n return `${err}: ${flattenError(err.cause)}`\n }\n\n return err.message\n}\n\n/**\n * Convert an `ErrorEvent` instance into a plain object for inspection.\n *\n * @param err - The `ErrorEvent` instance to inspect\n * @returns A plain object representation of the error\n * @internal\n */\nfunction inspectableError(err: ErrorEvent) {\n return {\n type: err.type,\n message: err.message,\n code: err.code,\n defaultPrevented: err.defaultPrevented,\n cancelable: err.cancelable,\n timeStamp: err.timeStamp,\n }\n}\n", "/**\n * The type of error that occurred.\n * @public\n */\nexport type ErrorType = 'invalid-retry' | 'unknown-field' | 'max-buffer-size-exceeded'\n\n/**\n * Error thrown when encountering an issue during parsing.\n *\n * @public\n */\nexport class ParseError extends Error {\n /**\n * The type of error that occurred.\n */\n type: ErrorType\n\n /**\n * In the case of a completed unknown field encountered in the stream, this will be the field name.\n */\n field?: string | undefined\n\n /**\n * In the case of a completed unknown field encountered in the stream, this will be the value of the field.\n */\n value?: string | undefined\n\n /**\n * The line that caused the error, if available.\n */\n line?: string | undefined\n\n constructor(\n message: string,\n options: {type: ErrorType; field?: string; value?: string; line?: string},\n ) {\n super(message)\n this.name = 'ParseError'\n this.type = options.type\n this.field = options.field\n this.value = options.value\n this.line = options.line\n }\n}\n", "/**\n * EventSource/Server-Sent Events parser\n * @see https://html.spec.whatwg.org/multipage/server-sent-events.html\n */\nimport {ParseError} from './errors.ts'\nimport type {EventSourceParser, ParserConfig} from './types.ts'\n\n// ASCII codes used in the hot parsing paths.\nconst LF = 10\nconst CR = 13\nconst SPACE = 32\nconst MAX_FIELD_PREFIX_LENGTH = 6\n\n/**\n * Creates a new EventSource parser.\n *\n * @param config - Parser configuration. Accepts callbacks (see {@link ParserCallbacks})\n * and options like `maxBufferSize` (see {@link ParserConfig}).\n *\n * @returns A new EventSource parser, with `feed` and `reset` methods.\n * @public\n */\nexport function createParser(config: ParserConfig): EventSourceParser {\n if (typeof config === 'function') {\n throw new TypeError(\n '`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?',\n )\n }\n\n const {maxBufferSize, onComment, onError, onEvent, onId, onRetry} = config\n\n // Trailing bytes from prior `feed()` calls that did not yet form a complete line.\n // Stored as an array of fragments and only joined when a line terminator arrives.\n // Concatenating per-feed (`prefix + chunk`) is O(N\u00B2) when a single SSE line spans\n // many chunks (e.g. a large `data:` payload streamed in tiny slices, or an MCP-style\n // server that emits one giant content block). Buffering as fragments + joining once\n // makes the same workload linear.\n const pendingFragments: string[] = []\n\n // Running total of `pendingFragments` lengths, kept in sync with the array so the\n // `maxBufferSize` check doesn't have to walk the fragment list on every feed.\n let pendingFragmentsLength = 0\n\n let isFirstChunk = true\n let id: string | undefined\n let data = ''\n let dataLines = 0\n let eventType: string | undefined\n\n // Set after a `maxBufferSize` overflow. Once tripped, `feed()` throws until\n // `reset()` is called \u2014 see the comment on `maxBufferSize` in `ParserConfig`.\n let terminated = false\n let skippingLine = false\n\n // Set when a line (parsed or discarded) was terminated by a trailing `\\r` at the very\n // end of a chunk. That `\\r` is ambiguous: it may be a bare-CR terminator or the first\n // half of a `\\r\\n` whose `\\n` lands in the next chunk. The line itself is complete\n // either way, but we must remember to swallow a single leading `\\n` from the next\n // chunk so the pair is treated as one terminator rather than a blank line (which\n // would dispatch an event prematurely).\n let skipNextLineFeed = false\n\n /**\n * Feeds a chunk of the SSE stream to the parser. Any trailing bytes that do\n * not yet form a complete line are held back and prepended to the next chunk,\n * so callers can pass arbitrary slices of the stream without worrying about\n * line boundaries.\n *\n * Per the SSE spec, one leading UTF-8 BOM at the start of the very first chunk\n * is stripped before parsing. This handles both the raw 3-byte form (0xEF 0xBB\n * 0xBF) and a single decoded U+FEFF, so a leading BOM is ignored regardless of\n * how the caller decoded the bytes.\n *\n * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream\n */\n function feed(chunk: string) {\n if (terminated) {\n throw new Error(\n 'Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.',\n )\n }\n\n if (isFirstChunk) {\n isFirstChunk = false\n // Strip one leading UTF-8 BOM from the start of the stream, if present.\n // (Per the spec, this is only valid at the very start of the stream.)\n // Two representations can reach us depending on how the caller decoded the\n // bytes: a single decoded U+FEFF (e.g. a `TextDecoder` created with\n // `ignoreBOM`) or the raw 3-byte sequence (0xEF 0xBB 0xBF, e.g. a latin1 or\n // passthrough decode). Both are stripped so a leading BOM is ignored\n // regardless of decode path.\n if (chunk.charCodeAt(0) === 0xfeff) {\n chunk = chunk.slice(1)\n } else if (\n chunk.charCodeAt(0) === 0xef &&\n chunk.charCodeAt(1) === 0xbb &&\n chunk.charCodeAt(2) === 0xbf\n ) {\n chunk = chunk.slice(3)\n }\n }\n\n // Rare resume states from a prior chunk boundary: a pending `\\r\\n` split or a\n // line being discarded. Single combined check keeps the hot path to one branch;\n // the actual handling lives out-of-line in `resumeAfterSkip`.\n if (skippingLine || skipNextLineFeed) {\n chunk = resumeAfterSkip(chunk)\n if (!chunk) {\n return\n }\n }\n\n // Hot path: no buffered prefix from a prior partial line. Hand the chunk\n // straight to `processLines`, exactly like the original implementation.\n // Zero new work in the common case (every chunk ends with `\\n\\n`).\n if (!pendingFragments.length) {\n const trailing = processLines(chunk)\n if (trailing !== '') {\n storeTrailing(trailing)\n }\n checkBufferSize()\n return\n }\n\n // We have a buffered prefix. If this chunk also has no terminator, append\n // to the buffer without concatenating \u2014 that's the O(N\u00B2) trap we're\n // avoiding (large single `data:` payload split across many tiny chunks).\n if (chunk.indexOf('\\n') === -1 && chunk.indexOf('\\r') === -1) {\n if (pendingFragmentsLength < MAX_FIELD_PREFIX_LENGTH) {\n const head =\n pendingFragments.join('') +\n chunk.slice(0, MAX_FIELD_PREFIX_LENGTH - pendingFragmentsLength)\n if (!shouldBufferTrailing(head)) {\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n skippingLine = true\n return\n }\n }\n pendingFragments.push(chunk)\n pendingFragmentsLength += chunk.length\n checkBufferSize()\n return\n }\n\n // Terminator arrived. Join the accumulated fragments + this chunk once,\n // process, and buffer any new trailing partial line.\n pendingFragments.push(chunk)\n const input = pendingFragments.join('')\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n storeTrailing(processLines(input))\n checkBufferSize()\n }\n\n // Out-of-line handler for the rare post-boundary states. `skipNextLineFeed` means a\n // line (parsed or discarded) ended with a trailing `\\r` at the previous chunk boundary,\n // so a single leading `\\n` must be swallowed to consume a split `\\r\\n` as one terminator.\n // `skippingLine` means we are discarding an invalid line until its terminator arrives.\n // The two states are mutually exclusive. Returns the remaining chunk to parse ('' if\n // this chunk was fully consumed).\n function resumeAfterSkip(chunk: string): string {\n if (chunk.length === 0) {\n return chunk\n }\n\n if (skipNextLineFeed) {\n skipNextLineFeed = false\n return chunk.charCodeAt(0) === LF ? chunk.slice(1) : chunk\n }\n\n const crIndex = chunk.indexOf('\\r')\n const lfIndex = chunk.indexOf('\\n')\n const lineEnd =\n crIndex === -1 ? lfIndex : lfIndex === -1 ? crIndex : crIndex < lfIndex ? crIndex : lfIndex\n\n if (lineEnd === -1) {\n return ''\n }\n\n // Trailing `\\r` at the very end of the chunk: defer the CRLF/CR decision to the\n // next chunk (see `skipNextLineFeed`) rather than greedily consuming just the `\\r`.\n if (lineEnd === chunk.length - 1 && chunk.charCodeAt(lineEnd) === CR) {\n skippingLine = false\n skipNextLineFeed = true\n return ''\n }\n\n skippingLine = false\n return chunk.slice(\n lineEnd + (chunk.charCodeAt(lineEnd) === CR && chunk.charCodeAt(lineEnd + 1) === LF ? 2 : 1),\n )\n }\n\n function storeTrailing(trailing: string) {\n if (!trailing) return\n\n // A trailing that ends with `\\r` is not a partial line: the `\\r` terminates it,\n // and only the CRLF-vs-CR ambiguity remains (the matching `\\n` may start the next\n // chunk). Parse the completed line now \u2014 buffering it could grow unbounded through\n // the no-terminator append path, and discarding it would eat the terminator and\n // make skip mode swallow the next line.\n if (trailing.charCodeAt(trailing.length - 1) === CR) {\n parseLine(trailing, 0, trailing.length - 1)\n skipNextLineFeed = true\n return\n }\n\n if (shouldBufferTrailing(trailing)) {\n pendingFragments.push(trailing)\n pendingFragmentsLength = trailing.length\n return\n }\n\n skippingLine = true\n }\n\n function shouldBufferTrailing(trailing: string) {\n const firstCharCode = trailing.charCodeAt(0)\n return (\n (firstCharCode === 58 && !!onComment) ||\n (firstCharCode === 100 && isPotentialField(trailing, 'data')) ||\n (firstCharCode === 101 && isPotentialField(trailing, 'event')) ||\n (firstCharCode === 105 && isPotentialField(trailing, 'id')) ||\n (firstCharCode === 114 && isPotentialField(trailing, 'retry'))\n )\n }\n\n function checkBufferSize() {\n if (maxBufferSize === undefined) return\n if (pendingFragmentsLength + data.length <= maxBufferSize) return\n\n terminated = true\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n skippingLine = false\n skipNextLineFeed = false\n onError?.(\n new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {\n type: 'max-buffer-size-exceeded',\n }),\n )\n }\n\n /**\n * Splits `chunk` into SSE lines and dispatches each to the appropriate handler.\n * Returns any trailing bytes that did not terminate with a line break, so the\n * caller can prepend them to the next chunk.\n *\n * The SSE spec permits three line terminators: `\\n`, `\\r`, and `\\r\\n`. Real-world\n * streams almost always use plain `\\n`, so we take a fast path when no `\\r` is\n * present in the chunk. The slow path is spec-correct but does more work per line.\n */\n function processLines(chunk: string): string {\n let searchIndex = 0\n\n // Fast path: LF-only chunk (the common case for typical SSE servers).\n // We can scan forward with a single `indexOf('\\n')` per line and inline\n // the hot-path branches for `data:` and `event:` without the CR bookkeeping\n // the slow path needs.\n if (chunk.indexOf('\\r') === -1) {\n let lfIndex = chunk.indexOf('\\n', searchIndex)\n while (lfIndex !== -1) {\n // Blank line: end-of-event marker. Dispatch the accumulated event (if any)\n // and reset the buffered fields. This is hoisted out of `parseLine` because\n // it's the single most common line shape after `data:` lines.\n if (searchIndex === lfIndex) {\n if (id !== undefined) {\n onId?.(id)\n }\n if (dataLines > 0) {\n onEvent?.({id, event: eventType, data})\n }\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n searchIndex = lfIndex + 1\n lfIndex = chunk.indexOf('\\n', searchIndex)\n continue\n }\n const firstCharCode = chunk.charCodeAt(searchIndex)\n if (isDataPrefix(chunk, searchIndex, firstCharCode)) {\n // `data:` line \u2014 append the value to the event's data buffer.\n // 'data:'.length === 5, 'data: '.length === 6\n const valueStart =\n chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5\n const value = chunk.slice(valueStart, lfIndex)\n // Fast path within a fast path: if this is the first data line AND the\n // next char is another LF (i.e. `data:foo\\n\\n`), dispatch immediately\n // without ever writing to the `data` buffer. This is the shape of a\n // typical single-line SSE event (ChatGPT-style streams, etc.) and is\n // hot enough to be worth the duplication.\n if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {\n if (id !== undefined) {\n onId?.(id)\n }\n onEvent?.({id, event: eventType, data: value})\n id = undefined\n data = ''\n eventType = undefined\n searchIndex = lfIndex + 2\n lfIndex = chunk.indexOf('\\n', searchIndex)\n continue\n }\n // Multi-line data: concatenate with newline separator per spec.\n data = dataLines === 0 ? value : `${data}\\n${value}`\n dataLines++\n } else if (isEventPrefix(chunk, searchIndex, firstCharCode)) {\n // `event:` line \u2014 set the event type for the next dispatch. Per spec,\n // an empty value resets `event type` to its default (undefined here).\n // 'event:'.length === 6, 'event: '.length === 7\n eventType =\n chunk.slice(\n chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,\n lfIndex,\n ) || undefined\n } else {\n // Everything else: `id:`, `retry:`, comment lines (`:` prefix), unknown\n // fields, or malformed lines. These are rarer and go through the full\n // per-line parser, which handles the SSE field grammar in detail.\n parseLine(chunk, searchIndex, lfIndex)\n }\n searchIndex = lfIndex + 1\n lfIndex = chunk.indexOf('\\n', searchIndex)\n }\n return chunk.slice(searchIndex)\n }\n\n // Slow path: the chunk contains at least one `\\r`, so lines may be terminated\n // by `\\r`, `\\n`, or `\\r\\n`. We locate the next terminator by looking at both\n // the nearest `\\r` and `\\n` and picking whichever comes first.\n while (searchIndex < chunk.length) {\n const crIndex = chunk.indexOf('\\r', searchIndex)\n const lfIndex = chunk.indexOf('\\n', searchIndex)\n\n let lineEnd = -1\n if (crIndex !== -1 && lfIndex !== -1) {\n lineEnd = crIndex < lfIndex ? crIndex : lfIndex\n } else if (crIndex !== -1) {\n // A trailing `\\r` at the very end of the chunk is ambiguous: it could be\n // a bare-CR terminator, or the first half of a `\\r\\n` whose `\\n` arrives\n // in the next chunk. Defer until we see more input.\n if (crIndex === chunk.length - 1) {\n lineEnd = -1\n } else {\n lineEnd = crIndex\n }\n } else if (lfIndex !== -1) {\n lineEnd = lfIndex\n }\n\n if (lineEnd === -1) {\n break\n }\n\n parseLine(chunk, searchIndex, lineEnd)\n searchIndex = lineEnd + 1\n // If we just consumed a `\\r` and the next char is `\\n`, skip it so the\n // pair is treated as a single terminator rather than an empty line.\n if (chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF) {\n searchIndex++\n }\n }\n\n return chunk.slice(searchIndex)\n }\n\n function parseLine(chunk: string, start: number, end: number) {\n if (start === end) {\n dispatchEvent()\n return\n }\n\n const firstCharCode = chunk.charCodeAt(start)\n\n if (isDataPrefix(chunk, start, firstCharCode)) {\n // 'data:'.length === 5, 'data: '.length === 6\n const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5\n const value = chunk.slice(valueStart, end)\n data = dataLines === 0 ? value : `${data}\\n${value}`\n dataLines++\n return\n }\n\n if (isEventPrefix(chunk, start, firstCharCode)) {\n // 'event:'.length === 6, 'event: '.length === 7\n eventType =\n chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || undefined\n return\n }\n\n // Fast path for \"id:\" \u2014 'i' = 105, 'd' = 100, ':' = 58\n if (\n firstCharCode === 105 &&\n chunk.charCodeAt(start + 1) === 100 &&\n chunk.charCodeAt(start + 2) === 58\n ) {\n // 'id:'.length === 3, 'id: '.length === 4\n const value = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end)\n // If the field value does not contain U+0000 NULL, then set the `ID` buffer to\n // the field value. Otherwise, ignore the field.\n if (!value.includes('\\0')) id = value\n return\n }\n\n // Comment line \u2014 ':' = 58\n if (firstCharCode === 58) {\n if (onComment) {\n const line = chunk.slice(start, end)\n // skip ':' (+1), or ': ' (+2) when a space follows\n onComment(line.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1))\n }\n return\n }\n\n const line = chunk.slice(start, end)\n const fieldSeparatorIndex = line.indexOf(':')\n if (fieldSeparatorIndex === -1) {\n processField(line, '', line)\n return\n }\n\n const field = line.slice(0, fieldSeparatorIndex)\n // skip ':' (+1), or ': ' (+2) when a space follows\n const offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1\n const value = line.slice(fieldSeparatorIndex + offset)\n processField(field, value, line)\n }\n\n function processField(field: string, value: string, line: string) {\n // Field names must be compared literally, with no case folding performed.\n switch (field) {\n case 'event':\n // Set the `event type` buffer to field value\n eventType = value || undefined\n break\n case 'data':\n data = dataLines === 0 ? value : `${data}\\n${value}`\n dataLines++\n break\n case 'id':\n // If the field value does not contain U+0000 NULL, then set the `ID` buffer to\n // the field value. Otherwise, ignore the field.\n if (!value.includes('\\0')) id = value\n break\n case 'retry':\n // If the field value consists of only ASCII digits, then interpret the field value as an\n // integer in base ten, and set the event stream's reconnection time to that integer.\n // Otherwise, ignore the field.\n if (/^\\d+$/.test(value)) {\n onRetry?.(parseInt(value, 10))\n } else {\n onError?.(\n new ParseError(`Invalid \\`retry\\` value: \"${value}\"`, {\n type: 'invalid-retry',\n value,\n line,\n }),\n )\n }\n break\n default:\n // Otherwise, the field is ignored.\n onError?.(\n new ParseError(\n `Unknown field \"${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}\"`,\n {type: 'unknown-field', field, value, line},\n ),\n )\n break\n }\n }\n\n function dispatchEvent() {\n if (id !== undefined) {\n onId?.(id)\n }\n\n if (dataLines > 0) {\n onEvent?.({\n id,\n event: eventType,\n data,\n })\n }\n\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n }\n\n function reset(options: {consume?: boolean} = {}) {\n if (options.consume && pendingFragments.length > 0) {\n const incompleteLine = pendingFragments.join('')\n parseLine(incompleteLine, 0, incompleteLine.length)\n }\n\n isFirstChunk = true\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n terminated = false\n skippingLine = false\n skipNextLineFeed = false\n }\n\n return {feed, reset}\n}\n\n/**\n * Checks if `chunk` starts with the literal `data:` at index `i`.\n *\n * Equivalent to `chunk.startsWith('data:', i)`, but benchmarks show this\n * hand-unrolled char-code comparison is ~20% faster on common event types.\n * The caller passes `firstCharCode` (the code at `i`) so it can be reused\n * across prefix checks.\n *\n * ASCII: 'd' = 100, 'a' = 97, 't' = 116, 'a' = 97, ':' = 58\n */\nfunction isDataPrefix(chunk: string, i: number, firstCharCode: number): boolean {\n return (\n firstCharCode === 100 &&\n chunk.charCodeAt(i + 1) === 97 &&\n chunk.charCodeAt(i + 2) === 116 &&\n chunk.charCodeAt(i + 3) === 97 &&\n chunk.charCodeAt(i + 4) === 58\n )\n}\n\n/**\n * Checks if `chunk` starts with the literal `event:` at index `i`.\n *\n * See {@link isDataPrefix} for why this is hand-unrolled rather than using\n * `String.prototype.startsWith`.\n *\n * ASCII: 'e' = 101, 'v' = 118, 'e' = 101, 'n' = 110, 't' = 116, ':' = 58\n */\nfunction isEventPrefix(chunk: string, i: number, firstCharCode: number): boolean {\n return (\n firstCharCode === 101 &&\n chunk.charCodeAt(i + 1) === 118 &&\n chunk.charCodeAt(i + 2) === 101 &&\n chunk.charCodeAt(i + 3) === 110 &&\n chunk.charCodeAt(i + 4) === 116 &&\n chunk.charCodeAt(i + 5) === 58\n )\n}\n\nfunction isPotentialField(line: string, field: string): boolean {\n let i = 1\n while (i < line.length && i < field.length) {\n if (line.charCodeAt(i) !== field.charCodeAt(i)) {\n return false\n }\n i++\n }\n\n return line.length <= field.length || line.charCodeAt(field.length) === 58\n}\n", "export {type ErrorType, ParseError} from './errors.ts'\nexport {createParser} from './parse.ts'\nexport type {EventSourceMessage, EventSourceParser, ParserCallbacks, ParserConfig} from './types.ts'\n", "import {\n createParser,\n type EventSourceMessage,\n type EventSourceParser,\n type ParseError,\n} from 'eventsource-parser'\n\nimport {ErrorEvent, flattenError, syntaxError} from './errors.ts'\nimport type {\n AddEventListenerOptions,\n EventListenerOptions,\n EventListenerOrEventListenerObject,\n EventSourceEventMap,\n EventSourceFetchInit,\n EventSourceInit,\n FetchLike,\n FetchLikeResponse,\n} from './types.ts'\n\nconst DEFAULT_MAX_BUFFER_SIZE = 100 * 1024 * 1024\n\n/**\n * An `EventSource` instance opens a persistent connection to an HTTP server, which sends events\n * in `text/event-stream` format. The connection remains open until closed by calling `.close()`.\n *\n * Deliberately an `interface` and not a `class`: it lets consumers pass the native `EventSource`,\n * a mock, or any other implementation wherever this type is expected.\n *\n * @public\n * @example\n * ```js\n * const eventSource = new EventSource('https://example.com/stream')\n * eventSource.addEventListener('error', (error) => {\n * console.error(error)\n * })\n * eventSource.addEventListener('message', (event) => {\n * console.log('Received message:', event.data)\n * })\n * ```\n */\nexport interface EventSource extends EventTarget {\n /**\n * ReadyState representing an EventSource currently trying to connect\n *\n * @public\n */\n readonly CONNECTING: 0\n\n /**\n * ReadyState representing an EventSource connection that is open (eg connected)\n *\n * @public\n */\n readonly OPEN: 1\n\n /**\n * ReadyState representing an EventSource connection that is closed (eg disconnected)\n *\n * @public\n */\n readonly CLOSED: 2\n\n /**\n * Returns the state of this EventSource object's connection. It can have the values described below.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)\n *\n * Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,\n * defined in the TypeScript `dom` library.\n *\n * @public\n */\n readonly readyState: number\n\n /**\n * Returns the URL providing the event stream.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)\n *\n * @public\n */\n readonly url: string\n\n /**\n * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to \"include\", and false otherwise.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)\n *\n * @public\n */\n readonly withCredentials: boolean\n\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */\n onerror: ((this: EventSource, ev: ErrorEvent) => unknown) | null\n\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */\n onmessage: ((this: EventSource, ev: MessageEvent) => unknown) | null\n\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */\n onopen: ((this: EventSource, ev: Event) => unknown) | null\n\n addEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n addEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void\n\n removeEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n removeEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void\n\n /**\n * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)\n *\n * @public\n */\n close(): void\n}\n\n/**\n * The `EventSource` constructor. Mirrors the shape of the native one, so the two can be used\n * interchangeably - eg for functions that take an implementation to construct.\n *\n * @public\n */\nexport interface EventSourceConstructor {\n readonly prototype: EventSource\n\n /**\n * Constructs a new `EventSource` instance, which immediately starts connecting.\n *\n * @param url - The URL to connect to\n * @param eventSourceInitDict - Options for the connection\n */\n new (url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource\n\n /** ReadyState representing an EventSource currently trying to connect */\n readonly CONNECTING: 0\n\n /** ReadyState representing an EventSource connection that is open (eg connected) */\n readonly OPEN: 1\n\n /** ReadyState representing an EventSource connection that is closed (eg disconnected) */\n readonly CLOSED: 2\n}\n\n/**\n * Implementation of the `EventSource` interface.\n *\n * Intentionally not exported: TypeScript emits a `#private` brand into declaration files for any\n * class holding hard-private (`#`) fields, which makes the emitted type nominal. Exporting the\n * interface and const instead keeps the public type structural, while the implementation keeps\n * its actual, runtime-enforced private state.\n *\n * Public members are documented on the `EventSource` interface, which is what consumers see.\n *\n * @internal\n */\nclass EventSourceImpl extends EventTarget implements EventSource {\n static CONNECTING = 0 as const\n static OPEN = 1 as const\n static CLOSED = 2 as const\n\n readonly CONNECTING = 0 as const\n readonly OPEN = 1 as const\n readonly CLOSED = 2 as const\n\n public get readyState(): number {\n return this.#readyState\n }\n\n public get url(): string {\n return this.#url.href\n }\n\n public get withCredentials(): boolean {\n return this.#withCredentials\n }\n\n public get onerror(): ((this: EventSource, ev: ErrorEvent) => unknown) | null {\n return this.#onError\n }\n public set onerror(value: ((this: EventSource, ev: ErrorEvent) => unknown) | null) {\n if (this.#onError) {\n this.removeEventListener('error', this.#onError)\n }\n this.#onError = value\n if (value) {\n this.addEventListener('error', value)\n }\n }\n\n public get onmessage(): ((this: EventSource, ev: MessageEvent) => unknown) | null {\n return this.#onMessage\n }\n public set onmessage(value: ((this: EventSource, ev: MessageEvent) => unknown) | null) {\n if (this.#onMessage) {\n this.removeEventListener('message', this.#onMessage)\n }\n this.#onMessage = value\n if (value) {\n this.addEventListener('message', value)\n }\n }\n\n public get onopen(): ((this: EventSource, ev: Event) => unknown) | null {\n return this.#onOpen\n }\n public set onopen(value: ((this: EventSource, ev: Event) => unknown) | null) {\n if (this.#onOpen) {\n this.removeEventListener('open', this.#onOpen)\n }\n this.#onOpen = value\n if (value) {\n this.addEventListener('open', value)\n }\n }\n\n override addEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n override addEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n override addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void\n override addEventListener(\n type: string,\n listener:\n | ((this: EventSource, event: MessageEvent) => unknown)\n | EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void {\n const listen = listener as (this: EventSource, event: Event) => unknown\n super.addEventListener(type, listen, options)\n }\n\n override removeEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n override removeEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n override removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void\n override removeEventListener(\n type: string,\n listener:\n | ((this: EventSource, event: MessageEvent) => unknown)\n | EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void {\n const listen = listener as (this: EventSource, event: Event) => unknown\n super.removeEventListener(type, listen, options)\n }\n\n constructor(url: string | URL, eventSourceInitDict?: EventSourceInit) {\n super()\n\n try {\n if (url instanceof URL) {\n this.#url = url\n } else if (typeof url === 'string') {\n this.#url = new URL(url, getBaseURL())\n } else {\n throw new Error('Invalid URL')\n }\n } catch {\n throw syntaxError('An invalid or illegal string was specified')\n }\n\n this.#parser = createParser({\n maxBufferSize: eventSourceInitDict?.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n onEvent: this.#onEvent,\n onError: this.#onParseError,\n onId: this.#onIdChange,\n onRetry: this.#onRetryChange,\n })\n\n this.#readyState = this.CONNECTING\n this.#reconnectInterval = 3000\n this.#fetch = eventSourceInitDict?.fetch ?? globalThis.fetch\n this.#withCredentials = eventSourceInitDict?.withCredentials ?? false\n\n this.#connect()\n }\n\n close(): void {\n if (this.#reconnectTimer) clearTimeout(this.#reconnectTimer)\n if (this.#readyState === this.CLOSED) return\n if (this.#controller) this.#controller.abort()\n this.#readyState = this.CLOSED\n this.#controller = undefined\n }\n\n // PRIVATES FOLLOW\n\n /**\n * Current connection state\n *\n * @internal\n */\n #readyState: number\n\n /**\n * Original URL used to connect.\n *\n * Note that this will stay the same even after a redirect.\n *\n * @internal\n */\n #url: URL\n\n /**\n * The destination URL after a redirect. Is reset on reconnection.\n *\n * @internal\n */\n #redirectUrl: URL | undefined\n\n /**\n * Whether to include credentials in the request\n *\n * @internal\n */\n #withCredentials: boolean\n\n /**\n * The fetch implementation to use\n *\n * @internal\n */\n #fetch: FetchLike\n\n /**\n * The reconnection time in milliseconds\n *\n * @internal\n */\n #reconnectInterval: number\n\n /**\n * Reference to an ongoing reconnect attempt, if any\n *\n * @internal\n */\n #reconnectTimer: ReturnType<typeof setTimeout> | undefined\n\n /**\n * The last event ID seen by the EventSource, which will be sent as `Last-Event-ID` in the\n * request headers on a reconnection attempt.\n *\n * @internal\n */\n #lastEventId: string | null = null\n\n /**\n * The AbortController instance used to abort the fetch request\n *\n * @internal\n */\n #controller: AbortController | undefined\n\n /**\n * Instance of an EventSource parser (`eventsource-parser` npm module)\n *\n * @internal\n */\n #parser: EventSourceParser\n\n /**\n * Holds the current error handler, attached through `onerror` property directly.\n * Note that `addEventListener('error', \u2026)` will not be stored here.\n *\n * @internal\n */\n #onError: ((this: EventSource, ev: ErrorEvent) => unknown) | null = null\n\n /**\n * Holds the current message handler, attached through `onmessage` property directly.\n * Note that `addEventListener('message', \u2026)` will not be stored here.\n *\n * @internal\n */\n #onMessage: ((this: EventSource, ev: MessageEvent) => unknown) | null = null\n\n /**\n * Holds the current open handler, attached through `onopen` property directly.\n * Note that `addEventListener('open', \u2026)` will not be stored here.\n *\n * @internal\n */\n #onOpen: ((this: EventSource, ev: Event) => unknown) | null = null\n\n /**\n * Connect to the given URL and start receiving events\n *\n * @internal\n */\n #connect() {\n this.#readyState = this.CONNECTING\n this.#controller = new AbortController()\n\n // Browser tests are failing if we directly call `this.#fetch()`, thus the indirection.\n const fetch = this.#fetch\n fetch(this.#url, this.#getRequestOptions())\n .then(this.#onFetchResponse)\n .catch(this.#onFetchError)\n }\n\n /**\n * Handles the fetch response\n *\n * @param response - The Fetch(ish) response\n * @internal\n */\n #onFetchResponse = async (response: FetchLikeResponse) => {\n this.#parser.reset()\n\n const {body, redirected, status, headers} = response\n\n // [spec] a client can be told to stop reconnecting using the HTTP 204 No Content response code.\n if (status === 204) {\n // We still need to emit an error event - this mirrors the browser behavior,\n // and without it there is no way to tell the user that the connection was closed.\n this.#failConnection('Server sent HTTP 204, not reconnecting', 204)\n this.close()\n return\n }\n\n // [spec] \u2026Event stream requests can be redirected using HTTP 301 and 307 redirects as with\n // [spec] normal HTTP requests.\n // Spec does not say anything about other redirect codes (302, 308), but this seems an\n // unintended omission, rather than a feature. Browsers will happily redirect on other 3xxs's.\n if (redirected) {\n this.#redirectUrl = new URL(response.url)\n } else {\n this.#redirectUrl = undefined\n }\n\n // [spec] if res's status is not 200, \u2026, then fail the connection.\n if (status !== 200) {\n this.#failConnection(`Non-200 status code (${status})`, status)\n return\n }\n\n // [spec] \u2026or if res's `Content-Type` is not `text/event-stream`, then fail the connection.\n const contentType = headers.get('content-type') || ''\n if (!contentType.startsWith('text/event-stream')) {\n this.#failConnection('Invalid content type, expected \"text/event-stream\"', status)\n return\n }\n\n // [spec] \u2026if the readyState attribute is set to a value other than CLOSED\u2026\n if (this.#readyState === this.CLOSED) {\n return\n }\n\n // [spec] \u2026sets the readyState attribute to OPEN and fires an event\n // [spec] \u2026named open at the EventSource object.\n this.#readyState = this.OPEN\n\n const openEvent = new Event('open')\n this.dispatchEvent(openEvent)\n\n // Ensure that the response stream is a web stream\n if (typeof body !== 'object' || !body || !('getReader' in body)) {\n this.#failConnection('Invalid response body, expected a web ReadableStream', status)\n this.close() // This should only happen if `fetch` provided is \"faulty\" - don't reconnect\n return\n }\n\n const decoder = new TextDecoder()\n\n const reader = body.getReader()\n let open = true\n\n do {\n const {done, value} = await reader.read()\n if (this.#readyState === this.CLOSED) {\n open = false\n break\n }\n\n if (value) {\n this.#parser.feed(decoder.decode(value, {stream: !done}))\n }\n\n if (!done) {\n continue\n }\n\n open = false\n this.#parser.reset()\n\n this.#scheduleReconnect()\n } while (open)\n }\n\n /**\n * Handles rejected requests for the EventSource endpoint\n *\n * @param err - The error from `fetch()`\n * @internal\n */\n #onFetchError = (err: Error & {type?: string}) => {\n this.#controller = undefined\n\n // We expect abort errors when the user manually calls `close()` - ignore those\n if (err.name === 'AbortError' || err.type === 'aborted') {\n return\n }\n\n this.#scheduleReconnect(flattenError(err))\n }\n\n /**\n * Get request options for the `fetch()` request\n *\n * @returns The request options\n * @internal\n */\n #getRequestOptions(): EventSourceFetchInit {\n const lastEvent = this.#lastEventId ? {'Last-Event-ID': this.#lastEventId} : undefined\n\n const init: EventSourceFetchInit = {\n // [spec] Let `corsAttributeState` be `Anonymous`\u2026\n // [spec] \u2026will have their mode set to \"cors\"\u2026\n mode: 'cors',\n redirect: 'follow',\n headers: {Accept: 'text/event-stream', ...lastEvent},\n cache: 'no-store',\n signal: this.#controller?.signal,\n }\n\n // Some environments crash if attempting to set `credentials` where it is not supported,\n // eg on Cloudflare Workers. To avoid this, we only set it in browser-like environments.\n if ('window' in globalThis) {\n // [spec] \u2026and their credentials mode set to \"same-origin\"\n // [spec] \u2026if the `withCredentials` attribute is `true`, set the credentials mode to \"include\"\u2026\n init.credentials = this.withCredentials ? 'include' : 'same-origin'\n }\n\n return init\n }\n\n /**\n * Called by EventSourceParser when a blank line ends a block containing a valid `id` field.\n * This runs before `#onEvent` when the same block also contains data.\n *\n * @param value - The value of the `id` field\n * @internal\n */\n #onIdChange = (value: string) => {\n this.#lastEventId = value\n }\n\n /**\n * Called by EventSourceParser instance when an event has successfully been parsed\n * and is ready to be processed.\n *\n * @param event - The parsed event\n * @internal\n */\n #onEvent = (event: EventSourceMessage) => {\n const origin = this.#redirectUrl ? this.#redirectUrl.origin : this.#url.origin\n // [spec] The `lastEventId` attribute is the last event ID string of the event\n // source, i.e. the persisted buffer (`#lastEventId`) - not the current event's `id`.\n // The buffer is only updated by an explicit `id` field and must survive an\n // event that omits `id`.\n const lastEventId = this.#lastEventId ?? ''\n\n const messageEvent = new MessageEvent(event.event || 'message', {\n data: event.data,\n origin,\n lastEventId,\n })\n\n // workerd (Cloudflare Workers) accepts `data` but silently drops `origin` and `lastEventId`\n // from the constructor init, yielding `null` and `''`. Both are plain own properties there\n // rather than prototype getters, so they can be assigned after the fact. Elsewhere the\n // constructor honours them and this is skipped, so no runtime pays for it unnecessarily.\n if (messageEvent.origin !== origin) {\n defineEventProperty(messageEvent, 'origin', origin)\n }\n\n if (messageEvent.lastEventId !== lastEventId) {\n defineEventProperty(messageEvent, 'lastEventId', lastEventId)\n }\n\n // The `onmessage` property only triggers on messages without an `event` field, or ones that\n // explicitly set `message`. This is handled automatically: the event is dispatched with type\n // `event.event || 'message'`, and `onmessage` is registered as a `message` event listener.\n this.dispatchEvent(messageEvent)\n }\n\n /**\n * Called by EventSourceParser instance when a new reconnection interval is received\n * from the EventSource endpoint.\n *\n * @param value - The new reconnection interval in milliseconds\n * @internal\n */\n #onRetryChange = (value: number) => {\n this.#reconnectInterval = value\n }\n\n /**\n * Called by EventSourceParser instance when a parse error occurs.\n *\n * @param error - The parser error\n * @internal\n */\n #onParseError = (error: ParseError) => {\n if (error.type !== 'max-buffer-size-exceeded') {\n return\n }\n\n this.close()\n this.#failConnection(error.message)\n }\n\n /**\n * Handles the process referred to in the EventSource specification as \"failing a connection\".\n *\n * @param error - The error causing the connection to fail\n * @param code - The HTTP status code, if available\n * @internal\n */\n #failConnection(message?: string, code?: number) {\n // [spec] \u2026if the readyState attribute is set to a value other than CLOSED,\n // [spec] sets the readyState attribute to CLOSED\u2026\n if (this.#readyState !== this.CLOSED) {\n this.#readyState = this.CLOSED\n }\n\n // [spec] \u2026and fires an event named `error` at the `EventSource` object.\n // [spec] Once the user agent has failed the connection, it does not attempt to reconnect.\n // [spec] > Implementations are especially encouraged to report detailed information\n // [spec] > to their development consoles whenever an error event is fired, since little\n // [spec] > to no information can be made available in the events themselves.\n // Printing to console is not very programatically helpful, though, so we emit a custom event.\n const errorEvent = new ErrorEvent('error', {code, message})\n this.dispatchEvent(errorEvent)\n }\n\n /**\n * Schedules a reconnection attempt against the EventSource endpoint.\n *\n * @param message - The error causing the connection to fail\n * @param code - The HTTP status code, if available\n * @internal\n */\n #scheduleReconnect(message?: string, code?: number) {\n // [spec] If the readyState attribute is set to CLOSED, abort the task.\n if (this.#readyState === this.CLOSED) {\n return\n }\n\n // [spec] Set the readyState attribute to CONNECTING.\n this.#readyState = this.CONNECTING\n\n // [spec] Fire an event named `error` at the EventSource object.\n const errorEvent = new ErrorEvent('error', {code, message})\n this.dispatchEvent(errorEvent)\n\n // [spec] Wait a delay equal to the reconnection time of the event source.\n const timer = setTimeout(this.#reconnect, this.#reconnectInterval)\n\n // In Node.js (and Bun), a pending timer keeps the event loop alive, preventing the\n // process from exiting while we wait to reconnect. `unref()` opts out of that. Browsers\n // and Deno return a numeric handle with no `unref()`, so only call it when available.\n if (typeof timer === 'object' && timer !== null && 'unref' in timer) {\n timer.unref()\n }\n\n this.#reconnectTimer = timer\n }\n\n /**\n * Reconnects to the EventSource endpoint after a disconnect/failure\n *\n * @internal\n */\n #reconnect = () => {\n this.#reconnectTimer = undefined\n\n // [spec] If the EventSource's readyState attribute is not set to CONNECTING, then return.\n if (this.#readyState !== this.CONNECTING) {\n return\n }\n\n this.#connect()\n }\n}\n\n// The class is named `EventSourceImpl` to leave the `EventSource` name free for the interface and\n// the const below. Restore the public name, so neither `EventSource.name` nor inspected instances\n// (eg `console.log(eventSource)`) leak the implementation name.\nObject.defineProperty(EventSourceImpl, 'name', {value: 'EventSource'})\n\n// Provides a way to detect that the EventSource implementation supports passing `fetch`\n// that can be used to customize the request, eg custom headers and similar.\nObject.defineProperty(EventSourceImpl, Symbol.for('eventsource.supports-fetch-override'), {\n value: true,\n writable: false,\n configurable: false,\n enumerable: false,\n})\n\n/**\n * An `EventSource` instance opens a persistent connection to an HTTP server, which sends events\n * in `text/event-stream` format. The connection remains open until closed by calling `.close()`.\n *\n * @public\n * @example\n * ```js\n * const eventSource = new EventSource('https://example.com/stream')\n * eventSource.addEventListener('error', (error) => {\n * console.error(error)\n * })\n * eventSource.addEventListener('message', (event) => {\n * console.log('Received message:', event.data)\n * })\n * ```\n */\nexport const EventSource: EventSourceConstructor = EventSourceImpl\n\n/**\n * According to spec, when constructing a URL:\n * > 1. Let baseURL be environment's base URL, if environment is a Document object\n * > 2. Return the result of applying the URL parser to url, with baseURL.\n *\n * Thus we should use `document.baseURI` if available, since it can be set through a base tag.\n *\n * @returns The base URL, if available - otherwise `undefined`\n * @internal\n */\nfunction getBaseURL(): string | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const doc = 'document' in globalThis ? (globalThis as any).document : undefined\n return doc && typeof doc === 'object' && 'baseURI' in doc && typeof doc.baseURI === 'string'\n ? doc.baseURI\n : undefined\n}\n\n/**\n * Assigns a `MessageEvent` property that the constructor's init dictionary was supposed to have\n * set, for runtimes that ignore it.\n *\n * Defined rather than assigned because on the runtimes that do implement the property as a\n * prototype getter, a plain assignment would throw in strict mode. `enumerable` and\n * `configurable` mirror how a spec-compliant implementation exposes it.\n *\n * @param event - The message event to define the property on\n * @param property - The property to define\n * @param value - The value the constructor should have set\n * @internal\n */\nfunction defineEventProperty(\n event: MessageEvent,\n property: 'origin' | 'lastEventId',\n value: string,\n): void {\n Object.defineProperty(event, property, {\n value,\n enumerable: true,\n configurable: true,\n })\n}\n", "export {ErrorEvent} from './errors.ts'\nexport {EventSource, type EventSourceConstructor} from './EventSource.ts'\nexport type * from './types.ts'\n", "import {\n ITriggerFunctions,\n ITriggerResponse,\n INodeType,\n INodeTypeDescription,\n IDataObject,\n NodeConnectionTypes,\n} from \"n8n-workflow\";\nimport { EventSource, ErrorEvent as EventSourceErrorEvent } from \"eventsource\";\nimport { LoadOptions } from \"../Common/LoadOptions\";\n\nexport class PocketbaseTrigger implements INodeType {\n description: INodeTypeDescription = {\n displayName: \"Pocketbase (Beta) Trigger\",\n name: \"pocketbaseTrigger\",\n icon: { light: \"file:pocketbaseTrigger.svg\", dark: \"file:pocketbaseTrigger.dark.svg\" },\n group: [\"trigger\"],\n version: 1,\n description: \"Handle Pocketbase events via SSE (Beta)\",\n subtitle: '={{$parameter[\"collection\"]}}',\n defaults: {\n name: \"Pocketbase Trigger\",\n },\n inputs: [],\n outputs: [NodeConnectionTypes.Main],\n credentials: [\n {\n name: \"pocketbaseHttpApi\",\n required: true,\n },\n ],\n properties: [\n {\n displayName: 'Collection Name or ID',\n name: \"collection\",\n type: \"options\",\n typeOptions: {\n loadOptionsMethod: \"getCollections\",\n },\n default: \"\",\n required: true,\n description: 'The name of the collection to watch for changes. Choose from the list, or specify an ID using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>.',\n },\n {\n displayName: \"Events\",\n name: \"events\",\n type: \"multiOptions\",\n options: [\n {\n name: \"Create\",\n value: \"create\",\n },\n {\n name: \"Update\",\n value: \"update\",\n },\n {\n name: \"Delete\",\n value: \"delete\",\n },\n ],\n default: [\"create\", \"update\", \"delete\"],\n required: true,\n description: \"The events to trigger the node\",\n },\n ],\n };\n\n methods = {\n loadOptions: LoadOptions,\n };\n\n async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {\n const credentials = await this.getCredentials(\"pocketbaseHttpApi\");\n const baseUrl = (credentials.url as string).replace(/\\/$/, \"\");\n const collection = this.getNodeParameter(\"collection\") as string;\n const events = this.getNodeParameter(\"events\") as string[];\n\n const { closeFunction } = subscribeToPocketbaseSSE.call(this, baseUrl, collection, events);\n\n return {\n closeFunction,\n manualTriggerFunction: async () => {\n const sampleData = {\n __action: \"create\",\n id: \"sample-id\",\n collectionId: \"sample-collection-id\",\n collectionName: collection,\n created: new Date().toISOString(),\n updated: new Date().toISOString(),\n };\n this.emit([this.helpers.returnJsonArray(sampleData)]);\n },\n };\n }\n}\n\nfunction subscribeToPocketbaseSSE(\n this: ITriggerFunctions,\n baseUrl: string,\n collection: string,\n events: string[],\n): { closeFunction: () => Promise<void> } {\n let es: EventSource | null = null;\n let isClosed = false;\n let isReconnecting = false;\n let reconnectTimeout: NodeJS.Timeout | null = null;\n let stabilityTimer: NodeJS.Timeout | null = null;\n let reconnectAttempts = 0;\n const MAX_RECONNECT_ATTEMPTS = 50;\n let consecutiveFailures = 0;\n\n const onConnect = async (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data as string);\n const clientId = data.clientId;\n\n await this.helpers.httpRequestWithAuthentication.call(this, \"pocketbaseHttpApi\", {\n method: \"POST\",\n url: `${baseUrl}/api/realtime`,\n body: {\n clientId,\n subscriptions: [collection],\n },\n });\n\n // Reset counters only after the stream has been stable for a short window\n if (stabilityTimer) clearTimeout(stabilityTimer);\n stabilityTimer = setTimeout(() => {\n reconnectAttempts = 0;\n consecutiveFailures = 0;\n stabilityTimer = null;\n }, 5000);\n } catch (error) {\n this.logger.error(\"Failed to connect to PocketBase SSE\", { error, collection });\n const normalizedError =\n error instanceof Error ? error : new Error(String(error || \"Unknown error during connect\"));\n\n // Only emit on the first consecutive failure to avoid flooding.\n if (consecutiveFailures === 0) {\n this.emitError(normalizedError);\n }\n consecutiveFailures++;\n reconnect();\n }\n };\n\n const onError = (error: EventSourceErrorEvent) => {\n if (stabilityTimer) {\n clearTimeout(stabilityTimer);\n stabilityTimer = null;\n }\n this.logger.error(\"PocketBase SSE connection failure\", {\n error,\n baseUrl,\n });\n\n const normalizedError = new Error(error.message || \"PocketBase SSE connection failure\") as Error & {\n code?: number;\n status?: number;\n originalErrorEvent?: EventSourceErrorEvent;\n };\n // `status` isn't part of eventsource's declared ErrorEvent shape, but the\n // library has been observed attaching it on some HTTP error responses.\n const status = (error as unknown as { status?: number }).status;\n if (error.code) normalizedError.code = error.code;\n if (status) normalizedError.status = status;\n normalizedError.originalErrorEvent = error;\n\n // Only emit error on the first failure. Subsequent reconnect attempts will not flood the error stream.\n if (consecutiveFailures === 0) {\n this.emitError(normalizedError);\n }\n consecutiveFailures++;\n reconnect();\n };\n\n const onMessage = (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data as string);\n if (events.includes(data.action) && data.record) {\n const output: IDataObject & { __original_action?: unknown; __action?: unknown } = {\n ...data.record,\n };\n if (\"action\" in output) {\n output.__original_action = output.action;\n }\n output.__action = data.action;\n\n this.emit([this.helpers.returnJsonArray(output)]);\n }\n } catch (error) {\n const rawData = String(e?.data ?? \"\");\n const redactedPreview = rawData\n .replace(\n /\"(password|token|secret|passwordConfirm|apiKey|accessToken|authorization|bearer)\":\\s*\"(?:[^\"\\\\]|\\\\.)*\"/gi,\n '\"$1\": \"[REDACTED]\"',\n )\n .replace(/\"email\":\\s*\"(?:[^\"\\\\]|\\\\.)*\"/gi, '\"email\": \"[REDACTED]\"')\n .replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g, \"[REDACTED]\")\n .substring(0, 200);\n this.logger.error(\"Failed to parse PocketBase SSE message\", {\n error,\n redactedPreview,\n collection,\n });\n }\n };\n\n const connect = () => {\n if (isClosed) return;\n isReconnecting = false;\n\n es = new EventSource(`${baseUrl}/api/realtime`);\n\n es.addEventListener(\"PB_CONNECT\", onConnect);\n es.addEventListener(\"error\", onError);\n es.addEventListener(collection, onMessage);\n };\n\n const reconnect = () => {\n if (isClosed || isReconnecting) return;\n isReconnecting = true;\n\n if (stabilityTimer) {\n clearTimeout(stabilityTimer);\n stabilityTimer = null;\n }\n\n if (es) {\n es.removeEventListener(\"PB_CONNECT\", onConnect);\n es.removeEventListener(\"error\", onError);\n es.removeEventListener(collection, onMessage);\n es.close();\n es = null;\n }\n\n if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {\n this.logger.error(\"PocketBase trigger permanently closed after max reconnection attempts\", {\n baseUrl,\n collection,\n reconnectAttempts,\n });\n this.emitError(\n new Error(\n `PocketBase SSE: Maximum reconnection attempts (${MAX_RECONNECT_ATTEMPTS}) reached`,\n ),\n );\n isClosed = true;\n isReconnecting = false;\n return;\n }\n\n const baseDelay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);\n const jitter = Math.random() * 1000; // Add 0-1000ms jitter\n const delay = baseDelay + jitter;\n reconnectAttempts++;\n\n reconnectTimeout = setTimeout(connect, delay);\n };\n\n connect();\n\n return {\n closeFunction: async () => {\n isClosed = true;\n if (reconnectTimeout) clearTimeout(reconnectTimeout);\n if (stabilityTimer) {\n clearTimeout(stabilityTimer);\n stabilityTimer = null;\n }\n if (es) {\n es.removeEventListener(\"PB_CONNECT\", onConnect);\n es.removeEventListener(\"error\", onError);\n es.removeEventListener(collection, onMessage);\n es.close();\n }\n },\n };\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuFM,SAAU,YAAY,SAAe;AAKzC,QAAM,eAAgB,WAAmB;AACzC,MAAI,OAAO,iBAAiB,YAAY;AACtC,WAAO,IAAI,aAAa,SAAS,aAAa;EAChD;AAEA,SAAO,IAAI,YAAY,OAAO;AAChC;AAUM,SAAU,aAAa,KAAY;AACvC,MAAI,EAAE,eAAe,QAAQ;AAC3B,WAAO,GAAG,GAAG;EACf;AAEA,MAAI,YAAY,OAAO,MAAM,QAAQ,IAAI,MAAM,GAAG;AAChD,WAAO,IAAI,OAAO,IAAI,YAAY,EAAE,KAAK,IAAI;EAC/C;AAEA,MAAI,WAAW,OAAO,IAAI,iBAAiB,OAAO;AAChD,WAAO,GAAG,GAAG,KAAK,aAAa,IAAI,KAAK,CAAC;EAC3C;AAEA,SAAO,IAAI;AACb;AASA,SAAS,iBAAiB,KAAe;AACvC,SAAO;IACL,MAAM,IAAI;IACV,SAAS,IAAI;IACb,MAAM,IAAI;IACV,kBAAkB,IAAI;IACtB,YAAY,IAAI;IAChB,WAAW,IAAI;;AAEnB;AA5IA,IAOa;AAPb;;AAOM,IAAO,aAAP,cAA0B,MAAK;;;;;;;MAO5B;;;;;;;MAQA;;;;;;;;MASP,YACE,MACA,oBAA8E;AAE9E,cAAM,IAAI;AACV,aAAK,OAAO,oBAAoB,QAAQ;AACxC,aAAK,UAAU,oBAAoB,WAAW;MAChD;;;;;;;;;;;;;MAcA,CAAC,uBAAO,IAAI,4BAA4B,CAAC,EACvC,QACA,SACA,SAAoE;AAEpE,eAAO,QAAQ,iBAAiB,IAAI,GAAG,OAAO;MAChD;;;;;;;;;;;;MAaA,CAAC,uBAAO,IAAI,oBAAoB,CAAC,EAC/B,SACA,SAA0B;AAE1B,eAAO,QAAQ,iBAAiB,IAAI,GAAG,OAAO;MAChD;;;;;;ACtEF,IAKa;AALb,IAAAA,eAAA;;AAKM,IAAO,aAAP,cAA0B,MAAK;MAqBnC,YACE,SACA,SAAyE;AAEzE,cAAM,OAAO;AACb,aAAK,OAAO;AACZ,aAAK,OAAO,QAAQ;AACpB,aAAK,QAAQ,QAAQ;AACrB,aAAK,QAAQ,QAAQ;AACrB,aAAK,OAAO,QAAQ;MACtB;;;;;;ACpBI,SAAU,aAAa,QAAoB;AAC/C,MAAI,OAAO,WAAW,YAAY;AAChC,UAAM,IAAI,UACR,iGAAiG;EAErG;AAEA,QAAM,EAAC,eAAe,WAAW,SAAS,SAAS,MAAM,QAAO,IAAI;AAQpE,QAAM,mBAA6B,CAAA;AAInC,MAAI,yBAAyB;AAE7B,MAAI,eAAe;AACnB,MAAI;AACJ,MAAI,OAAO;AACX,MAAI,YAAY;AAChB,MAAI;AAIJ,MAAI,aAAa;AACjB,MAAI,eAAe;AAQnB,MAAI,mBAAmB;AAevB,WAAS,KAAK,OAAa;AACzB,QAAI,YAAY;AACd,YAAM,IAAI,MACR,yHAAyH;IAE7H;AAEA,QAAI,cAAc;AAChB,qBAAe;AAQf,UAAI,MAAM,WAAW,CAAC,MAAM,OAAQ;AAClC,gBAAQ,MAAM,MAAM,CAAC;MACvB,WACE,MAAM,WAAW,CAAC,MAAM,OACxB,MAAM,WAAW,CAAC,MAAM,OACxB,MAAM,WAAW,CAAC,MAAM,KACxB;AACA,gBAAQ,MAAM,MAAM,CAAC;MACvB;IACF;AAKA,QAAI,gBAAgB,kBAAkB;AACpC,cAAQ,gBAAgB,KAAK;AAC7B,UAAI,CAAC,OAAO;AACV;MACF;IACF;AAKA,QAAI,CAAC,iBAAiB,QAAQ;AAC5B,YAAM,WAAW,aAAa,KAAK;AACnC,UAAI,aAAa,IAAI;AACnB,sBAAc,QAAQ;MACxB;AACA,sBAAe;AACf;IACF;AAKA,QAAI,MAAM,QAAQ,IAAI,MAAM,MAAM,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC5D,UAAI,yBAAyB,yBAAyB;AACpD,cAAM,OACJ,iBAAiB,KAAK,EAAE,IACxB,MAAM,MAAM,GAAG,0BAA0B,sBAAsB;AACjE,YAAI,CAAC,qBAAqB,IAAI,GAAG;AAC/B,2BAAiB,SAAS;AAC1B,mCAAyB;AACzB,yBAAe;AACf;QACF;MACF;AACA,uBAAiB,KAAK,KAAK;AAC3B,gCAA0B,MAAM;AAChC,sBAAe;AACf;IACF;AAIA,qBAAiB,KAAK,KAAK;AAC3B,UAAM,QAAQ,iBAAiB,KAAK,EAAE;AACtC,qBAAiB,SAAS;AAC1B,6BAAyB;AACzB,kBAAc,aAAa,KAAK,CAAC;AACjC,oBAAe;EACjB;AAQA,WAAS,gBAAgB,OAAa;AACpC,QAAI,MAAM,WAAW,GAAG;AACtB,aAAO;IACT;AAEA,QAAI,kBAAkB;AACpB,yBAAmB;AACnB,aAAO,MAAM,WAAW,CAAC,MAAM,KAAK,MAAM,MAAM,CAAC,IAAI;IACvD;AAEA,UAAM,UAAU,MAAM,QAAQ,IAAI;AAClC,UAAM,UAAU,MAAM,QAAQ,IAAI;AAClC,UAAM,UACJ,YAAY,KAAK,UAAU,YAAY,KAAK,UAAU,UAAU,UAAU,UAAU;AAEtF,QAAI,YAAY,IAAI;AAClB,aAAO;IACT;AAIA,QAAI,YAAY,MAAM,SAAS,KAAK,MAAM,WAAW,OAAO,MAAM,IAAI;AACpE,qBAAe;AACf,yBAAmB;AACnB,aAAO;IACT;AAEA,mBAAe;AACf,WAAO,MAAM,MACX,WAAW,MAAM,WAAW,OAAO,MAAM,MAAM,MAAM,WAAW,UAAU,CAAC,MAAM,KAAK,IAAI,EAAE;EAEhG;AAEA,WAAS,cAAc,UAAgB;AACrC,QAAI,CAAC;AAAU;AAOf,QAAI,SAAS,WAAW,SAAS,SAAS,CAAC,MAAM,IAAI;AACnD,gBAAU,UAAU,GAAG,SAAS,SAAS,CAAC;AAC1C,yBAAmB;AACnB;IACF;AAEA,QAAI,qBAAqB,QAAQ,GAAG;AAClC,uBAAiB,KAAK,QAAQ;AAC9B,+BAAyB,SAAS;AAClC;IACF;AAEA,mBAAe;EACjB;AAEA,WAAS,qBAAqB,UAAgB;AAC5C,UAAM,gBAAgB,SAAS,WAAW,CAAC;AAC3C,WACG,kBAAkB,MAAM,CAAC,CAAC,aAC1B,kBAAkB,OAAO,iBAAiB,UAAU,MAAM,KAC1D,kBAAkB,OAAO,iBAAiB,UAAU,OAAO,KAC3D,kBAAkB,OAAO,iBAAiB,UAAU,IAAI,KACxD,kBAAkB,OAAO,iBAAiB,UAAU,OAAO;EAEhE;AAEA,WAAS,kBAAe;AACtB,QAAI,kBAAkB;AAAW;AACjC,QAAI,yBAAyB,KAAK,UAAU;AAAe;AAE3D,iBAAa;AACb,qBAAiB,SAAS;AAC1B,6BAAyB;AACzB,SAAK;AACL,WAAO;AACP,gBAAY;AACZ,gBAAY;AACZ,mBAAe;AACf,uBAAmB;AACnB,gBAAO,QAAP,YAAO,SAAA,SAAP,QACE,IAAI,WAAW,6CAA6C,aAAa,eAAe;MACtF,MAAM;KACP,CAAC;EAEN;AAWA,WAAS,aAAa,OAAa;AACjC,QAAI,cAAc;AAMlB,QAAI,MAAM,QAAQ,IAAI,MAAM,IAAI;AAC9B,UAAI,UAAU,MAAM,QAAQ,MAAM,WAAW;AAC7C,aAAO,YAAY,IAAI;AAIrB,YAAI,gBAAgB,SAAS;AAC3B,cAAI,OAAO,QAAW;AACpB,qBAAI,QAAJ,SAAI,SAAA,SAAJ,KAAO,EAAE;UACX;AACA,cAAI,YAAY,GAAG;AACjB,wBAAO,QAAP,YAAO,SAAA,SAAP,QAAU,EAAC,IAAI,OAAO,WAAW,KAAI,CAAC;UACxC;AACA,eAAK;AACL,iBAAO;AACP,sBAAY;AACZ,sBAAY;AACZ,wBAAc,UAAU;AACxB,oBAAU,MAAM,QAAQ,MAAM,WAAW;AACzC;QACF;AACA,cAAM,gBAAgB,MAAM,WAAW,WAAW;AAClD,YAAI,aAAa,OAAO,aAAa,aAAa,GAAG;AAGnD,gBAAM,aACJ,MAAM,WAAW,cAAc,CAAC,MAAM,QAAQ,cAAc,IAAI,cAAc;AAChF,gBAAM,QAAQ,MAAM,MAAM,YAAY,OAAO;AAM7C,cAAI,cAAc,KAAK,MAAM,WAAW,UAAU,CAAC,MAAM,IAAI;AAC3D,gBAAI,OAAO,QAAW;AACpB,uBAAI,QAAJ,SAAI,SAAA,SAAJ,KAAO,EAAE;YACX;AACA,wBAAO,QAAP,YAAO,SAAA,SAAP,QAAU,EAAC,IAAI,OAAO,WAAW,MAAM,MAAK,CAAC;AAC7C,iBAAK;AACL,mBAAO;AACP,wBAAY;AACZ,0BAAc,UAAU;AACxB,sBAAU,MAAM,QAAQ,MAAM,WAAW;AACzC;UACF;AAEA,iBAAO,cAAc,IAAI,QAAQ,GAAG,IAAI;EAAK,KAAK;AAClD;QACF,WAAW,cAAc,OAAO,aAAa,aAAa,GAAG;AAI3D,sBACE,MAAM,MACJ,MAAM,WAAW,cAAc,CAAC,MAAM,QAAQ,cAAc,IAAI,cAAc,GAC9E,OAAO,KACJ;QACT,OAAO;AAIL,oBAAU,OAAO,aAAa,OAAO;QACvC;AACA,sBAAc,UAAU;AACxB,kBAAU,MAAM,QAAQ,MAAM,WAAW;MAC3C;AACA,aAAO,MAAM,MAAM,WAAW;IAChC;AAKA,WAAO,cAAc,MAAM,QAAQ;AACjC,YAAM,UAAU,MAAM,QAAQ,MAAM,WAAW;AAC/C,YAAM,UAAU,MAAM,QAAQ,MAAM,WAAW;AAE/C,UAAI,UAAU;AACd,UAAI,YAAY,MAAM,YAAY,IAAI;AACpC,kBAAU,UAAU,UAAU,UAAU;MAC1C,WAAW,YAAY,IAAI;AAIzB,YAAI,YAAY,MAAM,SAAS,GAAG;AAChC,oBAAU;QACZ,OAAO;AACL,oBAAU;QACZ;MACF,WAAW,YAAY,IAAI;AACzB,kBAAU;MACZ;AAEA,UAAI,YAAY,IAAI;AAClB;MACF;AAEA,gBAAU,OAAO,aAAa,OAAO;AACrC,oBAAc,UAAU;AAGxB,UAAI,MAAM,WAAW,cAAc,CAAC,MAAM,MAAM,MAAM,WAAW,WAAW,MAAM,IAAI;AACpF;MACF;IACF;AAEA,WAAO,MAAM,MAAM,WAAW;EAChC;AAEA,WAAS,UAAU,OAAe,OAAe,KAAW;AAC1D,QAAI,UAAU,KAAK;AACjB,oBAAa;AACb;IACF;AAEA,UAAM,gBAAgB,MAAM,WAAW,KAAK;AAE5C,QAAI,aAAa,OAAO,OAAO,aAAa,GAAG;AAE7C,YAAM,aAAa,MAAM,WAAW,QAAQ,CAAC,MAAM,QAAQ,QAAQ,IAAI,QAAQ;AAC/E,YAAMC,SAAQ,MAAM,MAAM,YAAY,GAAG;AACzC,aAAO,cAAc,IAAIA,SAAQ,GAAG,IAAI;EAAKA,MAAK;AAClD;AACA;IACF;AAEA,QAAI,cAAc,OAAO,OAAO,aAAa,GAAG;AAE9C,kBACE,MAAM,MAAM,MAAM,WAAW,QAAQ,CAAC,MAAM,QAAQ,QAAQ,IAAI,QAAQ,GAAG,GAAG,KAAK;AACrF;IACF;AAGA,QACE,kBAAkB,OAClB,MAAM,WAAW,QAAQ,CAAC,MAAM,OAChC,MAAM,WAAW,QAAQ,CAAC,MAAM,IAChC;AAEA,YAAMA,SAAQ,MAAM,MAAM,MAAM,WAAW,QAAQ,CAAC,MAAM,QAAQ,QAAQ,IAAI,QAAQ,GAAG,GAAG;AAG5F,UAAI,CAACA,OAAM,SAAS,IAAI;AAAG,aAAKA;AAChC;IACF;AAGA,QAAI,kBAAkB,IAAI;AACxB,UAAI,WAAW;AACb,cAAMC,QAAO,MAAM,MAAM,OAAO,GAAG;AAEnC,kBAAUA,MAAK,MAAM,MAAM,WAAW,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAC;MACrE;AACA;IACF;AAEA,UAAM,OAAO,MAAM,MAAM,OAAO,GAAG;AACnC,UAAM,sBAAsB,KAAK,QAAQ,GAAG;AAC5C,QAAI,wBAAwB,IAAI;AAC9B,mBAAa,MAAM,IAAI,IAAI;AAC3B;IACF;AAEA,UAAM,QAAQ,KAAK,MAAM,GAAG,mBAAmB;AAE/C,UAAM,SAAS,KAAK,WAAW,sBAAsB,CAAC,MAAM,QAAQ,IAAI;AACxE,UAAM,QAAQ,KAAK,MAAM,sBAAsB,MAAM;AACrD,iBAAa,OAAO,OAAO,IAAI;EACjC;AAEA,WAAS,aAAa,OAAe,OAAe,MAAY;AAE9D,YAAQ,OAAO;MACb,KAAK;AAEH,oBAAY,SAAS;AACrB;MACF,KAAK;AACH,eAAO,cAAc,IAAI,QAAQ,GAAG,IAAI;EAAK,KAAK;AAClD;AACA;MACF,KAAK;AAGH,YAAI,CAAC,MAAM,SAAS,IAAI;AAAG,eAAK;AAChC;MACF,KAAK;AAIH,YAAI,QAAQ,KAAK,KAAK,GAAG;AACvB,sBAAO,QAAP,YAAO,SAAA,SAAP,QAAU,SAAS,OAAO,EAAE,CAAC;QAC/B,OAAO;AACL,sBAAO,QAAP,YAAO,SAAA,SAAP,QACE,IAAI,WAAW,6BAA6B,KAAK,KAAK;YACpD,MAAM;YACN;YACA;WACD,CAAC;QAEN;AACA;MACF;AAEE,oBAAO,QAAP,YAAO,SAAA,SAAP,QACE,IAAI,WACF,kBAAkB,MAAM,SAAS,KAAK,GAAG,MAAM,MAAM,GAAG,EAAE,CAAC,WAAM,KAAK,KACtE,EAAC,MAAM,iBAAiB,OAAO,OAAO,KAAI,CAAC,CAC5C;AAEH;IACJ;EACF;AAEA,WAAS,gBAAa;AACpB,QAAI,OAAO,QAAW;AACpB,eAAI,QAAJ,SAAI,SAAA,SAAJ,KAAO,EAAE;IACX;AAEA,QAAI,YAAY,GAAG;AACjB,kBAAO,QAAP,YAAO,SAAA,SAAP,QAAU;QACR;QACA,OAAO;QACP;OACD;IACH;AAEA,SAAK;AACL,WAAO;AACP,gBAAY;AACZ,gBAAY;EACd;AAEA,WAAS,MAAM,UAA+B,CAAA,GAAE;AAC9C,QAAI,QAAQ,WAAW,iBAAiB,SAAS,GAAG;AAClD,YAAM,iBAAiB,iBAAiB,KAAK,EAAE;AAC/C,gBAAU,gBAAgB,GAAG,eAAe,MAAM;IACpD;AAEA,mBAAe;AACf,SAAK;AACL,WAAO;AACP,gBAAY;AACZ,gBAAY;AACZ,qBAAiB,SAAS;AAC1B,6BAAyB;AACzB,iBAAa;AACb,mBAAe;AACf,uBAAmB;EACrB;AAEA,SAAO,EAAC,MAAM,MAAK;AACrB;AAYA,SAAS,aAAa,OAAe,GAAW,eAAqB;AACnE,SACE,kBAAkB,OAClB,MAAM,WAAW,IAAI,CAAC,MAAM,MAC5B,MAAM,WAAW,IAAI,CAAC,MAAM,OAC5B,MAAM,WAAW,IAAI,CAAC,MAAM,MAC5B,MAAM,WAAW,IAAI,CAAC,MAAM;AAEhC;AAUA,SAAS,cAAc,OAAe,GAAW,eAAqB;AACpE,SACE,kBAAkB,OAClB,MAAM,WAAW,IAAI,CAAC,MAAM,OAC5B,MAAM,WAAW,IAAI,CAAC,MAAM,OAC5B,MAAM,WAAW,IAAI,CAAC,MAAM,OAC5B,MAAM,WAAW,IAAI,CAAC,MAAM,OAC5B,MAAM,WAAW,IAAI,CAAC,MAAM;AAEhC;AAEA,SAAS,iBAAiB,MAAc,OAAa;AACnD,MAAI,IAAI;AACR,SAAO,IAAI,KAAK,UAAU,IAAI,MAAM,QAAQ;AAC1C,QAAI,KAAK,WAAW,CAAC,MAAM,MAAM,WAAW,CAAC,GAAG;AAC9C,aAAO;IACT;AACA;EACF;AAEA,SAAO,KAAK,UAAU,MAAM,UAAU,KAAK,WAAW,MAAM,MAAM,MAAM;AAC1E;AAvjBA,IAQM,IACA,IACA,OACA;AAXN;;AAIA,IAAAC;AAIA,IAAM,KAAK;AACX,IAAM,KAAK;AACX,IAAM,QAAQ;AACd,IAAM,0BAA0B;;;;;ACXhC;;AACA;;;;;ACuwBA,SAAS,aAAU;AAEjB,QAAM,MAAM,cAAc,aAAc,WAAmB,WAAW;AACtE,SAAO,OAAO,OAAO,QAAQ,YAAY,aAAa,OAAO,OAAO,IAAI,YAAY,WAChF,IAAI,UACJ;AACN;AAeA,SAAS,oBACP,OACA,UACA,OAAa;AAEb,SAAO,eAAe,OAAO,UAAU;IACrC;IACA,YAAY;IACZ,cAAc;GACf;AACH;AAvyBA,IAmBM,yBAmKA,iBAskBO;AA5vBb;;;AAOA;AAYA,IAAM,0BAA0B,MAAM,OAAO;AAmK7C,IAAM,kBAAN,cAA8B,YAAW;MACvC,OAAO,aAAa;MACpB,OAAO,OAAO;MACd,OAAO,SAAS;MAEP,aAAa;MACb,OAAO;MACP,SAAS;MAElB,IAAW,aAAU;AACnB,eAAO,KAAK;MACd;MAEA,IAAW,MAAG;AACZ,eAAO,KAAK,KAAK;MACnB;MAEA,IAAW,kBAAe;AACxB,eAAO,KAAK;MACd;MAEA,IAAW,UAAO;AAChB,eAAO,KAAK;MACd;MACA,IAAW,QAAQ,OAA8D;AAC/E,YAAI,KAAK,UAAU;AACjB,eAAK,oBAAoB,SAAS,KAAK,QAAQ;QACjD;AACA,aAAK,WAAW;AAChB,YAAI,OAAO;AACT,eAAK,iBAAiB,SAAS,KAAK;QACtC;MACF;MAEA,IAAW,YAAS;AAClB,eAAO,KAAK;MACd;MACA,IAAW,UAAU,OAAgE;AACnF,YAAI,KAAK,YAAY;AACnB,eAAK,oBAAoB,WAAW,KAAK,UAAU;QACrD;AACA,aAAK,aAAa;AAClB,YAAI,OAAO;AACT,eAAK,iBAAiB,WAAW,KAAK;QACxC;MACF;MAEA,IAAW,SAAM;AACf,eAAO,KAAK;MACd;MACA,IAAW,OAAO,OAAyD;AACzE,YAAI,KAAK,SAAS;AAChB,eAAK,oBAAoB,QAAQ,KAAK,OAAO;QAC/C;AACA,aAAK,UAAU;AACf,YAAI,OAAO;AACT,eAAK,iBAAiB,QAAQ,KAAK;QACrC;MACF;MAiBS,iBACP,MACA,UAGA,SAA2C;AAE3C,cAAM,SAAS;AACf,cAAM,iBAAiB,MAAM,QAAQ,OAAO;MAC9C;MAiBS,oBACP,MACA,UAGA,SAAwC;AAExC,cAAM,SAAS;AACf,cAAM,oBAAoB,MAAM,QAAQ,OAAO;MACjD;MAEA,YAAY,KAAmB,qBAAqC;AAClE,cAAK;AAEL,YAAI;AACF,cAAI,eAAe,KAAK;AACtB,iBAAK,OAAO;UACd,WAAW,OAAO,QAAQ,UAAU;AAClC,iBAAK,OAAO,IAAI,IAAI,KAAK,WAAU,CAAE;UACvC,OAAO;AACL,kBAAM,IAAI,MAAM,aAAa;UAC/B;QACF,QAAQ;AACN,gBAAM,YAAY,4CAA4C;QAChE;AAEA,aAAK,UAAU,aAAa;UAC1B,eAAe,qBAAqB,iBAAiB;UACrD,SAAS,KAAK;UACd,SAAS,KAAK;UACd,MAAM,KAAK;UACX,SAAS,KAAK;SACf;AAED,aAAK,cAAc,KAAK;AACxB,aAAK,qBAAqB;AAC1B,aAAK,SAAS,qBAAqB,SAAS,WAAW;AACvD,aAAK,mBAAmB,qBAAqB,mBAAmB;AAEhE,aAAK,SAAQ;MACf;MAEA,QAAK;AACH,YAAI,KAAK;AAAiB,uBAAa,KAAK,eAAe;AAC3D,YAAI,KAAK,gBAAgB,KAAK;AAAQ;AACtC,YAAI,KAAK;AAAa,eAAK,YAAY,MAAK;AAC5C,aAAK,cAAc,KAAK;AACxB,aAAK,cAAc;MACrB;;;;;;;MASA;;;;;;;;MASA;;;;;;MAOA;;;;;;MAOA;;;;;;MAOA;;;;;;MAOA;;;;;;MAOA;;;;;;;MAQA,eAA8B;;;;;;MAO9B;;;;;;MAOA;;;;;;;MAQA,WAAoE;;;;;;;MAQpE,aAAwE;;;;;;;MAQxE,UAA8D;;;;;;MAO9D,WAAQ;AACN,aAAK,cAAc,KAAK;AACxB,aAAK,cAAc,IAAI,gBAAe;AAGtC,cAAM,QAAQ,KAAK;AACnB,cAAM,KAAK,MAAM,KAAK,mBAAkB,CAAE,EACvC,KAAK,KAAK,gBAAgB,EAC1B,MAAM,KAAK,aAAa;MAC7B;;;;;;;MAQA,mBAAmB,OAAO,aAA+B;AACvD,aAAK,QAAQ,MAAK;AAElB,cAAM,EAAC,MAAM,YAAY,QAAQ,QAAO,IAAI;AAG5C,YAAI,WAAW,KAAK;AAGlB,eAAK,gBAAgB,0CAA0C,GAAG;AAClE,eAAK,MAAK;AACV;QACF;AAMA,YAAI,YAAY;AACd,eAAK,eAAe,IAAI,IAAI,SAAS,GAAG;QAC1C,OAAO;AACL,eAAK,eAAe;QACtB;AAGA,YAAI,WAAW,KAAK;AAClB,eAAK,gBAAgB,wBAAwB,MAAM,KAAK,MAAM;AAC9D;QACF;AAGA,cAAM,cAAc,QAAQ,IAAI,cAAc,KAAK;AACnD,YAAI,CAAC,YAAY,WAAW,mBAAmB,GAAG;AAChD,eAAK,gBAAgB,sDAAsD,MAAM;AACjF;QACF;AAGA,YAAI,KAAK,gBAAgB,KAAK,QAAQ;AACpC;QACF;AAIA,aAAK,cAAc,KAAK;AAExB,cAAM,YAAY,IAAI,MAAM,MAAM;AAClC,aAAK,cAAc,SAAS;AAG5B,YAAI,OAAO,SAAS,YAAY,CAAC,QAAQ,EAAE,eAAe,OAAO;AAC/D,eAAK,gBAAgB,wDAAwD,MAAM;AACnF,eAAK,MAAK;AACV;QACF;AAEA,cAAM,UAAU,IAAI,YAAW;AAE/B,cAAM,SAAS,KAAK,UAAS;AAC7B,YAAI,OAAO;AAEX,WAAG;AACD,gBAAM,EAAC,MAAM,MAAK,IAAI,MAAM,OAAO,KAAI;AACvC,cAAI,KAAK,gBAAgB,KAAK,QAAQ;AACpC,mBAAO;AACP;UACF;AAEA,cAAI,OAAO;AACT,iBAAK,QAAQ,KAAK,QAAQ,OAAO,OAAO,EAAC,QAAQ,CAAC,KAAI,CAAC,CAAC;UAC1D;AAEA,cAAI,CAAC,MAAM;AACT;UACF;AAEA,iBAAO;AACP,eAAK,QAAQ,MAAK;AAElB,eAAK,mBAAkB;QACzB,SAAS;MACX;;;;;;;MAQA,gBAAgB,CAAC,QAAgC;AAC/C,aAAK,cAAc;AAGnB,YAAI,IAAI,SAAS,gBAAgB,IAAI,SAAS,WAAW;AACvD;QACF;AAEA,aAAK,mBAAmB,aAAa,GAAG,CAAC;MAC3C;;;;;;;MAQA,qBAAkB;AAChB,cAAM,YAAY,KAAK,eAAe,EAAC,iBAAiB,KAAK,aAAY,IAAI;AAE7E,cAAM,OAA6B;;;UAGjC,MAAM;UACN,UAAU;UACV,SAAS,EAAC,QAAQ,qBAAqB,GAAG,UAAS;UACnD,OAAO;UACP,QAAQ,KAAK,aAAa;;AAK5B,YAAI,YAAY,YAAY;AAG1B,eAAK,cAAc,KAAK,kBAAkB,YAAY;QACxD;AAEA,eAAO;MACT;;;;;;;;MASA,cAAc,CAAC,UAAiB;AAC9B,aAAK,eAAe;MACtB;;;;;;;;MASA,WAAW,CAAC,UAA6B;AACvC,cAAM,SAAS,KAAK,eAAe,KAAK,aAAa,SAAS,KAAK,KAAK;AAKxE,cAAM,cAAc,KAAK,gBAAgB;AAEzC,cAAM,eAAe,IAAI,aAAa,MAAM,SAAS,WAAW;UAC9D,MAAM,MAAM;UACZ;UACA;SACD;AAMD,YAAI,aAAa,WAAW,QAAQ;AAClC,8BAAoB,cAAc,UAAU,MAAM;QACpD;AAEA,YAAI,aAAa,gBAAgB,aAAa;AAC5C,8BAAoB,cAAc,eAAe,WAAW;QAC9D;AAKA,aAAK,cAAc,YAAY;MACjC;;;;;;;;MASA,iBAAiB,CAAC,UAAiB;AACjC,aAAK,qBAAqB;MAC5B;;;;;;;MAQA,gBAAgB,CAAC,UAAqB;AACpC,YAAI,MAAM,SAAS,4BAA4B;AAC7C;QACF;AAEA,aAAK,MAAK;AACV,aAAK,gBAAgB,MAAM,OAAO;MACpC;;;;;;;;MASA,gBAAgB,SAAkB,MAAa;AAG7C,YAAI,KAAK,gBAAgB,KAAK,QAAQ;AACpC,eAAK,cAAc,KAAK;QAC1B;AAQA,cAAM,aAAa,IAAI,WAAW,SAAS,EAAC,MAAM,QAAO,CAAC;AAC1D,aAAK,cAAc,UAAU;MAC/B;;;;;;;;MASA,mBAAmB,SAAkB,MAAa;AAEhD,YAAI,KAAK,gBAAgB,KAAK,QAAQ;AACpC;QACF;AAGA,aAAK,cAAc,KAAK;AAGxB,cAAM,aAAa,IAAI,WAAW,SAAS,EAAC,MAAM,QAAO,CAAC;AAC1D,aAAK,cAAc,UAAU;AAG7B,cAAM,QAAQ,WAAW,KAAK,YAAY,KAAK,kBAAkB;AAKjE,YAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,WAAW,OAAO;AACnE,gBAAM,MAAK;QACb;AAEA,aAAK,kBAAkB;MACzB;;;;;;MAOA,aAAa,MAAK;AAChB,aAAK,kBAAkB;AAGvB,YAAI,KAAK,gBAAgB,KAAK,YAAY;AACxC;QACF;AAEA,aAAK,SAAQ;MACf;;AAMF,WAAO,eAAe,iBAAiB,QAAQ,EAAC,OAAO,cAAa,CAAC;AAIrE,WAAO,eAAe,iBAAiB,uBAAO,IAAI,qCAAqC,GAAG;MACxF,OAAO;MACP,UAAU;MACV,cAAc;MACd,YAAY;KACb;AAkBM,IAAM,cAAsC;;;;;AC5vBnD;;;;;IAAAC,aAAA;;;AACA;;;;;;;ACDA,IAAA,iBAAA,QAAA,cAAA;AAQA,IAAA,gBAAA;AACA,IAAA,gBAAA,QAAA,uBAAA;AAEA,IAAa,oBAAb,MAA8B;EAA9B,cAAA;AACE,SAAA,cAAoC;MAClC,aAAa;MACb,MAAM;MACN,MAAM,EAAE,OAAO,8BAA8B,MAAM,kCAAiC;MACpF,OAAO,CAAC,SAAS;MACjB,SAAS;MACT,aAAa;MACb,UAAU;MACV,UAAU;QACR,MAAM;;MAER,QAAQ,CAAA;MACR,SAAS,CAAC,eAAA,oBAAoB,IAAI;MAClC,aAAa;QACX;UACE,MAAM;UACN,UAAU;;;MAGd,YAAY;QACV;UACE,aAAa;UACb,MAAM;UACN,MAAM;UACN,aAAa;YACX,mBAAmB;;UAErB,SAAS;UACT,UAAU;UACV,aAAa;;QAEf;UACE,aAAa;UACb,MAAM;UACN,MAAM;UACN,SAAS;YACP;cACE,MAAM;cACN,OAAO;;YAET;cACE,MAAM;cACN,OAAO;;YAET;cACE,MAAM;cACN,OAAO;;;UAGX,SAAS,CAAC,UAAU,UAAU,QAAQ;UACtC,UAAU;UACV,aAAa;;;;AAKnB,SAAA,UAAU;MACR,aAAa,cAAA;;EA0BjB;EAvBE,MAAM,UAAO;AACX,UAAM,cAAc,MAAM,KAAK,eAAe,mBAAmB;AACjE,UAAM,UAAW,YAAY,IAAe,QAAQ,OAAO,EAAE;AAC7D,UAAM,aAAa,KAAK,iBAAiB,YAAY;AACrD,UAAM,SAAS,KAAK,iBAAiB,QAAQ;AAE7C,UAAM,EAAE,cAAa,IAAK,yBAAyB,KAAK,MAAM,SAAS,YAAY,MAAM;AAEzF,WAAO;MACL;MACA,uBAAuB,YAAW;AAChC,cAAM,aAAa;UACjB,UAAU;UACV,IAAI;UACJ,cAAc;UACd,gBAAgB;UAChB,UAAS,oBAAI,KAAI,GAAG,YAAW;UAC/B,UAAS,oBAAI,KAAI,GAAG,YAAW;;AAEjC,aAAK,KAAK,CAAC,KAAK,QAAQ,gBAAgB,UAAU,CAAC,CAAC;MACtD;;EAEJ;;AAnFF,QAAA,oBAAA;AAsFA,SAAS,yBAEP,SACA,YACA,QAAgB;AAEhB,MAAI,KAAyB;AAC7B,MAAI,WAAW;AACf,MAAI,iBAAiB;AACrB,MAAI,mBAA0C;AAC9C,MAAI,iBAAwC;AAC5C,MAAI,oBAAoB;AACxB,QAAM,yBAAyB;AAC/B,MAAI,sBAAsB;AAE1B,QAAM,YAAY,OAAO,MAAmB;AAC1C,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,EAAE,IAAc;AACxC,YAAM,WAAW,KAAK;AAEtB,YAAM,KAAK,QAAQ,8BAA8B,KAAK,MAAM,qBAAqB;QAC/E,QAAQ;QACR,KAAK,GAAG,OAAO;QACf,MAAM;UACJ;UACA,eAAe,CAAC,UAAU;;OAE7B;AAGD,UAAI;AAAgB,qBAAa,cAAc;AAC/C,uBAAiB,WAAW,MAAK;AAC/B,4BAAoB;AACpB,8BAAsB;AACtB,yBAAiB;MACnB,GAAG,GAAI;IACT,SAAS,OAAO;AACd,WAAK,OAAO,MAAM,uCAAuC,EAAE,OAAO,WAAU,CAAE;AAC9E,YAAM,kBACJ,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,SAAS,8BAA8B,CAAC;AAG5F,UAAI,wBAAwB,GAAG;AAC7B,aAAK,UAAU,eAAe;MAChC;AACA;AACA,gBAAS;IACX;EACF;AAEA,QAAM,UAAU,CAAC,UAAgC;AAC/C,QAAI,gBAAgB;AAClB,mBAAa,cAAc;AAC3B,uBAAiB;IACnB;AACA,SAAK,OAAO,MAAM,qCAAqC;MACrD;MACA;KACD;AAED,UAAM,kBAAkB,IAAI,MAAM,MAAM,WAAW,mCAAmC;AAOtF,UAAM,SAAU,MAAyC;AACzD,QAAI,MAAM;AAAM,sBAAgB,OAAO,MAAM;AAC7C,QAAI;AAAQ,sBAAgB,SAAS;AACrC,oBAAgB,qBAAqB;AAGrC,QAAI,wBAAwB,GAAG;AAC7B,WAAK,UAAU,eAAe;IAChC;AACA;AACA,cAAS;EACX;AAEA,QAAM,YAAY,CAAC,MAAmB;;AACpC,QAAI;AACF,YAAM,OAAO,KAAK,MAAM,EAAE,IAAc;AACxC,UAAI,OAAO,SAAS,KAAK,MAAM,KAAK,KAAK,QAAQ;AAC/C,cAAM,SAA4E;UAChF,GAAG,KAAK;;AAEV,YAAI,YAAY,QAAQ;AACtB,iBAAO,oBAAoB,OAAO;QACpC;AACA,eAAO,WAAW,KAAK;AAEvB,aAAK,KAAK,CAAC,KAAK,QAAQ,gBAAgB,MAAM,CAAC,CAAC;MAClD;IACF,SAAS,OAAO;AACd,YAAM,UAAU,QAAO,KAAA,MAAC,QAAD,MAAC,SAAA,SAAD,EAAG,UAAI,QAAA,OAAA,SAAA,KAAI,EAAE;AACpC,YAAM,kBAAkB,QACrB,QACC,4GACA,oBAAoB,EAErB,QAAQ,kCAAkC,uBAAuB,EACjE,QAAQ,mDAAmD,YAAY,EACvE,UAAU,GAAG,GAAG;AACnB,WAAK,OAAO,MAAM,0CAA0C;QAC1D;QACA;QACA;OACD;IACH;EACF;AAEA,QAAM,UAAU,MAAK;AACnB,QAAI;AAAU;AACd,qBAAiB;AAEjB,SAAK,IAAI,cAAA,YAAY,GAAG,OAAO,eAAe;AAE9C,OAAG,iBAAiB,cAAc,SAAS;AAC3C,OAAG,iBAAiB,SAAS,OAAO;AACpC,OAAG,iBAAiB,YAAY,SAAS;EAC3C;AAEA,QAAM,YAAY,MAAK;AACrB,QAAI,YAAY;AAAgB;AAChC,qBAAiB;AAEjB,QAAI,gBAAgB;AAClB,mBAAa,cAAc;AAC3B,uBAAiB;IACnB;AAEA,QAAI,IAAI;AACN,SAAG,oBAAoB,cAAc,SAAS;AAC9C,SAAG,oBAAoB,SAAS,OAAO;AACvC,SAAG,oBAAoB,YAAY,SAAS;AAC5C,SAAG,MAAK;AACR,WAAK;IACP;AAEA,QAAI,qBAAqB,wBAAwB;AAC/C,WAAK,OAAO,MAAM,yEAAyE;QACzF;QACA;QACA;OACD;AACD,WAAK,UACH,IAAI,MACF,kDAAkD,sBAAsB,WAAW,CACpF;AAEH,iBAAW;AACX,uBAAiB;AACjB;IACF;AAEA,UAAM,YAAY,KAAK,IAAI,MAAO,KAAK,IAAI,GAAG,iBAAiB,GAAG,GAAK;AACvE,UAAM,SAAS,KAAK,OAAM,IAAK;AAC/B,UAAM,QAAQ,YAAY;AAC1B;AAEA,uBAAmB,WAAW,SAAS,KAAK;EAC9C;AAEA,UAAO;AAEP,SAAO;IACL,eAAe,YAAW;AACxB,iBAAW;AACX,UAAI;AAAkB,qBAAa,gBAAgB;AACnD,UAAI,gBAAgB;AAClB,qBAAa,cAAc;AAC3B,yBAAiB;MACnB;AACA,UAAI,IAAI;AACN,WAAG,oBAAoB,cAAc,SAAS;AAC9C,WAAG,oBAAoB,SAAS,OAAO;AACvC,WAAG,oBAAoB,YAAY,SAAS;AAC5C,WAAG,MAAK;MACV;IACF;;AAEJ;",
|
|
4
|
+
"sourcesContent": ["/**\n * An extended version of the `Event` emitted by the `EventSource` object when an error occurs.\n * While the spec does not include any additional properties, we intentionally go beyond the spec\n * and provide some (minimal) additional information to aid in debugging.\n *\n * @public\n */\nexport class ErrorEvent extends Event {\n /**\n * HTTP status code, if this was triggered by an HTTP error\n * Note: this is not part of the spec, but is included for better error handling.\n *\n * @public\n */\n public code?: number | undefined\n\n /**\n * Optional message attached to the error.\n * Note: this is not part of the spec, but is included for better error handling.\n *\n * @public\n */\n public message?: string | undefined\n\n /**\n * Constructs a new `ErrorEvent` instance. This is typically not called directly,\n * but rather emitted by the `EventSource` object when an error occurs.\n *\n * @param type - The type of the event (should be \"error\")\n * @param errorEventInitDict - Optional properties to include in the error event\n */\n constructor(\n type: string,\n errorEventInitDict?: {message?: string | undefined; code?: number | undefined},\n ) {\n super(type)\n this.code = errorEventInitDict?.code ?? undefined\n this.message = errorEventInitDict?.message ?? undefined\n }\n\n /**\n * Node.js \"hides\" the `message` and `code` properties of the `ErrorEvent` instance,\n * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,\n * we explicitly include the properties in the `inspect` method.\n *\n * This is automatically called by Node.js when you `console.log` an instance of this class.\n *\n * @param _depth - The current depth\n * @param options - The options passed to `util.inspect`\n * @param inspect - The inspect function to use (prevents having to import it from `util`)\n * @returns A string representation of the error\n */\n [Symbol.for('nodejs.util.inspect.custom')](\n _depth: number,\n options: {colors: boolean},\n inspect: (obj: unknown, inspectOptions: {colors: boolean}) => string,\n ): string {\n return inspect(inspectableError(this), options)\n }\n\n /**\n * Deno \"hides\" the `message` and `code` properties of the `ErrorEvent` instance,\n * when it is `console.log`'ed. This makes it harder to debug errors. To ease debugging,\n * we explicitly include the properties in the `inspect` method.\n *\n * This is automatically called by Deno when you `console.log` an instance of this class.\n *\n * @param inspect - The inspect function to use (prevents having to import it from `util`)\n * @param options - The options passed to `Deno.inspect`\n * @returns A string representation of the error\n */\n [Symbol.for('Deno.customInspect')](\n inspect: (obj: unknown, inspectOptions: {colors: boolean}) => string,\n options: {colors: boolean},\n ): string {\n return inspect(inspectableError(this), options)\n }\n}\n\n/**\n * For environments where DOMException may not exist, we will use a SyntaxError instead.\n * While this isn't strictly according to spec, it is very close.\n *\n * @param message - The message to include in the error\n * @returns A `DOMException` or `SyntaxError` instance\n * @internal\n */\nexport function syntaxError(message: string): SyntaxError {\n // If someone can figure out a way to make this work without depending on DOM/Node.js typings,\n // and without casting to `any`, please send a PR \uD83D\uDE4F\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const DomException = (globalThis as any).DOMException\n if (typeof DomException === 'function') {\n return new DomException(message, 'SyntaxError')\n }\n\n return new SyntaxError(message)\n}\n\n/**\n * Flatten an error into a single error message string.\n * Unwraps nested errors and joins them with a comma.\n *\n * @param err - The error to flatten\n * @returns A string representation of the error\n * @internal\n */\nexport function flattenError(err: unknown): string {\n if (!(err instanceof Error)) {\n return `${err}`\n }\n\n if ('errors' in err && Array.isArray(err.errors)) {\n return err.errors.map(flattenError).join(', ')\n }\n\n if ('cause' in err && err.cause instanceof Error) {\n return `${err}: ${flattenError(err.cause)}`\n }\n\n return err.message\n}\n\n/**\n * Convert an `ErrorEvent` instance into a plain object for inspection.\n *\n * @param err - The `ErrorEvent` instance to inspect\n * @returns A plain object representation of the error\n * @internal\n */\nfunction inspectableError(err: ErrorEvent) {\n return {\n type: err.type,\n message: err.message,\n code: err.code,\n defaultPrevented: err.defaultPrevented,\n cancelable: err.cancelable,\n timeStamp: err.timeStamp,\n }\n}\n", "/**\n * The type of error that occurred.\n * @public\n */\nexport type ErrorType = 'invalid-retry' | 'unknown-field' | 'max-buffer-size-exceeded'\n\n/**\n * Error thrown when encountering an issue during parsing.\n *\n * @public\n */\nexport class ParseError extends Error {\n /**\n * The type of error that occurred.\n */\n type: ErrorType\n\n /**\n * In the case of a completed unknown field encountered in the stream, this will be the field name.\n */\n field?: string | undefined\n\n /**\n * In the case of a completed unknown field encountered in the stream, this will be the value of the field.\n */\n value?: string | undefined\n\n /**\n * The line that caused the error, if available.\n */\n line?: string | undefined\n\n constructor(\n message: string,\n options: {type: ErrorType; field?: string; value?: string; line?: string},\n ) {\n super(message)\n this.name = 'ParseError'\n this.type = options.type\n this.field = options.field\n this.value = options.value\n this.line = options.line\n }\n}\n", "/**\n * EventSource/Server-Sent Events parser\n * @see https://html.spec.whatwg.org/multipage/server-sent-events.html\n */\nimport {ParseError} from './errors.ts'\nimport type {EventSourceParser, ParserConfig} from './types.ts'\n\n// ASCII codes used in the hot parsing paths.\nconst LF = 10\nconst CR = 13\nconst SPACE = 32\nconst MAX_FIELD_PREFIX_LENGTH = 6\n\n/**\n * Creates a new EventSource parser.\n *\n * @param config - Parser configuration. Accepts callbacks (see {@link ParserCallbacks})\n * and options like `maxBufferSize` (see {@link ParserConfig}).\n *\n * @returns A new EventSource parser, with `feed` and `reset` methods.\n * @public\n */\nexport function createParser(config: ParserConfig): EventSourceParser {\n if (typeof config === 'function') {\n throw new TypeError(\n '`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?',\n )\n }\n\n const {maxBufferSize, onComment, onError, onEvent, onId, onRetry} = config\n\n // Trailing bytes from prior `feed()` calls that did not yet form a complete line.\n // Stored as an array of fragments and only joined when a line terminator arrives.\n // Concatenating per-feed (`prefix + chunk`) is O(N\u00B2) when a single SSE line spans\n // many chunks (e.g. a large `data:` payload streamed in tiny slices, or an MCP-style\n // server that emits one giant content block). Buffering as fragments + joining once\n // makes the same workload linear.\n const pendingFragments: string[] = []\n\n // Running total of `pendingFragments` lengths, kept in sync with the array so the\n // `maxBufferSize` check doesn't have to walk the fragment list on every feed.\n let pendingFragmentsLength = 0\n\n // Empty or partial leading BOM; undefined once the BOM check is complete.\n let bomPrefix: string | undefined = ''\n let id: string | undefined\n let data = ''\n let dataLines = 0\n let eventType: string | undefined\n\n // Set after a `maxBufferSize` overflow. Once tripped, `feed()` throws until\n // `reset()` is called \u2014 see the comment on `maxBufferSize` in `ParserConfig`.\n let terminated = false\n let skippingLine = false\n\n // Set when a line (parsed or discarded) was terminated by a trailing `\\r` at the very\n // end of a chunk. That `\\r` is ambiguous: it may be a bare-CR terminator or the first\n // half of a `\\r\\n` whose `\\n` lands in the next chunk. The line itself is complete\n // either way, but we must remember to swallow a single leading `\\n` from the next\n // chunk so the pair is treated as one terminator rather than a blank line (which\n // would dispatch an event prematurely).\n let skipNextLineFeed = false\n\n /**\n * Feeds a chunk of the SSE stream to the parser. Any trailing bytes that do\n * not yet form a complete line are held back and prepended to the next chunk,\n * so callers can pass arbitrary slices of the stream without worrying about\n * line boundaries.\n *\n * Per the SSE spec, one leading UTF-8 BOM is stripped before parsing,\n * even when split across chunks. This handles both the raw 3-byte form (0xEF 0xBB\n * 0xBF) and a single decoded U+FEFF, so a leading BOM is ignored regardless of\n * how the caller decoded the bytes.\n *\n * @see https://html.spec.whatwg.org/multipage/server-sent-events.html#parsing-an-event-stream\n */\n function feed(chunk: string) {\n if (terminated) {\n throw new Error(\n 'Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing.',\n )\n }\n\n if (bomPrefix !== undefined) {\n chunk = bomPrefix + chunk\n // Wait only while the input could still be a raw BOM. Empty chunks must\n // not finish the check, and a mismatched prefix must remain ordinary input.\n if (chunk === '' || chunk === '\\xEF' || chunk === '\\xEF\\xBB') {\n bomPrefix = chunk\n return\n }\n bomPrefix = undefined\n // Strip exactly one leading BOM, in decoded or raw byte-valued form.\n chunk = chunk.replace(/^(?:\\uFEFF|\\xEF\\xBB\\xBF)/, '')\n }\n\n // Rare resume states from a prior chunk boundary: a pending `\\r\\n` split or a\n // line being discarded. Single combined check keeps the hot path to one branch;\n // the actual handling lives out-of-line in `resumeAfterSkip`.\n if (skippingLine || skipNextLineFeed) {\n chunk = resumeAfterSkip(chunk)\n if (!chunk) {\n return\n }\n }\n\n // Hot path: no buffered prefix from a prior partial line. Hand the chunk\n // straight to `processLines`, exactly like the original implementation.\n // Zero new work in the common case (every chunk ends with `\\n\\n`).\n if (!pendingFragments.length) {\n const trailing = processLines(chunk)\n if (trailing !== '') {\n storeTrailing(trailing)\n }\n checkBufferSize()\n return\n }\n\n // We have a buffered prefix. If this chunk also has no terminator, append\n // to the buffer without concatenating \u2014 that's the O(N\u00B2) trap we're\n // avoiding (large single `data:` payload split across many tiny chunks).\n if (chunk.indexOf('\\n') === -1 && chunk.indexOf('\\r') === -1) {\n if (pendingFragmentsLength < MAX_FIELD_PREFIX_LENGTH) {\n const head =\n pendingFragments.join('') +\n chunk.slice(0, MAX_FIELD_PREFIX_LENGTH - pendingFragmentsLength)\n if (!shouldBufferTrailing(head)) {\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n skippingLine = true\n return\n }\n }\n pendingFragments.push(chunk)\n pendingFragmentsLength += chunk.length\n checkBufferSize()\n return\n }\n\n // Terminator arrived. Join the accumulated fragments + this chunk once,\n // process, and buffer any new trailing partial line.\n pendingFragments.push(chunk)\n const input = pendingFragments.join('')\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n storeTrailing(processLines(input))\n checkBufferSize()\n }\n\n // Out-of-line handler for the rare post-boundary states. `skipNextLineFeed` means a\n // line (parsed or discarded) ended with a trailing `\\r` at the previous chunk boundary,\n // so a single leading `\\n` must be swallowed to consume a split `\\r\\n` as one terminator.\n // `skippingLine` means we are discarding an invalid line until its terminator arrives.\n // The two states are mutually exclusive. Returns the remaining chunk to parse ('' if\n // this chunk was fully consumed).\n function resumeAfterSkip(chunk: string): string {\n if (chunk.length === 0) {\n return chunk\n }\n\n if (skipNextLineFeed) {\n skipNextLineFeed = false\n return chunk.charCodeAt(0) === LF ? chunk.slice(1) : chunk\n }\n\n const crIndex = chunk.indexOf('\\r')\n const lfIndex = chunk.indexOf('\\n')\n const lineEnd =\n crIndex === -1 ? lfIndex : lfIndex === -1 ? crIndex : crIndex < lfIndex ? crIndex : lfIndex\n\n if (lineEnd === -1) {\n return ''\n }\n\n // Trailing `\\r` at the very end of the chunk: defer the CRLF/CR decision to the\n // next chunk (see `skipNextLineFeed`) rather than greedily consuming just the `\\r`.\n if (lineEnd === chunk.length - 1 && chunk.charCodeAt(lineEnd) === CR) {\n skippingLine = false\n skipNextLineFeed = true\n return ''\n }\n\n skippingLine = false\n return chunk.slice(\n lineEnd + (chunk.charCodeAt(lineEnd) === CR && chunk.charCodeAt(lineEnd + 1) === LF ? 2 : 1),\n )\n }\n\n function storeTrailing(trailing: string) {\n if (!trailing) return\n\n // A trailing that ends with `\\r` is not a partial line: the `\\r` terminates it,\n // and only the CRLF-vs-CR ambiguity remains (the matching `\\n` may start the next\n // chunk). Parse the completed line now \u2014 buffering it could grow unbounded through\n // the no-terminator append path, and discarding it would eat the terminator and\n // make skip mode swallow the next line.\n if (trailing.charCodeAt(trailing.length - 1) === CR) {\n parseLine(trailing, 0, trailing.length - 1)\n skipNextLineFeed = true\n return\n }\n\n if (shouldBufferTrailing(trailing)) {\n pendingFragments.push(trailing)\n pendingFragmentsLength = trailing.length\n return\n }\n\n skippingLine = true\n }\n\n function shouldBufferTrailing(trailing: string) {\n const firstCharCode = trailing.charCodeAt(0)\n return (\n (firstCharCode === 58 && !!onComment) ||\n (firstCharCode === 100 && isPotentialField(trailing, 'data')) ||\n (firstCharCode === 101 && isPotentialField(trailing, 'event')) ||\n (firstCharCode === 105 && isPotentialField(trailing, 'id')) ||\n (firstCharCode === 114 && isPotentialField(trailing, 'retry'))\n )\n }\n\n function checkBufferSize() {\n if (maxBufferSize === undefined) return\n if (pendingFragmentsLength + data.length <= maxBufferSize) return\n\n terminated = true\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n skippingLine = false\n skipNextLineFeed = false\n onError?.(\n new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {\n type: 'max-buffer-size-exceeded',\n }),\n )\n }\n\n /**\n * Splits `chunk` into SSE lines and dispatches each to the appropriate handler.\n * Returns any trailing bytes that did not terminate with a line break, so the\n * caller can prepend them to the next chunk.\n *\n * The SSE spec permits three line terminators: `\\n`, `\\r`, and `\\r\\n`. Real-world\n * streams almost always use plain `\\n`, so we take a fast path when no `\\r` is\n * present in the chunk. The slow path is spec-correct but does more work per line.\n */\n function processLines(chunk: string): string {\n let searchIndex = 0\n\n // Fast path: LF-only chunk (the common case for typical SSE servers).\n // We can scan forward with a single `indexOf('\\n')` per line and inline\n // the hot-path branches for `data:` and `event:` without the CR bookkeeping\n // the slow path needs.\n if (chunk.indexOf('\\r') === -1) {\n let lfIndex = chunk.indexOf('\\n', searchIndex)\n while (lfIndex !== -1) {\n // Blank line: end-of-event marker. Dispatch the accumulated event (if any)\n // and reset the buffered fields. This is hoisted out of `parseLine` because\n // it's the single most common line shape after `data:` lines.\n if (searchIndex === lfIndex) {\n if (id !== undefined) {\n onId?.(id)\n }\n if (dataLines > 0) {\n onEvent?.({id, event: eventType, data})\n }\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n searchIndex = lfIndex + 1\n lfIndex = chunk.indexOf('\\n', searchIndex)\n continue\n }\n const firstCharCode = chunk.charCodeAt(searchIndex)\n if (isDataPrefix(chunk, searchIndex, firstCharCode)) {\n // `data:` line \u2014 append the value to the event's data buffer.\n // 'data:'.length === 5, 'data: '.length === 6\n const valueStart =\n chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5\n const value = chunk.slice(valueStart, lfIndex)\n // Fast path within a fast path: if this is the first data line AND the\n // next char is another LF (i.e. `data:foo\\n\\n`), dispatch immediately\n // without ever writing to the `data` buffer. This is the shape of a\n // typical single-line SSE event (ChatGPT-style streams, etc.) and is\n // hot enough to be worth the duplication.\n if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {\n if (id !== undefined) {\n onId?.(id)\n }\n onEvent?.({id, event: eventType, data: value})\n id = undefined\n data = ''\n eventType = undefined\n searchIndex = lfIndex + 2\n lfIndex = chunk.indexOf('\\n', searchIndex)\n continue\n }\n // Multi-line data: concatenate with newline separator per spec.\n data = dataLines === 0 ? value : `${data}\\n${value}`\n dataLines++\n } else if (isEventPrefix(chunk, searchIndex, firstCharCode)) {\n // `event:` line \u2014 set the event type for the next dispatch. Per spec,\n // an empty value resets `event type` to its default (undefined here).\n // 'event:'.length === 6, 'event: '.length === 7\n eventType =\n chunk.slice(\n chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,\n lfIndex,\n ) || undefined\n } else {\n // Everything else: `id:`, `retry:`, comment lines (`:` prefix), unknown\n // fields, or malformed lines. These are rarer and go through the full\n // per-line parser, which handles the SSE field grammar in detail.\n parseLine(chunk, searchIndex, lfIndex)\n }\n searchIndex = lfIndex + 1\n lfIndex = chunk.indexOf('\\n', searchIndex)\n }\n return chunk.slice(searchIndex)\n }\n\n // Slow path: the chunk contains at least one `\\r`, so lines may be terminated\n // by `\\r`, `\\n`, or `\\r\\n`. We locate the next terminator by looking at both\n // the nearest `\\r` and `\\n` and picking whichever comes first.\n while (searchIndex < chunk.length) {\n const crIndex = chunk.indexOf('\\r', searchIndex)\n const lfIndex = chunk.indexOf('\\n', searchIndex)\n\n let lineEnd = -1\n if (crIndex !== -1 && lfIndex !== -1) {\n lineEnd = crIndex < lfIndex ? crIndex : lfIndex\n } else if (crIndex !== -1) {\n // A trailing `\\r` at the very end of the chunk is ambiguous: it could be\n // a bare-CR terminator, or the first half of a `\\r\\n` whose `\\n` arrives\n // in the next chunk. Defer until we see more input.\n if (crIndex === chunk.length - 1) {\n lineEnd = -1\n } else {\n lineEnd = crIndex\n }\n } else if (lfIndex !== -1) {\n lineEnd = lfIndex\n }\n\n if (lineEnd === -1) {\n break\n }\n\n parseLine(chunk, searchIndex, lineEnd)\n searchIndex = lineEnd + 1\n // If we just consumed a `\\r` and the next char is `\\n`, skip it so the\n // pair is treated as a single terminator rather than an empty line.\n if (chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF) {\n searchIndex++\n }\n }\n\n return chunk.slice(searchIndex)\n }\n\n function parseLine(chunk: string, start: number, end: number) {\n if (start === end) {\n dispatchEvent()\n return\n }\n\n const firstCharCode = chunk.charCodeAt(start)\n\n if (isDataPrefix(chunk, start, firstCharCode)) {\n // 'data:'.length === 5, 'data: '.length === 6\n const valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5\n const value = chunk.slice(valueStart, end)\n data = dataLines === 0 ? value : `${data}\\n${value}`\n dataLines++\n return\n }\n\n if (isEventPrefix(chunk, start, firstCharCode)) {\n // 'event:'.length === 6, 'event: '.length === 7\n eventType =\n chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || undefined\n return\n }\n\n // Fast path for \"id:\" \u2014 'i' = 105, 'd' = 100, ':' = 58\n if (\n firstCharCode === 105 &&\n chunk.charCodeAt(start + 1) === 100 &&\n chunk.charCodeAt(start + 2) === 58\n ) {\n // 'id:'.length === 3, 'id: '.length === 4\n const value = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end)\n // If the field value does not contain U+0000 NULL, then set the `ID` buffer to\n // the field value. Otherwise, ignore the field.\n if (!value.includes('\\0')) id = value\n return\n }\n\n // Comment line \u2014 ':' = 58\n if (firstCharCode === 58) {\n if (onComment) {\n const line = chunk.slice(start, end)\n // skip ':' (+1), or ': ' (+2) when a space follows\n onComment(line.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1))\n }\n return\n }\n\n const line = chunk.slice(start, end)\n const fieldSeparatorIndex = line.indexOf(':')\n if (fieldSeparatorIndex === -1) {\n processField(line, '', line)\n return\n }\n\n const field = line.slice(0, fieldSeparatorIndex)\n // skip ':' (+1), or ': ' (+2) when a space follows\n const offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1\n const value = line.slice(fieldSeparatorIndex + offset)\n processField(field, value, line)\n }\n\n function processField(field: string, value: string, line: string) {\n // Field names must be compared literally, with no case folding performed.\n switch (field) {\n case 'event':\n // Set the `event type` buffer to field value\n eventType = value || undefined\n break\n case 'data':\n data = dataLines === 0 ? value : `${data}\\n${value}`\n dataLines++\n break\n case 'id':\n // If the field value does not contain U+0000 NULL, then set the `ID` buffer to\n // the field value. Otherwise, ignore the field.\n if (!value.includes('\\0')) id = value\n break\n case 'retry':\n // If the field value consists of only ASCII digits, then interpret the field value as an\n // integer in base ten, and set the event stream's reconnection time to that integer.\n // Otherwise, ignore the field.\n if (/^\\d+$/.test(value)) {\n onRetry?.(parseInt(value, 10))\n } else {\n onError?.(\n new ParseError(`Invalid \\`retry\\` value: \"${value}\"`, {\n type: 'invalid-retry',\n value,\n line,\n }),\n )\n }\n break\n default:\n // Otherwise, the field is ignored.\n onError?.(\n new ParseError(\n `Unknown field \"${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}\"`,\n {type: 'unknown-field', field, value, line},\n ),\n )\n break\n }\n }\n\n function dispatchEvent() {\n if (id !== undefined) {\n onId?.(id)\n }\n\n if (dataLines > 0) {\n onEvent?.({\n id,\n event: eventType,\n data,\n })\n }\n\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n }\n\n function reset(options: {consume?: boolean} = {}) {\n if (options.consume && pendingFragments.length > 0) {\n const incompleteLine = pendingFragments.join('')\n parseLine(incompleteLine, 0, incompleteLine.length)\n }\n\n bomPrefix = ''\n id = undefined\n data = ''\n dataLines = 0\n eventType = undefined\n pendingFragments.length = 0\n pendingFragmentsLength = 0\n terminated = false\n skippingLine = false\n skipNextLineFeed = false\n }\n\n return {feed, reset}\n}\n\n/**\n * Checks if `chunk` starts with the literal `data:` at index `i`.\n *\n * Equivalent to `chunk.startsWith('data:', i)`, but benchmarks show this\n * hand-unrolled char-code comparison is ~20% faster on common event types.\n * The caller passes `firstCharCode` (the code at `i`) so it can be reused\n * across prefix checks.\n *\n * ASCII: 'd' = 100, 'a' = 97, 't' = 116, 'a' = 97, ':' = 58\n */\nfunction isDataPrefix(chunk: string, i: number, firstCharCode: number): boolean {\n return (\n firstCharCode === 100 &&\n chunk.charCodeAt(i + 1) === 97 &&\n chunk.charCodeAt(i + 2) === 116 &&\n chunk.charCodeAt(i + 3) === 97 &&\n chunk.charCodeAt(i + 4) === 58\n )\n}\n\n/**\n * Checks if `chunk` starts with the literal `event:` at index `i`.\n *\n * See {@link isDataPrefix} for why this is hand-unrolled rather than using\n * `String.prototype.startsWith`.\n *\n * ASCII: 'e' = 101, 'v' = 118, 'e' = 101, 'n' = 110, 't' = 116, ':' = 58\n */\nfunction isEventPrefix(chunk: string, i: number, firstCharCode: number): boolean {\n return (\n firstCharCode === 101 &&\n chunk.charCodeAt(i + 1) === 118 &&\n chunk.charCodeAt(i + 2) === 101 &&\n chunk.charCodeAt(i + 3) === 110 &&\n chunk.charCodeAt(i + 4) === 116 &&\n chunk.charCodeAt(i + 5) === 58\n )\n}\n\nfunction isPotentialField(line: string, field: string): boolean {\n let i = 1\n while (i < line.length && i < field.length) {\n if (line.charCodeAt(i) !== field.charCodeAt(i)) {\n return false\n }\n i++\n }\n\n return line.length <= field.length || line.charCodeAt(field.length) === 58\n}\n", "export {type ErrorType, ParseError} from './errors.ts'\nexport {createParser} from './parse.ts'\nexport type {EventSourceMessage, EventSourceParser, ParserCallbacks, ParserConfig} from './types.ts'\n", "import {\n createParser,\n type EventSourceMessage,\n type EventSourceParser,\n type ParseError,\n} from 'eventsource-parser'\n\nimport {ErrorEvent, flattenError, syntaxError} from './errors.ts'\nimport type {\n AddEventListenerOptions,\n EventListenerOptions,\n EventListenerOrEventListenerObject,\n EventSourceEventMap,\n EventSourceFetchInit,\n EventSourceInit,\n FetchLike,\n FetchLikeResponse,\n} from './types.ts'\n\nconst DEFAULT_MAX_BUFFER_SIZE = 100 * 1024 * 1024\n\n/**\n * An `EventSource` instance opens a persistent connection to an HTTP server, which sends events\n * in `text/event-stream` format. The connection remains open until closed by calling `.close()`.\n *\n * Deliberately an `interface` and not a `class`: it lets consumers pass the native `EventSource`,\n * a mock, or any other implementation wherever this type is expected.\n *\n * @public\n * @example\n * ```js\n * const eventSource = new EventSource('https://example.com/stream')\n * eventSource.addEventListener('error', (error) => {\n * console.error(error)\n * })\n * eventSource.addEventListener('message', (event) => {\n * console.log('Received message:', event.data)\n * })\n * ```\n */\nexport interface EventSource extends EventTarget {\n /**\n * ReadyState representing an EventSource currently trying to connect\n *\n * @public\n */\n readonly CONNECTING: 0\n\n /**\n * ReadyState representing an EventSource connection that is open (eg connected)\n *\n * @public\n */\n readonly OPEN: 1\n\n /**\n * ReadyState representing an EventSource connection that is closed (eg disconnected)\n *\n * @public\n */\n readonly CLOSED: 2\n\n /**\n * Returns the state of this EventSource object's connection. It can have the values described below.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/readyState)\n *\n * Note: typed as `number` instead of `0 | 1 | 2` for compatibility with the `EventSource` interface,\n * defined in the TypeScript `dom` library.\n *\n * @public\n */\n readonly readyState: number\n\n /**\n * Returns the URL providing the event stream.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/url)\n *\n * @public\n */\n readonly url: string\n\n /**\n * Returns true if the credentials mode for connection requests to the URL providing the event stream is set to \"include\", and false otherwise.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/withCredentials)\n *\n * @public\n */\n readonly withCredentials: boolean\n\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/error_event) */\n onerror: ((this: EventSource, ev: ErrorEvent) => unknown) | null\n\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/message_event) */\n onmessage: ((this: EventSource, ev: MessageEvent) => unknown) | null\n\n /** [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/open_event) */\n onopen: ((this: EventSource, ev: Event) => unknown) | null\n\n addEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n addEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void\n\n removeEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n removeEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void\n\n /**\n * Aborts any instances of the fetch algorithm started for this EventSource object, and sets the readyState attribute to CLOSED.\n *\n * [MDN Reference](https://developer.mozilla.org/docs/Web/API/EventSource/close)\n *\n * @public\n */\n close(): void\n}\n\n/**\n * The `EventSource` constructor. Mirrors the shape of the native one, so the two can be used\n * interchangeably - eg for functions that take an implementation to construct.\n *\n * @public\n */\nexport interface EventSourceConstructor {\n readonly prototype: EventSource\n\n /**\n * Constructs a new `EventSource` instance, which immediately starts connecting.\n *\n * @param url - The URL to connect to\n * @param eventSourceInitDict - Options for the connection\n */\n new (url: string | URL, eventSourceInitDict?: EventSourceInit): EventSource\n\n /** ReadyState representing an EventSource currently trying to connect */\n readonly CONNECTING: 0\n\n /** ReadyState representing an EventSource connection that is open (eg connected) */\n readonly OPEN: 1\n\n /** ReadyState representing an EventSource connection that is closed (eg disconnected) */\n readonly CLOSED: 2\n}\n\n/**\n * Implementation of the `EventSource` interface.\n *\n * Intentionally not exported: TypeScript emits a `#private` brand into declaration files for any\n * class holding hard-private (`#`) fields, which makes the emitted type nominal. Exporting the\n * interface and const instead keeps the public type structural, while the implementation keeps\n * its actual, runtime-enforced private state.\n *\n * Public members are documented on the `EventSource` interface, which is what consumers see.\n *\n * @internal\n */\nclass EventSourceImpl extends EventTarget implements EventSource {\n static CONNECTING = 0 as const\n static OPEN = 1 as const\n static CLOSED = 2 as const\n\n readonly CONNECTING = 0 as const\n readonly OPEN = 1 as const\n readonly CLOSED = 2 as const\n\n public get readyState(): number {\n return this.#readyState\n }\n\n public get url(): string {\n return this.#url.href\n }\n\n public get withCredentials(): boolean {\n return this.#withCredentials\n }\n\n public get onerror(): ((this: EventSource, ev: ErrorEvent) => unknown) | null {\n return this.#onError\n }\n public set onerror(value: ((this: EventSource, ev: ErrorEvent) => unknown) | null) {\n if (this.#onError) {\n this.removeEventListener('error', this.#onError)\n }\n this.#onError = value\n if (value) {\n this.addEventListener('error', value)\n }\n }\n\n public get onmessage(): ((this: EventSource, ev: MessageEvent) => unknown) | null {\n return this.#onMessage\n }\n public set onmessage(value: ((this: EventSource, ev: MessageEvent) => unknown) | null) {\n if (this.#onMessage) {\n this.removeEventListener('message', this.#onMessage)\n }\n this.#onMessage = value\n if (value) {\n this.addEventListener('message', value)\n }\n }\n\n public get onopen(): ((this: EventSource, ev: Event) => unknown) | null {\n return this.#onOpen\n }\n public set onopen(value: ((this: EventSource, ev: Event) => unknown) | null) {\n if (this.#onOpen) {\n this.removeEventListener('open', this.#onOpen)\n }\n this.#onOpen = value\n if (value) {\n this.addEventListener('open', value)\n }\n }\n\n override addEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n override addEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | AddEventListenerOptions,\n ): void\n override addEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void\n override addEventListener(\n type: string,\n listener:\n | ((this: EventSource, event: MessageEvent) => unknown)\n | EventListenerOrEventListenerObject,\n options?: boolean | AddEventListenerOptions,\n ): void {\n const listen = listener as (this: EventSource, event: Event) => unknown\n super.addEventListener(type, listen, options)\n }\n\n override removeEventListener<K extends keyof EventSourceEventMap>(\n type: K,\n listener: (this: EventSource, ev: EventSourceEventMap[K]) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n override removeEventListener(\n type: string,\n listener: (this: EventSource, event: MessageEvent) => unknown,\n options?: boolean | EventListenerOptions,\n ): void\n override removeEventListener(\n type: string,\n listener: EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void\n override removeEventListener(\n type: string,\n listener:\n | ((this: EventSource, event: MessageEvent) => unknown)\n | EventListenerOrEventListenerObject,\n options?: boolean | EventListenerOptions,\n ): void {\n const listen = listener as (this: EventSource, event: Event) => unknown\n super.removeEventListener(type, listen, options)\n }\n\n constructor(url: string | URL, eventSourceInitDict?: EventSourceInit) {\n super()\n\n try {\n if (url instanceof URL) {\n this.#url = url\n } else if (typeof url === 'string') {\n this.#url = new URL(url, getBaseURL())\n } else {\n throw new Error('Invalid URL')\n }\n } catch {\n throw syntaxError('An invalid or illegal string was specified')\n }\n\n this.#parser = createParser({\n maxBufferSize: eventSourceInitDict?.maxBufferSize ?? DEFAULT_MAX_BUFFER_SIZE,\n onEvent: this.#onEvent,\n onError: this.#onParseError,\n onId: this.#onIdChange,\n onRetry: this.#onRetryChange,\n })\n\n this.#readyState = this.CONNECTING\n this.#reconnectInterval = 3000\n this.#fetch = eventSourceInitDict?.fetch ?? globalThis.fetch\n this.#withCredentials = eventSourceInitDict?.withCredentials ?? false\n\n this.#connect()\n }\n\n close(): void {\n if (this.#reconnectTimer) clearTimeout(this.#reconnectTimer)\n if (this.#readyState === this.CLOSED) return\n if (this.#controller) this.#controller.abort()\n this.#readyState = this.CLOSED\n this.#controller = undefined\n }\n\n // PRIVATES FOLLOW\n\n /**\n * Current connection state\n *\n * @internal\n */\n #readyState: number\n\n /**\n * Original URL used to connect.\n *\n * Note that this will stay the same even after a redirect.\n *\n * @internal\n */\n #url: URL\n\n /**\n * The destination URL after a redirect. Is reset on reconnection.\n *\n * @internal\n */\n #redirectUrl: URL | undefined\n\n /**\n * Whether to include credentials in the request\n *\n * @internal\n */\n #withCredentials: boolean\n\n /**\n * The fetch implementation to use\n *\n * @internal\n */\n #fetch: FetchLike\n\n /**\n * The reconnection time in milliseconds\n *\n * @internal\n */\n #reconnectInterval: number\n\n /**\n * Reference to an ongoing reconnect attempt, if any\n *\n * @internal\n */\n #reconnectTimer: ReturnType<typeof setTimeout> | undefined\n\n /**\n * The last event ID seen by the EventSource, which will be sent as `Last-Event-ID` in the\n * request headers on a reconnection attempt.\n *\n * @internal\n */\n #lastEventId: string | null = null\n\n /**\n * The AbortController instance used to abort the fetch request\n *\n * @internal\n */\n #controller: AbortController | undefined\n\n /**\n * Instance of an EventSource parser (`eventsource-parser` npm module)\n *\n * @internal\n */\n #parser: EventSourceParser\n\n /**\n * Holds the current error handler, attached through `onerror` property directly.\n * Note that `addEventListener('error', \u2026)` will not be stored here.\n *\n * @internal\n */\n #onError: ((this: EventSource, ev: ErrorEvent) => unknown) | null = null\n\n /**\n * Holds the current message handler, attached through `onmessage` property directly.\n * Note that `addEventListener('message', \u2026)` will not be stored here.\n *\n * @internal\n */\n #onMessage: ((this: EventSource, ev: MessageEvent) => unknown) | null = null\n\n /**\n * Holds the current open handler, attached through `onopen` property directly.\n * Note that `addEventListener('open', \u2026)` will not be stored here.\n *\n * @internal\n */\n #onOpen: ((this: EventSource, ev: Event) => unknown) | null = null\n\n /**\n * Connect to the given URL and start receiving events\n *\n * @internal\n */\n #connect() {\n this.#readyState = this.CONNECTING\n this.#controller = new AbortController()\n\n // Browser tests are failing if we directly call `this.#fetch()`, thus the indirection.\n const fetch = this.#fetch\n fetch(this.#url, this.#getRequestOptions())\n .then(this.#onFetchResponse)\n .catch(this.#onFetchError)\n }\n\n /**\n * Handles the fetch response\n *\n * @param response - The Fetch(ish) response\n * @internal\n */\n #onFetchResponse = async (response: FetchLikeResponse) => {\n this.#parser.reset()\n\n const {body, redirected, status, headers} = response\n\n // [spec] a client can be told to stop reconnecting using the HTTP 204 No Content response code.\n if (status === 204) {\n // We still need to emit an error event - this mirrors the browser behavior,\n // and without it there is no way to tell the user that the connection was closed.\n this.#failConnection('Server sent HTTP 204, not reconnecting', 204)\n this.close()\n return\n }\n\n // [spec] \u2026Event stream requests can be redirected using HTTP 301 and 307 redirects as with\n // [spec] normal HTTP requests.\n // Spec does not say anything about other redirect codes (302, 308), but this seems an\n // unintended omission, rather than a feature. Browsers will happily redirect on other 3xxs's.\n if (redirected) {\n this.#redirectUrl = new URL(response.url)\n } else {\n this.#redirectUrl = undefined\n }\n\n // [spec] if res's status is not 200, \u2026, then fail the connection.\n if (status !== 200) {\n this.#failConnection(`Non-200 status code (${status})`, status)\n return\n }\n\n // [spec] \u2026or if res's `Content-Type` is not `text/event-stream`, then fail the connection.\n const contentType = headers.get('content-type') || ''\n if (!contentType.startsWith('text/event-stream')) {\n this.#failConnection('Invalid content type, expected \"text/event-stream\"', status)\n return\n }\n\n // [spec] \u2026if the readyState attribute is set to a value other than CLOSED\u2026\n if (this.#readyState === this.CLOSED) {\n return\n }\n\n // [spec] \u2026sets the readyState attribute to OPEN and fires an event\n // [spec] \u2026named open at the EventSource object.\n this.#readyState = this.OPEN\n\n const openEvent = new Event('open')\n this.dispatchEvent(openEvent)\n\n // Ensure that the response stream is a web stream\n if (typeof body !== 'object' || !body || !('getReader' in body)) {\n this.#failConnection('Invalid response body, expected a web ReadableStream', status)\n this.close() // This should only happen if `fetch` provided is \"faulty\" - don't reconnect\n return\n }\n\n const decoder = new TextDecoder()\n\n const reader = body.getReader()\n let open = true\n\n do {\n const {done, value} = await reader.read()\n if (this.#readyState === this.CLOSED) {\n open = false\n break\n }\n\n if (value) {\n this.#parser.feed(decoder.decode(value, {stream: !done}))\n }\n\n if (!done) {\n continue\n }\n\n open = false\n this.#parser.reset()\n\n this.#scheduleReconnect()\n } while (open)\n }\n\n /**\n * Handles rejected requests for the EventSource endpoint\n *\n * @param err - The error from `fetch()`\n * @internal\n */\n #onFetchError = (err: Error & {type?: string}) => {\n this.#controller = undefined\n\n // We expect abort errors when the user manually calls `close()` - ignore those\n if (err.name === 'AbortError' || err.type === 'aborted') {\n return\n }\n\n this.#scheduleReconnect(flattenError(err))\n }\n\n /**\n * Get request options for the `fetch()` request\n *\n * @returns The request options\n * @internal\n */\n #getRequestOptions(): EventSourceFetchInit {\n const lastEvent = this.#lastEventId ? {'Last-Event-ID': this.#lastEventId} : undefined\n\n const init: EventSourceFetchInit = {\n // [spec] Let `corsAttributeState` be `Anonymous`\u2026\n // [spec] \u2026will have their mode set to \"cors\"\u2026\n mode: 'cors',\n redirect: 'follow',\n headers: {Accept: 'text/event-stream', ...lastEvent},\n cache: 'no-store',\n signal: this.#controller?.signal,\n }\n\n // Some environments crash if attempting to set `credentials` where it is not supported,\n // eg on Cloudflare Workers. To avoid this, we only set it in browser-like environments.\n if ('window' in globalThis) {\n // [spec] \u2026and their credentials mode set to \"same-origin\"\n // [spec] \u2026if the `withCredentials` attribute is `true`, set the credentials mode to \"include\"\u2026\n init.credentials = this.withCredentials ? 'include' : 'same-origin'\n }\n\n return init\n }\n\n /**\n * Called by EventSourceParser when a blank line ends a block containing a valid `id` field.\n * This runs before `#onEvent` when the same block also contains data.\n *\n * @param value - The value of the `id` field\n * @internal\n */\n #onIdChange = (value: string) => {\n this.#lastEventId = value\n }\n\n /**\n * Called by EventSourceParser instance when an event has successfully been parsed\n * and is ready to be processed.\n *\n * @param event - The parsed event\n * @internal\n */\n #onEvent = (event: EventSourceMessage) => {\n // A listener can close the connection while the parser is still processing this chunk.\n if (this.#readyState === this.CLOSED) {\n return\n }\n\n const origin = this.#redirectUrl ? this.#redirectUrl.origin : this.#url.origin\n // [spec] The `lastEventId` attribute is the last event ID string of the event\n // source, i.e. the persisted buffer (`#lastEventId`) - not the current event's `id`.\n // The buffer is only updated by an explicit `id` field and must survive an\n // event that omits `id`.\n const lastEventId = this.#lastEventId ?? ''\n\n const messageEvent = new MessageEvent(event.event || 'message', {\n data: event.data,\n origin,\n lastEventId,\n })\n\n // workerd (Cloudflare Workers) accepts `data` but silently drops `origin` and `lastEventId`\n // from the constructor init, yielding `null` and `''`. Both are plain own properties there\n // rather than prototype getters, so they can be assigned after the fact. Elsewhere the\n // constructor honours them and this is skipped, so no runtime pays for it unnecessarily.\n if (messageEvent.origin !== origin) {\n defineEventProperty(messageEvent, 'origin', origin)\n }\n\n if (messageEvent.lastEventId !== lastEventId) {\n defineEventProperty(messageEvent, 'lastEventId', lastEventId)\n }\n\n // The `onmessage` property only triggers on messages without an `event` field, or ones that\n // explicitly set `message`. This is handled automatically: the event is dispatched with type\n // `event.event || 'message'`, and `onmessage` is registered as a `message` event listener.\n this.dispatchEvent(messageEvent)\n }\n\n /**\n * Called by EventSourceParser instance when a new reconnection interval is received\n * from the EventSource endpoint.\n *\n * @param value - The new reconnection interval in milliseconds\n * @internal\n */\n #onRetryChange = (value: number) => {\n this.#reconnectInterval = value\n }\n\n /**\n * Called by EventSourceParser instance when a parse error occurs.\n *\n * @param error - The parser error\n * @internal\n */\n #onParseError = (error: ParseError) => {\n if (error.type !== 'max-buffer-size-exceeded') {\n return\n }\n\n this.close()\n this.#failConnection(error.message)\n }\n\n /**\n * Handles the process referred to in the EventSource specification as \"failing a connection\".\n *\n * @param error - The error causing the connection to fail\n * @param code - The HTTP status code, if available\n * @internal\n */\n #failConnection(message?: string, code?: number) {\n // [spec] \u2026if the readyState attribute is set to a value other than CLOSED,\n // [spec] sets the readyState attribute to CLOSED\u2026\n // Release the request before reporting failure, including responses with an unread body.\n this.close()\n\n // [spec] \u2026and fires an event named `error` at the `EventSource` object.\n // [spec] Once the user agent has failed the connection, it does not attempt to reconnect.\n // [spec] > Implementations are especially encouraged to report detailed information\n // [spec] > to their development consoles whenever an error event is fired, since little\n // [spec] > to no information can be made available in the events themselves.\n // Printing to console is not very programatically helpful, though, so we emit a custom event.\n const errorEvent = new ErrorEvent('error', {code, message})\n this.dispatchEvent(errorEvent)\n }\n\n /**\n * Schedules a reconnection attempt against the EventSource endpoint.\n *\n * @param message - The error causing the connection to fail\n * @param code - The HTTP status code, if available\n * @internal\n */\n #scheduleReconnect(message?: string, code?: number) {\n // [spec] If the readyState attribute is set to CLOSED, abort the task.\n if (this.#readyState === this.CLOSED) {\n return\n }\n\n // [spec] Set the readyState attribute to CONNECTING.\n this.#readyState = this.CONNECTING\n\n // [spec] Fire an event named `error` at the EventSource object.\n const errorEvent = new ErrorEvent('error', {code, message})\n this.dispatchEvent(errorEvent)\n\n // [spec] Wait a delay equal to the reconnection time of the event source.\n const timer = setTimeout(this.#reconnect, this.#reconnectInterval)\n\n // In Node.js (and Bun), a pending timer keeps the event loop alive, preventing the\n // process from exiting while we wait to reconnect. `unref()` opts out of that. Browsers\n // and Deno return a numeric handle with no `unref()`, so only call it when available.\n if (typeof timer === 'object' && timer !== null && 'unref' in timer) {\n timer.unref()\n }\n\n this.#reconnectTimer = timer\n }\n\n /**\n * Reconnects to the EventSource endpoint after a disconnect/failure\n *\n * @internal\n */\n #reconnect = () => {\n this.#reconnectTimer = undefined\n\n // [spec] If the EventSource's readyState attribute is not set to CONNECTING, then return.\n if (this.#readyState !== this.CONNECTING) {\n return\n }\n\n this.#connect()\n }\n}\n\n// The class is named `EventSourceImpl` to leave the `EventSource` name free for the interface and\n// the const below. Restore the public name, so neither `EventSource.name` nor inspected instances\n// (eg `console.log(eventSource)`) leak the implementation name.\nObject.defineProperty(EventSourceImpl, 'name', {value: 'EventSource'})\n\n// Provides a way to detect that the EventSource implementation supports passing `fetch`\n// that can be used to customize the request, eg custom headers and similar.\nObject.defineProperty(EventSourceImpl, Symbol.for('eventsource.supports-fetch-override'), {\n value: true,\n writable: false,\n configurable: false,\n enumerable: false,\n})\n\n/**\n * An `EventSource` instance opens a persistent connection to an HTTP server, which sends events\n * in `text/event-stream` format. The connection remains open until closed by calling `.close()`.\n *\n * @public\n * @example\n * ```js\n * const eventSource = new EventSource('https://example.com/stream')\n * eventSource.addEventListener('error', (error) => {\n * console.error(error)\n * })\n * eventSource.addEventListener('message', (event) => {\n * console.log('Received message:', event.data)\n * })\n * ```\n */\nexport const EventSource: EventSourceConstructor = EventSourceImpl\n\n/**\n * According to spec, when constructing a URL:\n * > 1. Let baseURL be environment's base URL, if environment is a Document object\n * > 2. Return the result of applying the URL parser to url, with baseURL.\n *\n * Thus we should use `document.baseURI` if available, since it can be set through a base tag.\n *\n * @returns The base URL, if available - otherwise `undefined`\n * @internal\n */\nfunction getBaseURL(): string | undefined {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const doc = 'document' in globalThis ? (globalThis as any).document : undefined\n return doc && typeof doc === 'object' && 'baseURI' in doc && typeof doc.baseURI === 'string'\n ? doc.baseURI\n : undefined\n}\n\n/**\n * Assigns a `MessageEvent` property that the constructor's init dictionary was supposed to have\n * set, for runtimes that ignore it.\n *\n * Defined rather than assigned because on the runtimes that do implement the property as a\n * prototype getter, a plain assignment would throw in strict mode. `enumerable` and\n * `configurable` mirror how a spec-compliant implementation exposes it.\n *\n * @param event - The message event to define the property on\n * @param property - The property to define\n * @param value - The value the constructor should have set\n * @internal\n */\nfunction defineEventProperty(\n event: MessageEvent,\n property: 'origin' | 'lastEventId',\n value: string,\n): void {\n Object.defineProperty(event, property, {\n value,\n enumerable: true,\n configurable: true,\n })\n}\n", "export {ErrorEvent} from './errors.ts'\nexport {EventSource, type EventSourceConstructor} from './EventSource.ts'\nexport type * from './types.ts'\n", "import {\n ITriggerFunctions,\n ITriggerResponse,\n INodeType,\n INodeTypeDescription,\n IDataObject,\n NodeConnectionTypes,\n} from \"n8n-workflow\";\nimport { EventSource, ErrorEvent as EventSourceErrorEvent } from \"eventsource\";\nimport { LoadOptions } from \"../Common/LoadOptions\";\n\nexport class PocketbaseTrigger implements INodeType {\n description: INodeTypeDescription = {\n displayName: \"Pocketbase (Beta) Trigger\",\n name: \"pocketbaseTrigger\",\n icon: { light: \"file:pocketbaseTrigger.svg\", dark: \"file:pocketbaseTrigger.dark.svg\" },\n group: [\"trigger\"],\n version: 1,\n description: \"Handle Pocketbase events via SSE (Beta)\",\n subtitle: '={{$parameter[\"collection\"]}}',\n defaults: {\n name: \"Pocketbase Trigger\",\n },\n inputs: [],\n outputs: [NodeConnectionTypes.Main],\n credentials: [\n {\n name: \"pocketbaseHttpApi\",\n required: true,\n },\n ],\n properties: [\n {\n displayName: 'Collection Name or ID',\n name: \"collection\",\n type: \"options\",\n typeOptions: {\n loadOptionsMethod: \"getCollections\",\n },\n default: \"\",\n required: true,\n description: 'The name of the collection to watch for changes. Choose from the list, or specify an ID using an <a href=\"https://docs.n8n.io/code/expressions/\">expression</a>.',\n },\n {\n displayName: \"Events\",\n name: \"events\",\n type: \"multiOptions\",\n options: [\n {\n name: \"Create\",\n value: \"create\",\n },\n {\n name: \"Update\",\n value: \"update\",\n },\n {\n name: \"Delete\",\n value: \"delete\",\n },\n ],\n default: [\"create\", \"update\", \"delete\"],\n required: true,\n description: \"The events to trigger the node\",\n },\n ],\n };\n\n methods = {\n loadOptions: LoadOptions,\n };\n\n async trigger(this: ITriggerFunctions): Promise<ITriggerResponse> {\n const credentials = await this.getCredentials(\"pocketbaseHttpApi\");\n const baseUrl = (credentials.url as string).replace(/\\/$/, \"\");\n const collection = this.getNodeParameter(\"collection\") as string;\n const events = this.getNodeParameter(\"events\") as string[];\n\n const { closeFunction } = subscribeToPocketbaseSSE.call(this, baseUrl, collection, events);\n\n return {\n closeFunction,\n manualTriggerFunction: async () => {\n const sampleData = {\n __action: \"create\",\n id: \"sample-id\",\n collectionId: \"sample-collection-id\",\n collectionName: collection,\n created: new Date().toISOString(),\n updated: new Date().toISOString(),\n };\n this.emit([this.helpers.returnJsonArray(sampleData)]);\n },\n };\n }\n}\n\nfunction subscribeToPocketbaseSSE(\n this: ITriggerFunctions,\n baseUrl: string,\n collection: string,\n events: string[],\n): { closeFunction: () => Promise<void> } {\n let es: EventSource | null = null;\n let isClosed = false;\n let isReconnecting = false;\n let reconnectTimeout: NodeJS.Timeout | null = null;\n let stabilityTimer: NodeJS.Timeout | null = null;\n let reconnectAttempts = 0;\n const MAX_RECONNECT_ATTEMPTS = 50;\n let consecutiveFailures = 0;\n\n const onConnect = async (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data as string);\n const clientId = data.clientId;\n\n await this.helpers.httpRequestWithAuthentication.call(this, \"pocketbaseHttpApi\", {\n method: \"POST\",\n url: `${baseUrl}/api/realtime`,\n body: {\n clientId,\n subscriptions: [collection],\n },\n });\n\n // Reset counters only after the stream has been stable for a short window\n if (stabilityTimer) clearTimeout(stabilityTimer);\n stabilityTimer = setTimeout(() => {\n reconnectAttempts = 0;\n consecutiveFailures = 0;\n stabilityTimer = null;\n }, 5000);\n } catch (error) {\n this.logger.error(\"Failed to connect to PocketBase SSE\", { error, collection });\n const normalizedError =\n error instanceof Error ? error : new Error(String(error || \"Unknown error during connect\"));\n\n // Only emit on the first consecutive failure to avoid flooding.\n if (consecutiveFailures === 0) {\n this.emitError(normalizedError);\n }\n consecutiveFailures++;\n reconnect();\n }\n };\n\n const onError = (error: EventSourceErrorEvent) => {\n if (stabilityTimer) {\n clearTimeout(stabilityTimer);\n stabilityTimer = null;\n }\n this.logger.error(\"PocketBase SSE connection failure\", {\n error,\n baseUrl,\n });\n\n const normalizedError = new Error(error.message || \"PocketBase SSE connection failure\") as Error & {\n code?: number;\n status?: number;\n originalErrorEvent?: EventSourceErrorEvent;\n };\n // `status` isn't part of eventsource's declared ErrorEvent shape, but the\n // library has been observed attaching it on some HTTP error responses.\n const status = (error as unknown as { status?: number }).status;\n if (error.code) normalizedError.code = error.code;\n if (status) normalizedError.status = status;\n normalizedError.originalErrorEvent = error;\n\n // Only emit error on the first failure. Subsequent reconnect attempts will not flood the error stream.\n if (consecutiveFailures === 0) {\n this.emitError(normalizedError);\n }\n consecutiveFailures++;\n reconnect();\n };\n\n const onMessage = (e: MessageEvent) => {\n try {\n const data = JSON.parse(e.data as string);\n if (events.includes(data.action) && data.record) {\n const output: IDataObject & { __original_action?: unknown; __action?: unknown } = {\n ...data.record,\n };\n if (\"action\" in output) {\n output.__original_action = output.action;\n }\n output.__action = data.action;\n\n this.emit([this.helpers.returnJsonArray(output)]);\n }\n } catch (error) {\n const rawData = String(e?.data ?? \"\");\n const redactedPreview = rawData\n .replace(\n /\"(password|token|secret|passwordConfirm|apiKey|accessToken|authorization|bearer)\":\\s*\"(?:[^\"\\\\]|\\\\.)*\"/gi,\n '\"$1\": \"[REDACTED]\"',\n )\n .replace(/\"email\":\\s*\"(?:[^\"\\\\]|\\\\.)*\"/gi, '\"email\": \"[REDACTED]\"')\n .replace(/[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}/g, \"[REDACTED]\")\n .substring(0, 200);\n this.logger.error(\"Failed to parse PocketBase SSE message\", {\n error,\n redactedPreview,\n collection,\n });\n }\n };\n\n const connect = () => {\n if (isClosed) return;\n isReconnecting = false;\n\n es = new EventSource(`${baseUrl}/api/realtime`);\n\n es.addEventListener(\"PB_CONNECT\", onConnect);\n es.addEventListener(\"error\", onError);\n es.addEventListener(collection, onMessage);\n };\n\n const reconnect = () => {\n if (isClosed || isReconnecting) return;\n isReconnecting = true;\n\n if (stabilityTimer) {\n clearTimeout(stabilityTimer);\n stabilityTimer = null;\n }\n\n if (es) {\n es.removeEventListener(\"PB_CONNECT\", onConnect);\n es.removeEventListener(\"error\", onError);\n es.removeEventListener(collection, onMessage);\n es.close();\n es = null;\n }\n\n if (reconnectAttempts >= MAX_RECONNECT_ATTEMPTS) {\n this.logger.error(\"PocketBase trigger permanently closed after max reconnection attempts\", {\n baseUrl,\n collection,\n reconnectAttempts,\n });\n this.emitError(\n new Error(\n `PocketBase SSE: Maximum reconnection attempts (${MAX_RECONNECT_ATTEMPTS}) reached`,\n ),\n );\n isClosed = true;\n isReconnecting = false;\n return;\n }\n\n const baseDelay = Math.min(1000 * Math.pow(2, reconnectAttempts), 30000);\n const jitter = Math.random() * 1000; // Add 0-1000ms jitter\n const delay = baseDelay + jitter;\n reconnectAttempts++;\n\n reconnectTimeout = setTimeout(connect, delay);\n };\n\n connect();\n\n return {\n closeFunction: async () => {\n isClosed = true;\n if (reconnectTimeout) clearTimeout(reconnectTimeout);\n if (stabilityTimer) {\n clearTimeout(stabilityTimer);\n stabilityTimer = null;\n }\n if (es) {\n es.removeEventListener(\"PB_CONNECT\", onConnect);\n es.removeEventListener(\"error\", onError);\n es.removeEventListener(collection, onMessage);\n es.close();\n }\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["init_errors", "value", "line", "init_errors", "init_dist"]
|
|
7
7
|
}
|
package/dist/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "n8n-nodes-pocketbase",
|
|
3
|
-
"version": "2.3.
|
|
3
|
+
"version": "2.3.45",
|
|
4
4
|
"description": "Interact with your PocketBase instance",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"n8n-community-node-package"
|
|
@@ -35,12 +35,12 @@
|
|
|
35
35
|
"prepublishOnly": "n8n-node prerelease"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@n8n/node-cli": "^0.
|
|
38
|
+
"@n8n/node-cli": "^0.49.0",
|
|
39
39
|
"@release-it/conventional-changelog": "^12.0.0",
|
|
40
40
|
"esbuild": "^0.28.1",
|
|
41
41
|
"eventsource": "^5.0.0",
|
|
42
42
|
"form-data": "^4.0.5",
|
|
43
|
-
"oxfmt": "^0.
|
|
43
|
+
"oxfmt": "^0.70.0",
|
|
44
44
|
"release-it": "^21.0.0",
|
|
45
45
|
"tsx": "^4.21.0",
|
|
46
46
|
"typescript": "5.9.3",
|
|
@@ -62,5 +62,5 @@
|
|
|
62
62
|
]
|
|
63
63
|
},
|
|
64
64
|
"pocketbaseVersion": "0.40.4",
|
|
65
|
-
"n8nWorkflowVersion": "2.
|
|
65
|
+
"n8nWorkflowVersion": "2.40.1"
|
|
66
66
|
}
|