@orpc/standard-server 1.14.12 → 1.14.14

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
@@ -112,12 +112,12 @@ If you find oRPC valuable and would like to support its development, you can do
112
112
  <td align="center"><a href="https://github.com/valerii15298?ref=orpc" target="_blank" rel="noopener" title="Valerii Petryniak"><img src="https://avatars.githubusercontent.com/u/44531564?u=88ac74d9bacd20401518441907acad21063cd397&amp;v=4" width="139" alt="Valerii Petryniak"/><br />Valerii Petryniak</a></td>
113
113
  <td align="center"><a href="https://github.com/letstri?ref=orpc" target="_blank" rel="noopener" title="Valerii Strilets"><img src="https://avatars.githubusercontent.com/u/13253748?u=c7b10399ccc8f8081e24db94ec32cd9858e86ac3&amp;v=4" width="139" alt="Valerii Strilets"/><br />Valerii Strilets</a></td>
114
114
  <td align="center"><a href="https://github.com/K-Mistele?ref=orpc" target="_blank" rel="noopener" title="Kyle Mistele"><img src="https://avatars.githubusercontent.com/u/18430555?u=3afebeb81de666e35aaac3ed46f14159d7603ffb&amp;v=4" width="139" alt="Kyle Mistele"/><br />Kyle Mistele</a></td>
115
- <td align="center"><a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&amp;v=4" width="139" alt="Ryan Vogel"/><br />Ryan Vogel</a></td>
116
115
  <td align="center"><a href="https://github.com/christ12938?ref=orpc" target="_blank" rel="noopener" title="christ12938"><img src="https://avatars.githubusercontent.com/u/25758598?v=4" width="139" alt="christ12938"/><br />christ12938</a></td>
116
+ <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
117
117
  </tr>
118
118
  <tr>
119
- <td align="center"><a href="https://github.com/Ryanjso?ref=orpc" target="_blank" rel="noopener" title="Ryan Soderberg"><img src="https://avatars.githubusercontent.com/u/39172778?u=5ed913c31d57e7221b75784abcad48c7ebddde27&amp;v=4" width="139" alt="Ryan Soderberg"/><br />Ryan Soderberg</a></td>
120
119
  <td align="center"><a href="https://github.com/itigoore01?ref=orpc" target="_blank" rel="noopener" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&amp;v=4" width="139" alt="shota"/><br />shota</a></td>
120
+ <td align="center"><a href="https://github.com/ellis-driscoll?ref=orpc" target="_blank" rel="noopener" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&amp;v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
121
121
  </tr>
122
122
  </table>
123
123
 
@@ -126,24 +126,23 @@ If you find oRPC valuable and would like to support its development, you can do
126
126
  <table>
127
127
  <tr>
128
128
  <td align="center"><a href="https://github.com/rhinodavid?ref=orpc" target="_blank" rel="noopener" title="David Walsh"><img src="https://avatars.githubusercontent.com/u/5778036?u=b5521f07d2f88c3db2a0dae62b5f2f8357214af0&amp;v=4" width="119" alt="David Walsh"/><br />David Walsh</a></td>
129
- <td align="center"><a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&amp;v=4" width="119" alt="Nicholas"/><br />Nicholas</a></td>
130
129
  <td align="center"><a href="https://github.com/Robbe95?ref=orpc" target="_blank" rel="noopener" title="Robbe Vaes"><img src="https://avatars.githubusercontent.com/u/44748019?u=e0232402c045ad4eac7cbd217f1f47e083103b89&amp;v=4" width="119" alt="Robbe Vaes"/><br />Robbe Vaes</a></td>
131
130
  <td align="center"><a href="https://github.com/aidansunbury?ref=orpc" target="_blank" rel="noopener" title="Aidan Sunbury"><img src="https://avatars.githubusercontent.com/u/64103161?v=4" width="119" alt="Aidan Sunbury"/><br />Aidan Sunbury</a></td>
132
131
  <td align="center"><a href="https://github.com/soonoo?ref=orpc" target="_blank" rel="noopener" title="soonoo"><img src="https://avatars.githubusercontent.com/u/5436405?u=5d0b4aa955c87e30e6bda7f0cccae5402da99528&amp;v=4" width="119" alt="soonoo"/><br />soonoo</a></td>
