@standardserver/peer 0.0.1 → 0.0.3
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/dist/index.d.mts +49 -11
- package/dist/index.d.ts +49 -11
- package/dist/index.mjs +41 -20
- package/package.json +3 -3
package/dist/index.d.mts
CHANGED
|
@@ -202,22 +202,60 @@ declare class ClientPeer {
|
|
|
202
202
|
close(options?: AsyncIdQueueCloseOptions): Promise<void>;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
interface EncodePeerMessageOptions {
|
|
206
|
+
/**
|
|
207
|
+
* Optional string prepended to the encoded message.
|
|
208
|
+
* Used to distinguish messages when multiple protocols share the same peer.
|
|
209
|
+
*/
|
|
210
|
+
prefix?: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Encodes a {@link PeerMessage} into a wire-safe representation.
|
|
214
|
+
*
|
|
215
|
+
* Encoding rules:
|
|
216
|
+
* - If no binary payload is present, the message is encoded as a JSON string.
|
|
217
|
+
* - If binary data exists, the output layout is:
|
|
218
|
+
*
|
|
219
|
+
* [ UTF-8 (prefix + JSON) | delimiter byte | raw binary bytes ]
|
|
220
|
+
*
|
|
221
|
+
* The optional prefix is prepended to the JSON portion before encoding.
|
|
222
|
+
*/
|
|
223
|
+
declare function encodePeerMessage(message: PeerMessage, options?: EncodePeerMessageOptions): Promise<string | Uint8Array<ArrayBuffer>>;
|
|
224
|
+
interface DecodePeerMessageOptions {
|
|
225
|
+
/**
|
|
226
|
+
* Optional prefix expected at the start of the encoded message.
|
|
227
|
+
* If present and the message does not start with this prefix,
|
|
228
|
+
* the decoder returns `matched: false`.
|
|
229
|
+
*/
|
|
230
|
+
prefix?: string;
|
|
231
|
+
}
|
|
205
232
|
/**
|
|
206
|
-
*
|
|
233
|
+
* Result of a decode attempt.
|
|
207
234
|
*
|
|
208
|
-
* -
|
|
209
|
-
*
|
|
210
|
-
*
|
|
235
|
+
* - `matched: false` indicates the input does not belong to this decoder
|
|
236
|
+
* (typically due to a prefix mismatch).
|
|
237
|
+
* - `matched: true` indicates successful decoding of a {@link PeerMessage}.
|
|
211
238
|
*/
|
|
212
|
-
|
|
239
|
+
type DecodePeerMessageResult = {
|
|
240
|
+
matched: false;
|
|
241
|
+
message?: undefined;
|
|
242
|
+
} | {
|
|
243
|
+
matched: true;
|
|
244
|
+
message: PeerMessage;
|
|
245
|
+
};
|
|
213
246
|
/**
|
|
214
|
-
* Decodes a wire-encoded PeerMessage.
|
|
247
|
+
* Decodes a wire-encoded {@link PeerMessage}.
|
|
248
|
+
*
|
|
249
|
+
* Decoding rules:
|
|
250
|
+
* - String input is treated as a JSON-only message.
|
|
251
|
+
* - Binary input may contain:
|
|
252
|
+
* - JSON only, or
|
|
253
|
+
* - JSON followed by binary data separated by the delimiter byte.
|
|
215
254
|
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* separated by the separator byte.
|
|
255
|
+
* If a prefix is provided, it must be present at the start of the payload
|
|
256
|
+
* or the decode attempt will return `matched: false`.
|
|
219
257
|
*/
|
|
220
|
-
declare function decodePeerMessage(
|
|
258
|
+
declare function decodePeerMessage(encoded: string | Uint8Array<ArrayBuffer>, options?: DecodePeerMessageOptions): DecodePeerMessageResult;
|
|
221
259
|
|
|
222
260
|
/**
|
|
223
261
|
* Creates an AsyncIterator from a queue of peer event-stream messages.
|
|
@@ -277,4 +315,4 @@ declare class ServerPeer {
|
|
|
277
315
|
}
|
|
278
316
|
|
|
279
317
|
export { ClientPeer, EventStreamTransmitter, HibernationEventIterator, ServerPeer, decodePeerMessage, encodePeerMessage, toEventIterator };
|
|
280
|
-
export type { ClientPeerCloseOptions, HibernationEventIteratorCallback, PeerAbortMessage, PeerEventStreamMessage, PeerMessage, PeerOctetStreamMessage, PeerRequestMessage, PeerResponseMessage, PeerStreamCancelMessage, ServerPeerCloseOptions };
|
|
318
|
+
export type { ClientPeerCloseOptions, DecodePeerMessageOptions, DecodePeerMessageResult, EncodePeerMessageOptions, HibernationEventIteratorCallback, PeerAbortMessage, PeerEventStreamMessage, PeerMessage, PeerOctetStreamMessage, PeerRequestMessage, PeerResponseMessage, PeerStreamCancelMessage, ServerPeerCloseOptions };
|
package/dist/index.d.ts
CHANGED
|
@@ -202,22 +202,60 @@ declare class ClientPeer {
|
|
|
202
202
|
close(options?: AsyncIdQueueCloseOptions): Promise<void>;
|
|
203
203
|
}
|
|
204
204
|
|
|
205
|
+
interface EncodePeerMessageOptions {
|
|
206
|
+
/**
|
|
207
|
+
* Optional string prepended to the encoded message.
|
|
208
|
+
* Used to distinguish messages when multiple protocols share the same peer.
|
|
209
|
+
*/
|
|
210
|
+
prefix?: string;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Encodes a {@link PeerMessage} into a wire-safe representation.
|
|
214
|
+
*
|
|
215
|
+
* Encoding rules:
|
|
216
|
+
* - If no binary payload is present, the message is encoded as a JSON string.
|
|
217
|
+
* - If binary data exists, the output layout is:
|
|
218
|
+
*
|
|
219
|
+
* [ UTF-8 (prefix + JSON) | delimiter byte | raw binary bytes ]
|
|
220
|
+
*
|
|
221
|
+
* The optional prefix is prepended to the JSON portion before encoding.
|
|
222
|
+
*/
|
|
223
|
+
declare function encodePeerMessage(message: PeerMessage, options?: EncodePeerMessageOptions): Promise<string | Uint8Array<ArrayBuffer>>;
|
|
224
|
+
interface DecodePeerMessageOptions {
|
|
225
|
+
/**
|
|
226
|
+
* Optional prefix expected at the start of the encoded message.
|
|
227
|
+
* If present and the message does not start with this prefix,
|
|
228
|
+
* the decoder returns `matched: false`.
|
|
229
|
+
*/
|
|
230
|
+
prefix?: string;
|
|
231
|
+
}
|
|
205
232
|
/**
|
|
206
|
-
*
|
|
233
|
+
* Result of a decode attempt.
|
|
207
234
|
*
|
|
208
|
-
* -
|
|
209
|
-
*
|
|
210
|
-
*
|
|
235
|
+
* - `matched: false` indicates the input does not belong to this decoder
|
|
236
|
+
* (typically due to a prefix mismatch).
|
|
237
|
+
* - `matched: true` indicates successful decoding of a {@link PeerMessage}.
|
|
211
238
|
*/
|
|
212
|
-
|
|
239
|
+
type DecodePeerMessageResult = {
|
|
240
|
+
matched: false;
|
|
241
|
+
message?: undefined;
|
|
242
|
+
} | {
|
|
243
|
+
matched: true;
|
|
244
|
+
message: PeerMessage;
|
|
245
|
+
};
|
|
213
246
|
/**
|
|
214
|
-
* Decodes a wire-encoded PeerMessage.
|
|
247
|
+
* Decodes a wire-encoded {@link PeerMessage}.
|
|
248
|
+
*
|
|
249
|
+
* Decoding rules:
|
|
250
|
+
* - String input is treated as a JSON-only message.
|
|
251
|
+
* - Binary input may contain:
|
|
252
|
+
* - JSON only, or
|
|
253
|
+
* - JSON followed by binary data separated by the delimiter byte.
|
|
215
254
|
*
|
|
216
|
-
*
|
|
217
|
-
*
|
|
218
|
-
* separated by the separator byte.
|
|
255
|
+
* If a prefix is provided, it must be present at the start of the payload
|
|
256
|
+
* or the decode attempt will return `matched: false`.
|
|
219
257
|
*/
|
|
220
|
-
declare function decodePeerMessage(
|
|
258
|
+
declare function decodePeerMessage(encoded: string | Uint8Array<ArrayBuffer>, options?: DecodePeerMessageOptions): DecodePeerMessageResult;
|
|
221
259
|
|
|
222
260
|
/**
|
|
223
261
|
* Creates an AsyncIterator from a queue of peer event-stream messages.
|
|
@@ -277,4 +315,4 @@ declare class ServerPeer {
|
|
|
277
315
|
}
|
|
278
316
|
|
|
279
317
|
export { ClientPeer, EventStreamTransmitter, HibernationEventIterator, ServerPeer, decodePeerMessage, encodePeerMessage, toEventIterator };
|
|
280
|
-
export type { ClientPeerCloseOptions, HibernationEventIteratorCallback, PeerAbortMessage, PeerEventStreamMessage, PeerMessage, PeerOctetStreamMessage, PeerRequestMessage, PeerResponseMessage, PeerStreamCancelMessage, ServerPeerCloseOptions };
|
|
318
|
+
export type { ClientPeerCloseOptions, DecodePeerMessageOptions, DecodePeerMessageResult, EncodePeerMessageOptions, HibernationEventIteratorCallback, PeerAbortMessage, PeerEventStreamMessage, PeerMessage, PeerOctetStreamMessage, PeerRequestMessage, PeerResponseMessage, PeerStreamCancelMessage, ServerPeerCloseOptions };
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { AsyncIteratorClass, isTypescriptObject, isAsyncIteratorObject, SequentialIdGenerator, AsyncIdQueue, AbortError, stringifyJSON } from '@standardserver/shared';
|
|
2
2
|
import { generateContentDisposition, flattenStandardHeader, getFilenameFromContentDisposition } from '@standardserver/core';
|
|
3
|
-
import { withEventIteratorEventMeta, EventIteratorErrorEvent,
|
|
3
|
+
import { withEventIteratorEventMeta, EventIteratorErrorEvent, unwrapEventIteratorEvent } from '@standardserver/core/event-stream';
|
|
4
4
|
|
|
5
5
|
function toEventIterator(pull, cleanup) {
|
|
6
6
|
return new AsyncIteratorClass(async () => {
|
|
@@ -55,7 +55,7 @@ class EventStreamTransmitter {
|
|
|
55
55
|
if (item.done) {
|
|
56
56
|
this.isCompleted = true;
|
|
57
57
|
}
|
|
58
|
-
const [data, meta] =
|
|
58
|
+
const [data, meta] = unwrapEventIteratorEvent(item.value);
|
|
59
59
|
json = { ...meta, event: item.done ? "close" : "message", data };
|
|
60
60
|
} catch (err) {
|
|
61
61
|
if (err instanceof EventIteratorErrorEvent) {
|
|
@@ -63,7 +63,7 @@ class EventStreamTransmitter {
|
|
|
63
63
|
return;
|
|
64
64
|
}
|
|
65
65
|
this.isCompleted = true;
|
|
66
|
-
const [resolvedError, meta] =
|
|
66
|
+
const [resolvedError, meta] = unwrapEventIteratorEvent(err);
|
|
67
67
|
json = { ...meta, event: "error", data: resolvedError.data };
|
|
68
68
|
} else {
|
|
69
69
|
this.isCompleted = true;
|
|
@@ -403,36 +403,57 @@ class ClientPeer {
|
|
|
403
403
|
}
|
|
404
404
|
}
|
|
405
405
|
|
|
406
|
-
const
|
|
406
|
+
const JSON_BINARY_DELIMITER = 255;
|
|
407
407
|
const textEncoder = new TextEncoder();
|
|
408
408
|
const textDecoder = new TextDecoder();
|
|
409
|
-
async function encodePeerMessage(message) {
|
|
409
|
+
async function encodePeerMessage(message, options = {}) {
|
|
410
|
+
const jsonPart = stringifyJSON({ ...message, binary: void 0 });
|
|
410
411
|
if (message.binary === void 0) {
|
|
411
|
-
return
|
|
412
|
+
return options.prefix ? options.prefix + jsonPart : jsonPart;
|
|
412
413
|
}
|
|
413
|
-
const
|
|
414
|
+
const textBytes = textEncoder.encode(
|
|
415
|
+
options.prefix ? options.prefix + jsonPart : jsonPart
|
|
416
|
+
);
|
|
414
417
|
const binaryBytes = message.binary instanceof Blob ? new Uint8Array(await message.binary.arrayBuffer()) : message.binary;
|
|
415
418
|
const output = new Uint8Array(
|
|
416
|
-
|
|
419
|
+
textBytes.length + 1 + binaryBytes.length
|
|
417
420
|
);
|
|
418
|
-
output.set(
|
|
419
|
-
output[
|
|
420
|
-
output.set(binaryBytes,
|
|
421
|
+
output.set(textBytes, 0);
|
|
422
|
+
output[textBytes.length] = JSON_BINARY_DELIMITER;
|
|
423
|
+
output.set(binaryBytes, textBytes.length + 1);
|
|
421
424
|
return output;
|
|
422
425
|
}
|
|
423
|
-
function decodePeerMessage(
|
|
424
|
-
if (typeof
|
|
425
|
-
|
|
426
|
+
function decodePeerMessage(encoded, options = {}) {
|
|
427
|
+
if (typeof encoded === "string") {
|
|
428
|
+
if (options.prefix) {
|
|
429
|
+
if (!encoded.startsWith(options.prefix)) {
|
|
430
|
+
return { matched: false };
|
|
431
|
+
}
|
|
432
|
+
encoded = encoded.slice(options.prefix.length);
|
|
433
|
+
}
|
|
434
|
+
return { matched: true, message: JSON.parse(encoded) };
|
|
426
435
|
}
|
|
427
|
-
|
|
436
|
+
if (options.prefix) {
|
|
437
|
+
const prefixBytes = textEncoder.encode(options.prefix);
|
|
438
|
+
for (let i = 0; i < prefixBytes.length; i++) {
|
|
439
|
+
if (encoded[i] !== prefixBytes[i]) {
|
|
440
|
+
return { matched: false };
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
encoded = encoded.subarray(prefixBytes.length);
|
|
444
|
+
}
|
|
445
|
+
const separatorIndex = encoded.indexOf(JSON_BINARY_DELIMITER);
|
|
428
446
|
if (separatorIndex === -1) {
|
|
429
|
-
return JSON.parse(textDecoder.decode(
|
|
447
|
+
return { matched: true, message: JSON.parse(textDecoder.decode(encoded)) };
|
|
430
448
|
}
|
|
431
|
-
const jsonBytes =
|
|
432
|
-
const binaryBytes =
|
|
449
|
+
const jsonBytes = encoded.subarray(0, separatorIndex);
|
|
450
|
+
const binaryBytes = encoded.subarray(separatorIndex + 1);
|
|
433
451
|
return {
|
|
434
|
-
|
|
435
|
-
|
|
452
|
+
matched: true,
|
|
453
|
+
message: {
|
|
454
|
+
...JSON.parse(textDecoder.decode(jsonBytes)),
|
|
455
|
+
binary: binaryBytes
|
|
456
|
+
}
|
|
436
457
|
};
|
|
437
458
|
}
|
|
438
459
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@standardserver/peer",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.0.
|
|
4
|
+
"version": "0.0.3",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"homepage": "https://standardserver.dev",
|
|
7
7
|
"repository": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"dist"
|
|
21
21
|
],
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@standardserver/core": "0.0.
|
|
24
|
-
"@standardserver/shared": "0.0.
|
|
23
|
+
"@standardserver/core": "0.0.3",
|
|
24
|
+
"@standardserver/shared": "0.0.3"
|
|
25
25
|
},
|
|
26
26
|
"scripts": {
|
|
27
27
|
"build": "unbuild",
|