133
132
  <td align="center"><a href="https://github.com/kporten?ref=orpc" target="_blank" rel="noopener" title="Kevin Porten"><img src="https://avatars.githubusercontent.com/u/1839345?u=dc2263d5cfe0d927ce1a0be04a1d55dd6b55405c&amp;v=4" width="119" alt="Kevin Porten"/><br />Kevin Porten</a></td>
134
133
  <td align="center"><a href="https://github.com/pumpkinlink?ref=orpc" target="_blank" rel="noopener" title="Denis"><img src="https://avatars.githubusercontent.com/u/11864620?u=5f47bbe6c65d0f6f5cf011021490238e4b0593d0&amp;v=4" width="119" alt="Denis"/><br />Denis</a></td>
134
+ <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&amp;v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
135
135
  </tr>
136
136
  <tr>
137
- <td align="center"><a href="https://github.com/christopher-kapic?ref=orpc" target="_blank" rel="noopener" title="Christopher Kapic"><img src="https://avatars.githubusercontent.com/u/59740769?u=e7ad4b72b5bf6c9eb1644c26dbf3332a8f987377&amp;v=4" width="119" alt="Christopher Kapic"/><br />Christopher Kapic</a></td>
138
137
  <td align="center"><a href="https://github.com/thomasballinger?ref=orpc" target="_blank" rel="noopener" title="Tom Ballinger"><img src="https://avatars.githubusercontent.com/u/458879?u=4b045ac75d721b6ac2b42a74d7d37f61f0414031&amp;v=4" width="119" alt="Tom Ballinger"/><br />Tom Ballinger</a></td>
139
138
  <td align="center"><a href="https://github.com/SSam0419?ref=orpc" target="_blank" rel="noopener" title="Sam"><img src="https://avatars.githubusercontent.com/u/102863520?u=3c89611f549d5070be232eb4532f690c8f2e7a65&amp;v=4" width="119" alt="Sam"/><br />Sam</a></td>
140
139
  <td align="center"><a href="https://github.com/Titoine?ref=orpc" target="_blank" rel="noopener" title="Titoine"><img src="https://avatars.githubusercontent.com/u/3514286?u=1bb1e86b0c99c8a1121372e56d51a177eea12191&amp;v=4" width="119" alt="Titoine"/><br />Titoine</a></td>
141
140
  <td align="center"><a href="https://github.com/Mnigos?ref=orpc" target="_blank" rel="noopener" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&amp;v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
142
141
  <td align="center"><a href="https://github.com/hanayashiki?ref=orpc" target="_blank" rel="noopener" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&amp;v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
143
142
  <td align="center"><a href="https://github.com/ldub?ref=orpc" target="_blank" rel="noopener" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&amp;v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
143
+ <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
144
144
  </tr>
145
145
  <tr>
146
- <td align="center"><a href="https://github.com/mr-kelly?ref=orpc" target="_blank" rel="noopener" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&amp;v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
147
146
  <td align="center"><a href="https://github.com/piscis?ref=orpc" target="_blank" rel="noopener" title="Alex"><img src="https://avatars.githubusercontent.com/u/326163?u=b245f368bd940cf51d08c0b6bf55f8257f359437&amp;v=4" width="119" alt="Alex"/><br />Alex</a></td>
148
147
  <td align="center"><a href="https://github.com/finom?ref=orpc" target="_blank" rel="noopener" title="Andrey Gubanov"><img src="https://avatars.githubusercontent.com/u/1082083?u=29e91400dbd4a9c217048a8f59562c4f740498e6&amp;v=4" width="119" alt="Andrey Gubanov"/><br />Andrey Gubanov</a></td>
149
148
  </tr>
@@ -176,6 +175,7 @@ If you find oRPC valuable and would like to support its development, you can do
176
175
  <a href="https://github.com/nguyenlc1993?ref=orpc" target="_blank" rel="noopener" title="Lê Cao Nguyên"><img src="https://avatars.githubusercontent.com/u/13871971?u=83c8b69d9e35b589c4e1f066cc113b1d9461386f&amp;v=4" width="32" height="32" alt="Lê Cao Nguyên" /></a>
177
176
  <a href="https://github.com/wobsoriano?ref=orpc" target="_blank" rel="noopener" title="Robert Soriano"><img src="https://avatars.githubusercontent.com/u/13049130?u=6d72104182e7c9ed25934815313fb69107332111&amp;v=4" width="32" height="32" alt="Robert Soriano" /></a>
178
177
  <a href="https://github.com/andrewpeters9?ref=orpc" target="_blank" rel="noopener" title="Andrew Peters"><img src="https://avatars.githubusercontent.com/u/36251325?v=4" width="32" height="32" alt="Andrew Peters" /></a>
178
+ <a href="https://github.com/R44VC0RP?ref=orpc" target="_blank" rel="noopener" title="Ryan Vogel"><img src="https://avatars.githubusercontent.com/u/89211796?u=1857347b9787d8d8a7ea5bfc333f96be92d5a683&amp;v=4" width="32" height="32" alt="Ryan Vogel" /></a>
179
179
  <a href="https://github.com/SKostyukovich?ref=orpc" target="_blank" rel="noopener" title="SKostyukovich"><img src="https://avatars.githubusercontent.com/u/10700067?v=4" width="32" height="32" alt="SKostyukovich" /></a>
180
180
  <a href="https://github.com/peter-adam-dy?ref=orpc" target="_blank" rel="noopener" title="Peter Adam"><img src="https://avatars.githubusercontent.com/u/132129459?u=4f3dbbb3b443990b56acb7d6a5d11ed2c555f6db&amp;v=4" width="32" height="32" alt="Peter Adam" /></a>
181
181
  <a href="https://github.com/FabworksHQ?ref=orpc" target="_blank" rel="noopener" title="Fabworks"><img src="https://avatars.githubusercontent.com/u/160179500?v=4" width="32" height="32" alt="Fabworks" /></a>
@@ -188,6 +188,7 @@ If you find oRPC valuable and would like to support its development, you can do
188
188
  <a href="https://github.com/nattstack?ref=orpc" target="_blank" rel="noopener" title="natt"><img src="https://avatars.githubusercontent.com/u/31426677?u=fa9dbb8b3e66eb0ea3c88db5dc07f31c8c5418fe&amp;v=4" width="32" height="32" alt="natt" /></a>
189
189
  <a href="https://github.com/ChromeGG?ref=orpc" target="_blank" rel="noopener" title="Adam Tkaczyk"><img src="https://avatars.githubusercontent.com/u/39050595?u=a58ca6042a6950e94e6e92442db76ef584279bc0&amp;v=4" width="32" height="32" alt="Adam Tkaczyk" /></a>
190
190
  <a href="https://github.com/plancraft?ref=orpc" target="_blank" rel="noopener" title="plancraft"><img src="https://avatars.githubusercontent.com/u/46482287?v=4" width="32" height="32" alt="plancraft" /></a>
191
+ <a href="https://github.com/Nic13Gamer?ref=orpc" target="_blank" rel="noopener" title="Nicholas"><img src="https://avatars.githubusercontent.com/u/54724556?u=56a7ab430ce7a80d648ab6eba051d454a818ed0b&amp;v=4" width="32" height="32" alt="Nicholas" /></a>
191
192
  </p>
192
193
 
193
194
  ## License
package/dist/index.d.mts CHANGED
@@ -19,7 +19,9 @@ interface EventDecoderOptions {
19
19
  }
20
20
  declare class EventDecoder {
21
21
  private options;
22
- private incomplete;
22
+ private pending;
23
+ private tail;
24
+ private discardLeadingLF;
23
25
  constructor(options?: EventDecoderOptions);
24
26
  feed(chunk: string): void;
25
27
  end(): void;
package/dist/index.d.ts CHANGED
@@ -19,7 +19,9 @@ interface EventDecoderOptions {
19
19
  }
20
20
  declare class EventDecoder {
21
21
  private options;
22
- private incomplete;
22
+ private pending;
23
+ private tail;
24
+ private discardLeadingLF;
23
25
  constructor(options?: EventDecoderOptions);
24
26
  feed(chunk: string): void;
25
27
  end(): void;
package/dist/index.mjs CHANGED
@@ -12,8 +12,13 @@ class ErrorEvent extends Error {
12
12
  }
13
13
  }
14
14
 
15
+ const LINE_ENDING_REGEX$1 = /\r\n|\r(?!\n)|\n/;
16
+ const MESSAGE_DELIMITER_REGEX = /(?:\r\n|\r(?!\n)|\n){2}/;
17
+ const MESSAGE_DELIMITER_GLOBAL_REGEX = /(?:\r\n|\r(?!\n)|\n){2}/g;
18
+ const CR = 13;
19
+ const LF = 10;
20
+ const SPACE = 32;
15
21
  function decodeEventMessage(encoded) {
16
- const lines = encoded.replace(/\n+$/, "").split(/\n/);
17
22
  const message = {
18
23
  data: void 0,
19
24
  event: void 0,
@@ -21,54 +26,94 @@ function decodeEventMessage(encoded) {
21
26
  retry: void 0,
22
27
  comments: []
23
28
  };
24
- for (const line of lines) {
29
+ for (const line of encoded.split(LINE_ENDING_REGEX$1)) {
30
+ if (line === "") {
31
+ continue;
32
+ }
25
33
  const index = line.indexOf(":");
26
- const key = index === -1 ? line : line.slice(0, index);
27
- const value = index === -1 ? "" : line.slice(index + 1).replace(/^\s/, "");
34
+ const value = index === -1 ? "" : line.slice(line.charCodeAt(index + 1) === SPACE ? index + 2 : index + 1);
28
35
  if (index === 0) {
29
36
  message.comments.push(value);
30
- } else if (key === "data") {
31
- message.data ??= "";
32
- message.data += `${value}
33
- `;
34
- } else if (key === "event") {
35
- message.event = value;
36
- } else if (key === "id") {
37
- message.id = value;
38
- } else if (key === "retry") {
39
- const maybeInteger = Number.parseInt(value);
40
- if (Number.isInteger(maybeInteger) && maybeInteger >= 0 && maybeInteger.toString() === value) {
41
- message.retry = maybeInteger;
37
+ continue;
38
+ }
39
+ switch (index === -1 ? line : line.slice(0, index)) {
40
+ case "data":
41
+ message.data = message.data === void 0 ? value : `${message.data}
42
+ ${value}`;
43
+ break;
44
+ case "event":
45
+ message.event = value;
46
+ break;
47
+ case "id":
48
+ message.id = value;
49
+ break;
50
+ case "retry": {
51
+ const maybeInteger = Number.parseInt(value, 10);
52
+ if (maybeInteger >= 0 && maybeInteger.toString() === value) {
53
+ message.retry = maybeInteger;
54
+ }
55
+ break;
42
56
  }
43
57
  }
44
58
  }
45
- message.data = message.data?.replace(/\n$/, "");
46
59
  return message;
47
60
  }
48
61
  class EventDecoder {
49
62
  constructor(options = {}) {
50
63
  this.options = options;
51
64
  }
52
- incomplete = "";
65
+ pending = [];
66
+ // Last up-to-3 characters of the pending buffer, prefixed to the next chunk
67
+ // so a delimiter straddling the boundary is still found.
68
+ tail = "";
69
+ // Set when a chunk-ending '\r' was already consumed as a line ending, so a
70
+ // leading '\n' in the next chunk is the second half of that CRLF pair.
71
+ discardLeadingLF = false;
53
72
  feed(chunk) {
54
- this.incomplete += chunk;
55
- const lastCompleteIndex = this.incomplete.lastIndexOf("\n\n");
56
- if (lastCompleteIndex === -1) {
73
+ if (chunk === "") {
57
74
  return;
58
75
  }
59
- const completes = this.incomplete.slice(0, lastCompleteIndex).split(/\n\n/);
60
- this.incomplete = this.incomplete.slice(lastCompleteIndex + 2);
61
- for (const encoded of completes) {
62
- const message = decodeEventMessage(`${encoded}
63
-
64
- `);
76
+ if (this.discardLeadingLF) {
77
+ this.discardLeadingLF = false;
78
+ if (chunk.charCodeAt(0) === LF) {
79
+ chunk = chunk.slice(1);
80
+ if (chunk === "") {
81
+ return;
82
+ }
83
+ }
84
+ }
85
+ const scan = this.tail + chunk;
86
+ if (!MESSAGE_DELIMITER_REGEX.test(scan)) {
87
+ this.pending.push(chunk);
88
+ this.tail = scan.slice(-3);
89
+ return;
90
+ }
91
+ this.pending.push(chunk);
92
+ const buffered = this.pending.length === 1 ? chunk : this.pending.join("");
93
+ const offset = buffered.length - scan.length;
94
+ const parts = [];
95
+ let start = 0;
96
+ for (const match of scan.matchAll(MESSAGE_DELIMITER_GLOBAL_REGEX)) {
97
+ parts.push(buffered.slice(start, offset + match.index));
98
+ start = offset + match.index + match[0].length;
99
+ }
100
+ const incomplete = buffered.slice(start);
101
+ this.pending.length = 0;
102
+ this.tail = incomplete.slice(-3);
103
+ if (incomplete === "") {
104
+ this.discardLeadingLF = chunk.charCodeAt(chunk.length - 1) === CR;
105
+ } else {
106
+ this.pending.push(incomplete);
107
+ }
108
+ for (const encoded of parts) {
109
+ const message = decodeEventMessage(encoded);
65
110
  if (this.options.onEvent) {
66
111
  this.options.onEvent(message);
67
112
  }
68
113
  }
69
114
  }
70
115
  end() {
71
- if (this.incomplete) {
116
+ if (this.pending.length !== 0) {
72
117
  throw new EventDecoderError("Event Iterator ended before complete");
73
118
  }
74
119
  }
@@ -94,14 +139,19 @@ class EventDecoderStream extends TransformStream {
94
139
  }
95
140
  }
96
141
 
142
+ const LINE_ENDING_REGEX = /\r\n|[\n\r]/;
143
+ const LINE_ENDING_GLOBAL_REGEX = /\r\n|[\n\r]/g;
144
+ function containsLineBreak(value) {
145
+ return LINE_ENDING_REGEX.test(value);
146
+ }
97
147
  function assertEventId(id) {
98
- if (id.includes("\n")) {
99
- throw new EventEncoderError("Event's id must not contain a newline character");
148
+ if (containsLineBreak(id)) {
149
+ throw new EventEncoderError("Event's id must not contain a carriage return or newline character");
100
150
  }
101
151
  }
102
152
  function assertEventName(event) {
103
- if (event.includes("\n")) {
104
- throw new EventEncoderError("Event's event must not contain a newline character");
153
+ if (containsLineBreak(event)) {
154
+ throw new EventEncoderError("Event's event must not contain a carriage return or newline character");
105
155
  }
106
156
  }
107
157
  function assertEventRetry(retry) {
@@ -110,18 +160,16 @@ function assertEventRetry(retry) {
110
160
  }
111
161
  }
112
162
  function assertEventComment(comment) {
113
- if (comment.includes("\n")) {
114
- throw new EventEncoderError("Event's comment must not contain a newline character");
163
+ if (containsLineBreak(comment)) {
164
+ throw new EventEncoderError("Event's comment must not contain a carriage return or newline character");
115
165
  }
116
166
  }
117
167
  function encodeEventData(data) {
118
- const lines = data?.split(/\n/) ?? [];
119
- let output = "";
120
- for (const line of lines) {
121
- output += `data: ${line}
122
- `;
168
+ if (data === void 0) {
169
+ return "";
123
170
  }
124
- return output;
171
+ return `data: ${data.replace(LINE_ENDING_GLOBAL_REGEX, "\ndata: ")}
172
+ `;
125
173
  }
126
174
  function encodeEventComments(comments) {
127
175
  let output = "";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@orpc/standard-server",
3
3
  "type": "module",
4
- "version": "1.14.12",
4
+ "version": "1.14.14",
5
5
  "license": "MIT",
6
6
  "homepage": "https://orpc.dev",
7
7
  "repository": {
@@ -29,7 +29,7 @@
29
29
  "dist"
30
30
  ],
31
31
  "dependencies": {
32
- "@orpc/shared": "1.14.12"
32
+ "@orpc/shared": "1.14.14"
33
33
  },
34
34
  "scripts": {
35
35
  "build": "unbuild",