@api.global/typedsocket 6.1.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/classes.nativebyteerror.d.ts +13 -0
- package/dist_ts/classes.nativebyteerror.js +26 -1
- package/dist_ts/classes.nativebytemanager.d.ts +180 -2
- package/dist_ts/classes.nativebytemanager.js +1400 -52
- package/dist_ts/classes.typedsocket.d.ts +11 -0
- package/dist_ts/classes.typedsocket.js +129 -8
- package/dist_ts/constants.nativemessages.d.ts +45 -0
- package/dist_ts/constants.nativemessages.js +44 -0
- package/dist_ts/helpers.nativemessagecodec.d.ts +6 -0
- package/dist_ts/helpers.nativemessagecodec.js +267 -0
- package/dist_ts/index.d.ts +3 -0
- package/dist_ts/index.js +3 -1
- package/dist_ts/interfaces.diagnostics.d.ts +1 -1
- package/dist_ts/interfaces.nativemessages.d.ts +144 -0
- package/dist_ts/interfaces.nativemessages.js +2 -0
- package/package.json +3 -3
- package/readme.hints.md +14 -5
- package/readme.md +142 -9
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
export declare const NATIVE_MESSAGE_PROTOCOL: "native-message-v1";
|
|
2
|
+
export declare const NATIVE_MESSAGE_PROTOCOL_MAJOR: 1;
|
|
3
|
+
export declare const NATIVE_MESSAGE_FRAME_MAGIC: "TSM1";
|
|
4
|
+
export declare const NATIVE_MESSAGE_FRAME_TYPES: {
|
|
5
|
+
readonly OPEN: 1;
|
|
6
|
+
readonly OPEN_ACK: 2;
|
|
7
|
+
readonly MESSAGE: 3;
|
|
8
|
+
readonly MESSAGE_ACK: 4;
|
|
9
|
+
readonly CLOSE: 5;
|
|
10
|
+
readonly CLOSE_ACK: 6;
|
|
11
|
+
readonly RESET: 7;
|
|
12
|
+
};
|
|
13
|
+
export declare const NATIVE_MESSAGE_RESET_CODES: {
|
|
14
|
+
readonly PROTOCOL_ERROR: 1;
|
|
15
|
+
readonly CAPABILITY_REJECTED: 2;
|
|
16
|
+
readonly RESOURCE_LIMIT: 3;
|
|
17
|
+
readonly TIMEOUT: 4;
|
|
18
|
+
readonly ABORTED: 5;
|
|
19
|
+
readonly AUTHORITY_REVOKED: 6;
|
|
20
|
+
readonly INTERNAL_ERROR: 7;
|
|
21
|
+
};
|
|
22
|
+
export declare const NATIVE_MESSAGE_COMMON_HEADER_BYTES = 32;
|
|
23
|
+
export declare const NATIVE_MESSAGE_OPEN_HEADER_BYTES = 72;
|
|
24
|
+
export declare const NATIVE_MESSAGE_OPEN_ACK_HEADER_BYTES = 40;
|
|
25
|
+
export declare const NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES = 48;
|
|
26
|
+
export declare const NATIVE_MESSAGE_ACK_HEADER_BYTES = 40;
|
|
27
|
+
export declare const NATIVE_MESSAGE_CLOSE_HEADER_BYTES = 32;
|
|
28
|
+
export declare const NATIVE_MESSAGE_CLOSE_ACK_HEADER_BYTES = 32;
|
|
29
|
+
export declare const NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES = 40;
|
|
30
|
+
export declare const NATIVE_MESSAGE_MAX_FRAME_BYTES: number;
|
|
31
|
+
export declare const NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES: number;
|
|
32
|
+
/** Package ceiling sized for bounded browser JPEG frame delivery. */
|
|
33
|
+
export declare const NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES: number;
|
|
34
|
+
export declare const NATIVE_MESSAGE_DEFAULT_MAX_LOGICAL_MESSAGE_BYTES: number;
|
|
35
|
+
export declare const NATIVE_MESSAGE_MAX_PENDING_MESSAGES_PER_CHANNEL = 8;
|
|
36
|
+
export declare const NATIVE_MESSAGE_MAX_PENDING_BYTES_PER_CHANNEL: number;
|
|
37
|
+
export declare const NATIVE_MESSAGE_MAX_CHANNELS_PER_CONNECTION = 32;
|
|
38
|
+
export declare const NATIVE_MESSAGE_MAX_TOMBSTONES_PER_CONNECTION = 64;
|
|
39
|
+
export declare const NATIVE_MESSAGE_MAX_RESET_REASON_BYTES = 256;
|
|
40
|
+
export declare const NATIVE_MESSAGE_NEGOTIATION_TIMEOUT_MS = 10000;
|
|
41
|
+
export declare const NATIVE_MESSAGE_OPEN_TIMEOUT_MS = 10000;
|
|
42
|
+
export declare const NATIVE_MESSAGE_PROGRESS_TIMEOUT_MS = 30000;
|
|
43
|
+
export declare const NATIVE_MESSAGE_TOMBSTONE_RETENTION_MS = 60000;
|
|
44
|
+
export type TNativeMessageFrameType = (typeof NATIVE_MESSAGE_FRAME_TYPES)[keyof typeof NATIVE_MESSAGE_FRAME_TYPES];
|
|
45
|
+
export type TNativeMessageResetCode = (typeof NATIVE_MESSAGE_RESET_CODES)[keyof typeof NATIVE_MESSAGE_RESET_CODES];
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
export const NATIVE_MESSAGE_PROTOCOL = 'native-message-v1';
|
|
2
|
+
export const NATIVE_MESSAGE_PROTOCOL_MAJOR = 1;
|
|
3
|
+
export const NATIVE_MESSAGE_FRAME_MAGIC = 'TSM1';
|
|
4
|
+
export const NATIVE_MESSAGE_FRAME_TYPES = {
|
|
5
|
+
OPEN: 1,
|
|
6
|
+
OPEN_ACK: 2,
|
|
7
|
+
MESSAGE: 3,
|
|
8
|
+
MESSAGE_ACK: 4,
|
|
9
|
+
CLOSE: 5,
|
|
10
|
+
CLOSE_ACK: 6,
|
|
11
|
+
RESET: 7,
|
|
12
|
+
};
|
|
13
|
+
export const NATIVE_MESSAGE_RESET_CODES = {
|
|
14
|
+
PROTOCOL_ERROR: 1,
|
|
15
|
+
CAPABILITY_REJECTED: 2,
|
|
16
|
+
RESOURCE_LIMIT: 3,
|
|
17
|
+
TIMEOUT: 4,
|
|
18
|
+
ABORTED: 5,
|
|
19
|
+
AUTHORITY_REVOKED: 6,
|
|
20
|
+
INTERNAL_ERROR: 7,
|
|
21
|
+
};
|
|
22
|
+
export const NATIVE_MESSAGE_COMMON_HEADER_BYTES = 32;
|
|
23
|
+
export const NATIVE_MESSAGE_OPEN_HEADER_BYTES = 72;
|
|
24
|
+
export const NATIVE_MESSAGE_OPEN_ACK_HEADER_BYTES = 40;
|
|
25
|
+
export const NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES = 48;
|
|
26
|
+
export const NATIVE_MESSAGE_ACK_HEADER_BYTES = 40;
|
|
27
|
+
export const NATIVE_MESSAGE_CLOSE_HEADER_BYTES = 32;
|
|
28
|
+
export const NATIVE_MESSAGE_CLOSE_ACK_HEADER_BYTES = 32;
|
|
29
|
+
export const NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES = 40;
|
|
30
|
+
export const NATIVE_MESSAGE_MAX_FRAME_BYTES = 32 * 1024;
|
|
31
|
+
export const NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES = NATIVE_MESSAGE_MAX_FRAME_BYTES - NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES;
|
|
32
|
+
/** Package ceiling sized for bounded browser JPEG frame delivery. */
|
|
33
|
+
export const NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES = 4 * 1024 * 1024;
|
|
34
|
+
export const NATIVE_MESSAGE_DEFAULT_MAX_LOGICAL_MESSAGE_BYTES = NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES;
|
|
35
|
+
export const NATIVE_MESSAGE_MAX_PENDING_MESSAGES_PER_CHANNEL = 8;
|
|
36
|
+
export const NATIVE_MESSAGE_MAX_PENDING_BYTES_PER_CHANNEL = 8 * 1024 * 1024;
|
|
37
|
+
export const NATIVE_MESSAGE_MAX_CHANNELS_PER_CONNECTION = 32;
|
|
38
|
+
export const NATIVE_MESSAGE_MAX_TOMBSTONES_PER_CONNECTION = 64;
|
|
39
|
+
export const NATIVE_MESSAGE_MAX_RESET_REASON_BYTES = 256;
|
|
40
|
+
export const NATIVE_MESSAGE_NEGOTIATION_TIMEOUT_MS = 10_000;
|
|
41
|
+
export const NATIVE_MESSAGE_OPEN_TIMEOUT_MS = 10_000;
|
|
42
|
+
export const NATIVE_MESSAGE_PROGRESS_TIMEOUT_MS = 30_000;
|
|
43
|
+
export const NATIVE_MESSAGE_TOMBSTONE_RETENTION_MS = 60_000;
|
|
44
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29uc3RhbnRzLm5hdGl2ZW1lc3NhZ2VzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvY29uc3RhbnRzLm5hdGl2ZW1lc3NhZ2VzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLG1CQUE0QixDQUFDO0FBQ3BFLE1BQU0sQ0FBQyxNQUFNLDZCQUE2QixHQUFHLENBQVUsQ0FBQztBQUN4RCxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxNQUFlLENBQUM7QUFFMUQsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUc7SUFDeEMsSUFBSSxFQUFFLENBQUM7SUFDUCxRQUFRLEVBQUUsQ0FBQztJQUNYLE9BQU8sRUFBRSxDQUFDO0lBQ1YsV0FBVyxFQUFFLENBQUM7SUFDZCxLQUFLLEVBQUUsQ0FBQztJQUNSLFNBQVMsRUFBRSxDQUFDO0lBQ1osS0FBSyxFQUFFLENBQUM7Q0FDQSxDQUFDO0FBRVgsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQUc7SUFDeEMsY0FBYyxFQUFFLENBQUM7SUFDakIsbUJBQW1CLEVBQUUsQ0FBQztJQUN0QixjQUFjLEVBQUUsQ0FBQztJQUNqQixPQUFPLEVBQUUsQ0FBQztJQUNWLE9BQU8sRUFBRSxDQUFDO0lBQ1YsaUJBQWlCLEVBQUUsQ0FBQztJQUNwQixjQUFjLEVBQUUsQ0FBQztDQUNULENBQUM7QUFFWCxNQUFNLENBQUMsTUFBTSxrQ0FBa0MsR0FBRyxFQUFFLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sZ0NBQWdDLEdBQUcsRUFBRSxDQUFDO0FBQ25ELE1BQU0sQ0FBQyxNQUFNLG9DQUFvQyxHQUFHLEVBQUUsQ0FBQztBQUN2RCxNQUFNLENBQUMsTUFBTSxvQ0FBb0MsR0FBRyxFQUFFLENBQUM7QUFDdkQsTUFBTSxDQUFDLE1BQU0sK0JBQStCLEdBQUcsRUFBRSxDQUFDO0FBQ2xELE1BQU0sQ0FBQyxNQUFNLGlDQUFpQyxHQUFHLEVBQUUsQ0FBQztBQUNwRCxNQUFNLENBQUMsTUFBTSxxQ0FBcUMsR0FBRyxFQUFFLENBQUM7QUFDeEQsTUFBTSxDQUFDLE1BQU0sdUNBQXVDLEdBQUcsRUFBRSxDQUFDO0FBQzFELE1BQU0sQ0FBQyxNQUFNLDhCQUE4QixHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFDeEQsTUFBTSxDQUFDLE1BQU0seUNBQXlDLEdBQ3BELDhCQUE4QixHQUFHLG9DQUFvQyxDQUFDO0FBRXhFLHFFQUFxRTtBQUNyRSxNQUFNLENBQUMsTUFBTSx3Q0FBd0MsR0FBRyxDQUFDLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN4RSxNQUFNLENBQUMsTUFBTSxnREFBZ0QsR0FDM0Qsd0NBQXdDLENBQUM7QUFDM0MsTUFBTSxDQUFDLE1BQU0sK0NBQStDLEdBQUcsQ0FBQyxDQUFDO0FBQ2pFLE1BQU0sQ0FBQyxNQUFNLDRDQUE0QyxHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQzVFLE1BQU0sQ0FBQyxNQUFNLDBDQUEwQyxHQUFHLEVBQUUsQ0FBQztBQUM3RCxNQUFNLENBQUMsTUFBTSw0Q0FBNEMsR0FBRyxFQUFFLENBQUM7QUFDL0QsTUFBTSxDQUFDLE1BQU0scUNBQXFDLEdBQUcsR0FBRyxDQUFDO0FBQ3pELE1BQU0sQ0FBQyxNQUFNLHFDQUFxQyxHQUFHLE1BQU0sQ0FBQztBQUM1RCxNQUFNLENBQUMsTUFBTSw4QkFBOEIsR0FBRyxNQUFNLENBQUM7QUFDckQsTUFBTSxDQUFDLE1BQU0sa0NBQWtDLEdBQUcsTUFBTSxDQUFDO0FBQ3pELE1BQU0sQ0FBQyxNQUFNLHFDQUFxQyxHQUFHLE1BQU0sQ0FBQyJ9
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { TNativeMessageFrame } from './interfaces.nativemessages.js';
|
|
2
|
+
export declare function normalizeNativeMessageChannelId(valueArg: unknown): string;
|
|
3
|
+
export declare function normalizeNativeMessageCapability(valueArg: unknown): string;
|
|
4
|
+
export declare function assertNativeMessageLength(valueArg: unknown, nameArg?: string): number;
|
|
5
|
+
export declare function encodeNativeMessageFrame(frameArg: TNativeMessageFrame): Uint8Array<ArrayBuffer>;
|
|
6
|
+
export declare function decodeNativeMessageFrame(bytesArg: Uint8Array): TNativeMessageFrame;
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
import { NATIVE_MESSAGE_ACK_HEADER_BYTES, NATIVE_MESSAGE_CLOSE_ACK_HEADER_BYTES, NATIVE_MESSAGE_CLOSE_HEADER_BYTES, NATIVE_MESSAGE_COMMON_HEADER_BYTES, NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES, NATIVE_MESSAGE_FRAME_MAGIC, NATIVE_MESSAGE_FRAME_TYPES, NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES, NATIVE_MESSAGE_MAX_FRAME_BYTES, NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES, NATIVE_MESSAGE_MAX_RESET_REASON_BYTES, NATIVE_MESSAGE_OPEN_ACK_HEADER_BYTES, NATIVE_MESSAGE_OPEN_HEADER_BYTES, NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES, } from './constants.nativemessages.js';
|
|
2
|
+
import { NativeMessageProtocolError } from './classes.nativebyteerror.js';
|
|
3
|
+
const textEncoder = new TextEncoder();
|
|
4
|
+
const fatalTextDecoder = new TextDecoder('utf-8', { fatal: true });
|
|
5
|
+
const channelIdPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/;
|
|
6
|
+
const capabilityPattern = /^[0-9a-f]{64}$/;
|
|
7
|
+
function bytesToHex(bytesArg) {
|
|
8
|
+
let result = '';
|
|
9
|
+
for (const value of bytesArg)
|
|
10
|
+
result += value.toString(16).padStart(2, '0');
|
|
11
|
+
return result;
|
|
12
|
+
}
|
|
13
|
+
function hexToBytes(valueArg) {
|
|
14
|
+
const result = new Uint8Array(valueArg.length / 2);
|
|
15
|
+
for (let index = 0; index < result.length; index++) {
|
|
16
|
+
result[index] = Number.parseInt(valueArg.slice(index * 2, index * 2 + 2), 16);
|
|
17
|
+
}
|
|
18
|
+
return result;
|
|
19
|
+
}
|
|
20
|
+
export function normalizeNativeMessageChannelId(valueArg) {
|
|
21
|
+
if (typeof valueArg !== 'string' || !channelIdPattern.test(valueArg)) {
|
|
22
|
+
throw new NativeMessageProtocolError('channelId must be a canonical lowercase 128-bit UUID');
|
|
23
|
+
}
|
|
24
|
+
return valueArg;
|
|
25
|
+
}
|
|
26
|
+
export function normalizeNativeMessageCapability(valueArg) {
|
|
27
|
+
if (typeof valueArg !== 'string' || !capabilityPattern.test(valueArg)) {
|
|
28
|
+
throw new NativeMessageProtocolError('capability must be 256 bits of lowercase hexadecimal');
|
|
29
|
+
}
|
|
30
|
+
return valueArg;
|
|
31
|
+
}
|
|
32
|
+
export function assertNativeMessageLength(valueArg, nameArg = 'maxMessageBytes') {
|
|
33
|
+
if (typeof valueArg !== 'number'
|
|
34
|
+
|| !Number.isSafeInteger(valueArg)
|
|
35
|
+
|| valueArg < 0
|
|
36
|
+
|| valueArg > NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES) {
|
|
37
|
+
throw new NativeMessageProtocolError(`${nameArg} must be an integer from 0 through ${NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES}`);
|
|
38
|
+
}
|
|
39
|
+
return valueArg;
|
|
40
|
+
}
|
|
41
|
+
function assertUint32(valueArg, nameArg) {
|
|
42
|
+
if (!Number.isSafeInteger(valueArg) || valueArg < 0 || valueArg > 0xffffffff) {
|
|
43
|
+
throw new NativeMessageProtocolError(`${nameArg} must be an unsigned 32-bit integer`);
|
|
44
|
+
}
|
|
45
|
+
return valueArg;
|
|
46
|
+
}
|
|
47
|
+
function channelIdToBytes(channelIdArg) {
|
|
48
|
+
return hexToBytes(normalizeNativeMessageChannelId(channelIdArg).replaceAll('-', ''));
|
|
49
|
+
}
|
|
50
|
+
function bytesToChannelId(bytesArg) {
|
|
51
|
+
const hex = bytesToHex(bytesArg);
|
|
52
|
+
return normalizeNativeMessageChannelId(`${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`);
|
|
53
|
+
}
|
|
54
|
+
function createHeader(typeArg, channelIdArg, headerLengthArg, payloadLengthArg) {
|
|
55
|
+
const totalLength = headerLengthArg + payloadLengthArg;
|
|
56
|
+
if (totalLength > NATIVE_MESSAGE_MAX_FRAME_BYTES) {
|
|
57
|
+
throw new NativeMessageProtocolError(`native-message-v1 frame exceeds ${NATIVE_MESSAGE_MAX_FRAME_BYTES} bytes`);
|
|
58
|
+
}
|
|
59
|
+
const bytes = new Uint8Array(totalLength);
|
|
60
|
+
bytes.set(textEncoder.encode(NATIVE_MESSAGE_FRAME_MAGIC), 0);
|
|
61
|
+
const view = new DataView(bytes.buffer);
|
|
62
|
+
view.setUint8(4, typeArg);
|
|
63
|
+
view.setUint8(5, 0);
|
|
64
|
+
view.setUint16(6, headerLengthArg, false);
|
|
65
|
+
bytes.set(channelIdToBytes(channelIdArg), 8);
|
|
66
|
+
view.setUint32(24, payloadLengthArg, false);
|
|
67
|
+
view.setUint32(28, 0, false);
|
|
68
|
+
return { bytes, view };
|
|
69
|
+
}
|
|
70
|
+
function assertExactLengths(headerLengthArg, expectedHeaderLengthArg, payloadLengthArg, expectedPayloadLengthArg = 0) {
|
|
71
|
+
if (headerLengthArg !== expectedHeaderLengthArg
|
|
72
|
+
|| payloadLengthArg !== expectedPayloadLengthArg) {
|
|
73
|
+
throw new NativeMessageProtocolError('frame has an invalid header or payload length');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
function decodeUtf8(bytesArg) {
|
|
77
|
+
try {
|
|
78
|
+
return fatalTextDecoder.decode(bytesArg);
|
|
79
|
+
}
|
|
80
|
+
catch (errorArg) {
|
|
81
|
+
throw new NativeMessageProtocolError('RESET reason must contain valid UTF-8', {
|
|
82
|
+
cause: errorArg,
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
export function encodeNativeMessageFrame(frameArg) {
|
|
87
|
+
switch (frameArg.type) {
|
|
88
|
+
case NATIVE_MESSAGE_FRAME_TYPES.OPEN: {
|
|
89
|
+
const { bytes, view } = createHeader(frameArg.type, frameArg.channelId, NATIVE_MESSAGE_OPEN_HEADER_BYTES, 0);
|
|
90
|
+
bytes.set(hexToBytes(normalizeNativeMessageCapability(frameArg.capability)), 32);
|
|
91
|
+
view.setUint32(64, assertNativeMessageLength(frameArg.maxMessageBytes), false);
|
|
92
|
+
view.setUint32(68, 0, false);
|
|
93
|
+
return bytes;
|
|
94
|
+
}
|
|
95
|
+
case NATIVE_MESSAGE_FRAME_TYPES.OPEN_ACK: {
|
|
96
|
+
const { bytes, view } = createHeader(frameArg.type, frameArg.channelId, NATIVE_MESSAGE_OPEN_ACK_HEADER_BYTES, 0);
|
|
97
|
+
view.setUint32(32, assertNativeMessageLength(frameArg.acceptedMaxMessageBytes, 'acceptedMaxMessageBytes'), false);
|
|
98
|
+
view.setUint32(36, 0, false);
|
|
99
|
+
return bytes;
|
|
100
|
+
}
|
|
101
|
+
case NATIVE_MESSAGE_FRAME_TYPES.MESSAGE: {
|
|
102
|
+
if (!(frameArg.payload instanceof Uint8Array)) {
|
|
103
|
+
throw new NativeMessageProtocolError('MESSAGE payload must be a Uint8Array');
|
|
104
|
+
}
|
|
105
|
+
if (frameArg.payload.byteLength > NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES) {
|
|
106
|
+
throw new NativeMessageProtocolError(`MESSAGE payload exceeds ${NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES} bytes`);
|
|
107
|
+
}
|
|
108
|
+
const totalLength = assertNativeMessageLength(frameArg.totalLength, 'totalLength');
|
|
109
|
+
const fragmentOffset = assertUint32(frameArg.fragmentOffset, 'fragmentOffset');
|
|
110
|
+
if (fragmentOffset > totalLength
|
|
111
|
+
|| fragmentOffset + frameArg.payload.byteLength > totalLength
|
|
112
|
+
|| (totalLength === 0 && (fragmentOffset !== 0 || frameArg.payload.byteLength !== 0))
|
|
113
|
+
|| (totalLength > 0 && frameArg.payload.byteLength === 0)) {
|
|
114
|
+
throw new NativeMessageProtocolError('MESSAGE fragment bounds are invalid');
|
|
115
|
+
}
|
|
116
|
+
const { bytes, view } = createHeader(frameArg.type, frameArg.channelId, NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES, frameArg.payload.byteLength);
|
|
117
|
+
view.setUint32(32, assertUint32(frameArg.sequence, 'sequence'), false);
|
|
118
|
+
view.setUint32(36, totalLength, false);
|
|
119
|
+
view.setUint32(40, fragmentOffset, false);
|
|
120
|
+
view.setUint32(44, 0, false);
|
|
121
|
+
bytes.set(frameArg.payload, NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES);
|
|
122
|
+
return bytes;
|
|
123
|
+
}
|
|
124
|
+
case NATIVE_MESSAGE_FRAME_TYPES.MESSAGE_ACK: {
|
|
125
|
+
const { bytes, view } = createHeader(frameArg.type, frameArg.channelId, NATIVE_MESSAGE_ACK_HEADER_BYTES, 0);
|
|
126
|
+
view.setUint32(32, assertUint32(frameArg.sequence, 'sequence'), false);
|
|
127
|
+
view.setUint32(36, 0, false);
|
|
128
|
+
return bytes;
|
|
129
|
+
}
|
|
130
|
+
case NATIVE_MESSAGE_FRAME_TYPES.CLOSE:
|
|
131
|
+
case NATIVE_MESSAGE_FRAME_TYPES.CLOSE_ACK: {
|
|
132
|
+
return createHeader(frameArg.type, frameArg.channelId, frameArg.type === NATIVE_MESSAGE_FRAME_TYPES.CLOSE
|
|
133
|
+
? NATIVE_MESSAGE_CLOSE_HEADER_BYTES
|
|
134
|
+
: NATIVE_MESSAGE_CLOSE_ACK_HEADER_BYTES, 0).bytes;
|
|
135
|
+
}
|
|
136
|
+
case NATIVE_MESSAGE_FRAME_TYPES.RESET: {
|
|
137
|
+
if (!Number.isSafeInteger(frameArg.code) || frameArg.code <= 0 || frameArg.code > 0xffff) {
|
|
138
|
+
throw new NativeMessageProtocolError('RESET code must be a nonzero unsigned 16-bit integer');
|
|
139
|
+
}
|
|
140
|
+
if (typeof frameArg.reason !== 'string') {
|
|
141
|
+
throw new NativeMessageProtocolError('RESET reason must be a string');
|
|
142
|
+
}
|
|
143
|
+
const reasonBytes = textEncoder.encode(frameArg.reason);
|
|
144
|
+
if (reasonBytes.byteLength > NATIVE_MESSAGE_MAX_RESET_REASON_BYTES) {
|
|
145
|
+
throw new NativeMessageProtocolError(`RESET reason exceeds ${NATIVE_MESSAGE_MAX_RESET_REASON_BYTES} UTF-8 bytes`);
|
|
146
|
+
}
|
|
147
|
+
const headerLength = NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES + reasonBytes.byteLength;
|
|
148
|
+
const { bytes, view } = createHeader(frameArg.type, frameArg.channelId, headerLength, 0);
|
|
149
|
+
view.setUint16(32, frameArg.code, false);
|
|
150
|
+
view.setUint16(34, reasonBytes.byteLength, false);
|
|
151
|
+
view.setUint32(36, 0, false);
|
|
152
|
+
bytes.set(reasonBytes, NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES);
|
|
153
|
+
return bytes;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
export function decodeNativeMessageFrame(bytesArg) {
|
|
158
|
+
if (!(bytesArg instanceof Uint8Array)) {
|
|
159
|
+
throw new NativeMessageProtocolError('frame must be a Uint8Array');
|
|
160
|
+
}
|
|
161
|
+
if (bytesArg.byteLength < NATIVE_MESSAGE_COMMON_HEADER_BYTES
|
|
162
|
+
|| bytesArg.byteLength > NATIVE_MESSAGE_MAX_FRAME_BYTES) {
|
|
163
|
+
throw new NativeMessageProtocolError('frame length is outside native-message-v1 bounds');
|
|
164
|
+
}
|
|
165
|
+
if (decodeUtf8(bytesArg.subarray(0, 4)) !== NATIVE_MESSAGE_FRAME_MAGIC) {
|
|
166
|
+
throw new NativeMessageProtocolError('frame magic is not TSM1');
|
|
167
|
+
}
|
|
168
|
+
const view = new DataView(bytesArg.buffer, bytesArg.byteOffset, bytesArg.byteLength);
|
|
169
|
+
const type = view.getUint8(4);
|
|
170
|
+
if (view.getUint8(5) !== 0 || view.getUint32(28, false) !== 0) {
|
|
171
|
+
throw new NativeMessageProtocolError('frame contains nonzero reserved flags or bytes');
|
|
172
|
+
}
|
|
173
|
+
const headerLength = view.getUint16(6, false);
|
|
174
|
+
const payloadLength = view.getUint32(24, false);
|
|
175
|
+
if (headerLength < NATIVE_MESSAGE_COMMON_HEADER_BYTES
|
|
176
|
+
|| headerLength > bytesArg.byteLength
|
|
177
|
+
|| headerLength + payloadLength !== bytesArg.byteLength) {
|
|
178
|
+
throw new NativeMessageProtocolError('frame length fields do not match the WebSocket message');
|
|
179
|
+
}
|
|
180
|
+
const channelId = bytesToChannelId(bytesArg.subarray(8, 24));
|
|
181
|
+
switch (type) {
|
|
182
|
+
case NATIVE_MESSAGE_FRAME_TYPES.OPEN:
|
|
183
|
+
assertExactLengths(headerLength, NATIVE_MESSAGE_OPEN_HEADER_BYTES, payloadLength);
|
|
184
|
+
if (view.getUint32(68, false) !== 0) {
|
|
185
|
+
throw new NativeMessageProtocolError('OPEN contains nonzero reserved bytes');
|
|
186
|
+
}
|
|
187
|
+
return {
|
|
188
|
+
type,
|
|
189
|
+
channelId,
|
|
190
|
+
capability: normalizeNativeMessageCapability(bytesToHex(bytesArg.subarray(32, 64))),
|
|
191
|
+
maxMessageBytes: assertNativeMessageLength(view.getUint32(64, false)),
|
|
192
|
+
};
|
|
193
|
+
case NATIVE_MESSAGE_FRAME_TYPES.OPEN_ACK:
|
|
194
|
+
assertExactLengths(headerLength, NATIVE_MESSAGE_OPEN_ACK_HEADER_BYTES, payloadLength);
|
|
195
|
+
if (view.getUint32(36, false) !== 0) {
|
|
196
|
+
throw new NativeMessageProtocolError('OPEN_ACK contains nonzero reserved bytes');
|
|
197
|
+
}
|
|
198
|
+
return {
|
|
199
|
+
type,
|
|
200
|
+
channelId,
|
|
201
|
+
acceptedMaxMessageBytes: assertNativeMessageLength(view.getUint32(32, false), 'acceptedMaxMessageBytes'),
|
|
202
|
+
};
|
|
203
|
+
case NATIVE_MESSAGE_FRAME_TYPES.MESSAGE: {
|
|
204
|
+
if (headerLength !== NATIVE_MESSAGE_FRAGMENT_HEADER_BYTES
|
|
205
|
+
|| payloadLength > NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES) {
|
|
206
|
+
throw new NativeMessageProtocolError('MESSAGE frame has invalid lengths');
|
|
207
|
+
}
|
|
208
|
+
if (view.getUint32(44, false) !== 0) {
|
|
209
|
+
throw new NativeMessageProtocolError('MESSAGE contains nonzero reserved bytes');
|
|
210
|
+
}
|
|
211
|
+
const totalLength = assertNativeMessageLength(view.getUint32(36, false), 'totalLength');
|
|
212
|
+
const fragmentOffset = view.getUint32(40, false);
|
|
213
|
+
if (fragmentOffset > totalLength
|
|
214
|
+
|| fragmentOffset + payloadLength > totalLength
|
|
215
|
+
|| (totalLength === 0 && (fragmentOffset !== 0 || payloadLength !== 0))
|
|
216
|
+
|| (totalLength > 0 && payloadLength === 0)) {
|
|
217
|
+
throw new NativeMessageProtocolError('MESSAGE fragment bounds are invalid');
|
|
218
|
+
}
|
|
219
|
+
return {
|
|
220
|
+
type,
|
|
221
|
+
channelId,
|
|
222
|
+
sequence: view.getUint32(32, false),
|
|
223
|
+
totalLength,
|
|
224
|
+
fragmentOffset,
|
|
225
|
+
payload: bytesArg.subarray(headerLength),
|
|
226
|
+
};
|
|
227
|
+
}
|
|
228
|
+
case NATIVE_MESSAGE_FRAME_TYPES.MESSAGE_ACK:
|
|
229
|
+
assertExactLengths(headerLength, NATIVE_MESSAGE_ACK_HEADER_BYTES, payloadLength);
|
|
230
|
+
if (view.getUint32(36, false) !== 0) {
|
|
231
|
+
throw new NativeMessageProtocolError('MESSAGE_ACK contains nonzero reserved bytes');
|
|
232
|
+
}
|
|
233
|
+
return {
|
|
234
|
+
type,
|
|
235
|
+
channelId,
|
|
236
|
+
sequence: view.getUint32(32, false),
|
|
237
|
+
};
|
|
238
|
+
case NATIVE_MESSAGE_FRAME_TYPES.CLOSE:
|
|
239
|
+
assertExactLengths(headerLength, NATIVE_MESSAGE_CLOSE_HEADER_BYTES, payloadLength);
|
|
240
|
+
return { type, channelId };
|
|
241
|
+
case NATIVE_MESSAGE_FRAME_TYPES.CLOSE_ACK:
|
|
242
|
+
assertExactLengths(headerLength, NATIVE_MESSAGE_CLOSE_ACK_HEADER_BYTES, payloadLength);
|
|
243
|
+
return { type, channelId };
|
|
244
|
+
case NATIVE_MESSAGE_FRAME_TYPES.RESET: {
|
|
245
|
+
if (headerLength < NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES || payloadLength !== 0) {
|
|
246
|
+
throw new NativeMessageProtocolError('RESET frame has invalid lengths');
|
|
247
|
+
}
|
|
248
|
+
const code = view.getUint16(32, false);
|
|
249
|
+
const reasonLength = view.getUint16(34, false);
|
|
250
|
+
if (code === 0
|
|
251
|
+
|| view.getUint32(36, false) !== 0
|
|
252
|
+
|| reasonLength > NATIVE_MESSAGE_MAX_RESET_REASON_BYTES
|
|
253
|
+
|| headerLength !== NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES + reasonLength) {
|
|
254
|
+
throw new NativeMessageProtocolError('RESET frame has invalid code, reserved bytes, or reason length');
|
|
255
|
+
}
|
|
256
|
+
return {
|
|
257
|
+
type,
|
|
258
|
+
channelId,
|
|
259
|
+
code,
|
|
260
|
+
reason: decodeUtf8(bytesArg.subarray(NATIVE_MESSAGE_RESET_FIXED_HEADER_BYTES, headerLength)),
|
|
261
|
+
};
|
|
262
|
+
}
|
|
263
|
+
default:
|
|
264
|
+
throw new NativeMessageProtocolError(`unknown native-message-v1 frame type ${type}`);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaGVscGVycy5uYXRpdmVtZXNzYWdlY29kZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9oZWxwZXJzLm5hdGl2ZW1lc3NhZ2Vjb2RlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wsK0JBQStCLEVBQy9CLHFDQUFxQyxFQUNyQyxpQ0FBaUMsRUFDakMsa0NBQWtDLEVBQ2xDLG9DQUFvQyxFQUNwQywwQkFBMEIsRUFDMUIsMEJBQTBCLEVBQzFCLHlDQUF5QyxFQUN6Qyw4QkFBOEIsRUFDOUIsd0NBQXdDLEVBQ3hDLHFDQUFxQyxFQUNyQyxvQ0FBb0MsRUFDcEMsZ0NBQWdDLEVBQ2hDLHVDQUF1QyxHQUN4QyxNQUFNLCtCQUErQixDQUFDO0FBQ3ZDLE9BQU8sRUFBRSwwQkFBMEIsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRzFFLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7QUFDdEMsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLFdBQVcsQ0FBQyxPQUFPLEVBQUUsRUFBRSxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztBQUNuRSxNQUFNLGdCQUFnQixHQUFHLGdFQUFnRSxDQUFDO0FBQzFGLE1BQU0saUJBQWlCLEdBQUcsZ0JBQWdCLENBQUM7QUFFM0MsU0FBUyxVQUFVLENBQUMsUUFBb0I7SUFDdEMsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO0lBQ2hCLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsUUFBUSxDQUFDLEVBQUUsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDNUUsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELFNBQVMsVUFBVSxDQUFDLFFBQWdCO0lBQ2xDLE1BQU0sTUFBTSxHQUFHLElBQUksVUFBVSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFD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
|
package/dist_ts/index.d.ts
CHANGED
|
@@ -4,6 +4,9 @@ export type { TNativeByteCapabilityMode, TNativeByteRole, TNativeByteAuthorityOp
|
|
|
4
4
|
export * from './classes.nativebyteerror.js';
|
|
5
5
|
export { NativeByteManager, NativeByteReceiver, NativeByteSender, } from './classes.nativebytemanager.js';
|
|
6
6
|
export type { INativeByteManagerOptions } from './classes.nativebytemanager.js';
|
|
7
|
+
export { NATIVE_MESSAGE_PROTOCOL, NATIVE_MESSAGE_PROTOCOL_MAJOR, NATIVE_MESSAGE_MAX_FRAME_BYTES, NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES, NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES, NATIVE_MESSAGE_DEFAULT_MAX_LOGICAL_MESSAGE_BYTES, NATIVE_MESSAGE_MAX_PENDING_MESSAGES_PER_CHANNEL, NATIVE_MESSAGE_MAX_PENDING_BYTES_PER_CHANNEL, NATIVE_MESSAGE_MAX_CHANNELS_PER_CONNECTION, NATIVE_MESSAGE_MAX_TOMBSTONES_PER_CONNECTION, NATIVE_MESSAGE_NEGOTIATION_TIMEOUT_MS, NATIVE_MESSAGE_OPEN_TIMEOUT_MS, NATIVE_MESSAGE_PROGRESS_TIMEOUT_MS, NATIVE_MESSAGE_TOMBSTONE_RETENTION_MS, } from './constants.nativemessages.js';
|
|
8
|
+
export type { TNativeMessageCapabilityMode, TNativeMessageAuthorizationOperation, INativeMessageDescriptorTransport, INativeMessageDescriptor, TNativeMessageRevalidationDescriptor, INativeMessageAuthorizationContext, INativeMessageAuthorizationBinding, INativeMessageAuthorizationAdapter, INativeMessageRevalidationContext, TNativeMessageRevalidate, INativeMessageCreateReceiveGrantOptions, INativeMessageOpenSenderOptions, INativeMessageCreateBinaryChannelOptions, INativeMessageReceiver, INativeMessageSender, INativeMessageReceiveGrant, INativeMessageCapabilityStatus, INativeMessageStats, TNativeMessageRuntime, } from './interfaces.nativemessages.js';
|
|
9
|
+
export { NativeMessageFacade, } from './classes.nativebytemanager.js';
|
|
7
10
|
export { TYPEDSOCKET_MAX_TAG_NAME_BYTES, TYPEDSOCKET_MAX_TAG_PAYLOAD_BYTES, TYPEDSOCKET_MAX_CLIENT_TAGS_PER_PEER, TYPEDSOCKET_MAX_CLIENT_TAG_RETAINED_BYTES_PER_PEER, TYPEDSOCKET_MAX_RETAINED_TAG_MUTATIONS_PER_PEER, TYPEDSOCKET_MAX_RETAINED_TAG_MUTATIONS_PER_RULE, TYPEDSOCKET_MAX_RETAINED_TAG_MUTATIONS_PER_SERVER, TYPEDSOCKET_MAX_TAG_AUTHORIZATION_TIMEOUT_MS, TYPEDSOCKET_MAX_SERVER_TAG_NAMES_PER_PEER, TYPEDSOCKET_MAX_SERVER_TAG_RETAINED_BYTES_PER_PEER, TYPEDSOCKET_TAG_DENIAL_CODES, TypedSocketClientTagDeniedError, } from './classes.typedsockettagpolicymanager.js';
|
|
8
11
|
export type { TTypedSocketDiagnosticSide, TTypedSocketDiagnosticEvent, TNativeByteDiagnosticEvent, ITypedSocketConnectionClosedDiagnostic, ITypedSocketPeerRejectedDiagnostic, ITypedSocketReconnectScheduledDiagnostic, ITypedSocketReconnectExhaustedDiagnostic, ITypedSocketTagMutationDeniedDiagnostic, ITypedSocketImplicitTargetingDiagnostic, } from './interfaces.diagnostics.js';
|
|
9
12
|
export type { TTypedSocketTagOwner, TTypedSocketTagMutationOperation, TTypedSocketTagDenialCode, ITypedSocketTagConnectionAuthority, ITypedSocketClientTagExistingState, ITypedSocketClientTagValidationContext, ITypedSocketClientTagRule, ITypedSocketClientTagPolicy, ITypedSocketTagMutationSuccess, ITypedSocketTagMutationDenial, TTypedSocketTagMutationResponse, } from './classes.typedsockettagpolicymanager.js';
|
package/dist_ts/index.js
CHANGED
|
@@ -2,5 +2,7 @@ export * from './classes.typedsocket.js';
|
|
|
2
2
|
export { NATIVE_BYTE_PROTOCOL, NATIVE_BYTE_PROTOCOL_MAJOR, NATIVE_BYTE_MAX_FRAME_BYTES, NATIVE_BYTE_MAX_CONTENT_TYPE_BYTES, NATIVE_BYTE_MAX_DATA_PAYLOAD_BYTES, NATIVE_BYTE_MAX_STREAM_BYTES, NATIVE_BYTE_DEFAULT_INITIAL_WINDOW_BYTES, NATIVE_BYTE_MAX_WINDOW_BYTES, NATIVE_BYTE_MAX_QUEUED_PAYLOAD_BYTES_PER_STREAM, NATIVE_BYTE_MAX_QUEUED_PAYLOAD_BYTES_PER_CONNECTION, NATIVE_BYTE_MAX_RECEIVE_QUEUE_CHUNKS, NATIVE_BYTE_MAX_STREAMS_PER_CONNECTION, NATIVE_BYTE_MAX_PENDING_DATA_OPERATIONS_PER_CONNECTION, NATIVE_BYTE_MAX_RAW_QUEUE_FRAMES, NATIVE_BYTE_MAX_RAW_QUEUE_BYTES, NATIVE_BYTE_GRANT_OPEN_TIMEOUT_MS, NATIVE_BYTE_PROGRESS_TIMEOUT_MS, NATIVE_BYTE_TOMBSTONE_RETENTION_MS, NATIVE_BYTE_MAX_TOMBSTONES, NATIVE_BYTE_MAX_PRINCIPAL_ID_BYTES, NATIVE_BYTE_MAX_AUTHORITY_REVISION_BYTES, NATIVE_BYTE_REVALIDATION_TIMEOUT_MS, NATIVE_BYTE_MAX_REVALIDATIONS_PER_PEER, NATIVE_BYTE_MAX_REVALIDATIONS_PER_PRINCIPAL, NATIVE_BYTE_MAX_REVALIDATIONS_PER_SERVER, NATIVE_BYTE_MAX_CONNECTIONS_PER_SERVER, NATIVE_BYTE_MAX_STREAMS_PER_SERVER, NATIVE_BYTE_MAX_RETAINED_BYTES_PER_SERVER, } from './constants.nativebytes.js';
|
|
3
3
|
export * from './classes.nativebyteerror.js';
|
|
4
4
|
export { NativeByteManager, NativeByteReceiver, NativeByteSender, } from './classes.nativebytemanager.js';
|
|
5
|
+
export { NATIVE_MESSAGE_PROTOCOL, NATIVE_MESSAGE_PROTOCOL_MAJOR, NATIVE_MESSAGE_MAX_FRAME_BYTES, NATIVE_MESSAGE_MAX_FRAGMENT_PAYLOAD_BYTES, NATIVE_MESSAGE_MAX_LOGICAL_MESSAGE_BYTES, NATIVE_MESSAGE_DEFAULT_MAX_LOGICAL_MESSAGE_BYTES, NATIVE_MESSAGE_MAX_PENDING_MESSAGES_PER_CHANNEL, NATIVE_MESSAGE_MAX_PENDING_BYTES_PER_CHANNEL, NATIVE_MESSAGE_MAX_CHANNELS_PER_CONNECTION, NATIVE_MESSAGE_MAX_TOMBSTONES_PER_CONNECTION, NATIVE_MESSAGE_NEGOTIATION_TIMEOUT_MS, NATIVE_MESSAGE_OPEN_TIMEOUT_MS, NATIVE_MESSAGE_PROGRESS_TIMEOUT_MS, NATIVE_MESSAGE_TOMBSTONE_RETENTION_MS, } from './constants.nativemessages.js';
|
|
6
|
+
export { NativeMessageFacade, } from './classes.nativebytemanager.js';
|
|
5
7
|
export { TYPEDSOCKET_MAX_TAG_NAME_BYTES, TYPEDSOCKET_MAX_TAG_PAYLOAD_BYTES, TYPEDSOCKET_MAX_CLIENT_TAGS_PER_PEER, TYPEDSOCKET_MAX_CLIENT_TAG_RETAINED_BYTES_PER_PEER, TYPEDSOCKET_MAX_RETAINED_TAG_MUTATIONS_PER_PEER, TYPEDSOCKET_MAX_RETAINED_TAG_MUTATIONS_PER_RULE, TYPEDSOCKET_MAX_RETAINED_TAG_MUTATIONS_PER_SERVER, TYPEDSOCKET_MAX_TAG_AUTHORIZATION_TIMEOUT_MS, TYPEDSOCKET_MAX_SERVER_TAG_NAMES_PER_PEER, TYPEDSOCKET_MAX_SERVER_TAG_RETAINED_BYTES_PER_PEER, TYPEDSOCKET_TAG_DENIAL_CODES, TypedSocketClientTagDeniedError, } from './classes.typedsockettagpolicymanager.js';
|
|
6
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
8
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi90cy9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxjQUFjLDBCQUEwQixDQUFDO0FBQ3pDLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsMEJBQTBCLEVBQzFCLDJCQUEyQixFQUMzQixrQ0FBa0MsRUFDbEMsa0NBQWtDLEVBQ2xDLDRCQUE0QixFQUM1Qix3Q0FBd0MsRUFDeEMsNEJBQTRCLEVBQzVCLCtDQUErQyxFQUMvQyxtREFBbUQsRUFDbkQsb0NBQW9DLEVBQ3BDLHNDQUFzQyxFQUN0QyxzREFBc0QsRUFDdEQsZ0NBQWdDLEVBQ2hDLCtCQUErQixFQUMvQixpQ0FBaUMsRUFDakMsK0JBQStCLEVBQy9CLGtDQUFrQyxFQUNsQywwQkFBMEIsRUFDMUIsa0NBQWtDLEVBQ2xDLHdDQUF3QyxFQUN4QyxtQ0FBbUMsRUFDbkMsc0NBQXNDLEVBQ3RDLDJDQUEyQyxFQUMzQyx3Q0FBd0MsRUFDeEMsc0NBQXNDLEVBQ3RDLGtDQUFrQyxFQUNsQyx5Q0FBeUMsR0FDMUMsTUFBTSw0QkFBNEIsQ0FBQztBQXlCcEMsY0FBYyw4QkFBOEIsQ0FBQztBQUM3QyxPQUFPLEVBQ0wsaUJBQWlCLEVBQ2pCLGtCQUFrQixFQUNsQixnQkFBZ0IsR0FDakIsTUFBTSxnQ0FBZ0MsQ0FBQztBQUV4QyxPQUFPLEVBQ0wsdUJBQXVCLEVBQ3ZCLDZCQUE2QixFQUM3Qiw4QkFBOEIsRUFDOUIseUNBQXlDLEVBQ3pDLHdDQUF3QyxFQUN4QyxnREFBZ0QsRUFDaEQsK0NBQStDLEVBQy9DLDRDQUE0QyxFQUM1QywwQ0FBMEMsRUFDMUMsNENBQTRDLEVBQzVDLHFDQUFxQyxFQUNyQyw4QkFBOEIsRUFDOUIsa0NBQWtDLEVBQ2xDLHFDQUFxQyxHQUN0QyxNQUFNLCtCQUErQixDQUFDO0FBc0J2QyxPQUFPLEVBQ0wsbUJBQW1CLEdBQ3BCLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxFQUNMLDhCQUE4QixFQUM5QixpQ0FBaUMsRUFDakMsb0NBQW9DLEVBQ3BDLGtEQUFrRCxFQUNsRCwrQ0FBK0MsRUFDL0MsK0NBQStDLEVBQy9DLGlEQUFpRCxFQUNqRCw0Q0FBNEMsRUFDNUMseUNBQXlDLEVBQ3pDLGtEQUFrRCxFQUNsRCw0QkFBNEIsRUFDNUIsK0JBQStCLEdBQ2hDLE1BQU0sMENBQTBDLENBQUMifQ==
|
|
@@ -8,7 +8,7 @@ export type TTypedSocketDiagnosticSide = 'client' | 'server';
|
|
|
8
8
|
export interface ITypedSocketConnectionClosedDiagnostic {
|
|
9
9
|
readonly kind: 'connectionClosed';
|
|
10
10
|
readonly side: TTypedSocketDiagnosticSide;
|
|
11
|
-
readonly scope: 'text' | 'nativeByte';
|
|
11
|
+
readonly scope: 'text' | 'nativeByte' | 'nativeMessage';
|
|
12
12
|
readonly closeCode: number;
|
|
13
13
|
readonly reason: string;
|
|
14
14
|
readonly errorCode?: string;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import type * as plugins from './plugins.js';
|
|
2
|
+
import type { NATIVE_MESSAGE_FRAME_TYPES, NATIVE_MESSAGE_PROTOCOL } from './constants.nativemessages.js';
|
|
3
|
+
import type { INativeByteAuthorityRevisions, INativeByteRuntime, TNativeByteConnectionBinding } from './interfaces.nativebytes.js';
|
|
4
|
+
export type TNativeMessageCapabilityMode = 'disabled' | 'optional' | 'required';
|
|
5
|
+
export type TNativeMessageAuthorizationOperation = 'open' | 'message' | 'close' | 'reject';
|
|
6
|
+
export interface INativeMessageDescriptorTransport {
|
|
7
|
+
readonly protocolMajor: 1;
|
|
8
|
+
readonly channelId: string;
|
|
9
|
+
readonly capability: string;
|
|
10
|
+
readonly expiresAt: number;
|
|
11
|
+
readonly maxMessageBytes: number;
|
|
12
|
+
}
|
|
13
|
+
export interface INativeMessageDescriptor {
|
|
14
|
+
readonly protocol: typeof NATIVE_MESSAGE_PROTOCOL;
|
|
15
|
+
readonly transport: INativeMessageDescriptorTransport;
|
|
16
|
+
}
|
|
17
|
+
export type TNativeMessageRevalidationDescriptor = {
|
|
18
|
+
readonly protocol: INativeMessageDescriptor['protocol'];
|
|
19
|
+
readonly transport: Omit<INativeMessageDescriptorTransport, 'capability'>;
|
|
20
|
+
};
|
|
21
|
+
export interface INativeMessageAuthorizationContext {
|
|
22
|
+
readonly target: plugins.IWebSocketPeer;
|
|
23
|
+
readonly maxMessageBytes: number;
|
|
24
|
+
}
|
|
25
|
+
export interface INativeMessageAuthorizationBinding extends INativeByteAuthorityRevisions {
|
|
26
|
+
readonly principalId: string;
|
|
27
|
+
readonly revalidate: TNativeMessageRevalidate;
|
|
28
|
+
}
|
|
29
|
+
export interface INativeMessageAuthorizationAdapter {
|
|
30
|
+
bind(authorizationArg: unknown, contextArg: Readonly<INativeMessageAuthorizationContext>): INativeMessageAuthorizationBinding;
|
|
31
|
+
}
|
|
32
|
+
export interface INativeMessageRevalidationContext extends INativeByteAuthorityRevisions {
|
|
33
|
+
readonly operation: TNativeMessageAuthorizationOperation;
|
|
34
|
+
readonly descriptor: TNativeMessageRevalidationDescriptor;
|
|
35
|
+
readonly connection: TNativeByteConnectionBinding;
|
|
36
|
+
readonly abortSignal: AbortSignal;
|
|
37
|
+
readonly deadline: number;
|
|
38
|
+
}
|
|
39
|
+
export type TNativeMessageRevalidate = (contextArg: INativeMessageRevalidationContext) => boolean | Promise<boolean>;
|
|
40
|
+
export interface INativeMessageCreateReceiveGrantOptions extends INativeByteAuthorityRevisions {
|
|
41
|
+
readonly principalId: string;
|
|
42
|
+
readonly maxMessageBytes?: number;
|
|
43
|
+
readonly revalidate: TNativeMessageRevalidate;
|
|
44
|
+
readonly target?: {
|
|
45
|
+
readonly peer: plugins.IWebSocketPeer;
|
|
46
|
+
} | plugins.IWebSocketPeer;
|
|
47
|
+
}
|
|
48
|
+
export interface INativeMessageOpenSenderOptions {
|
|
49
|
+
readonly target?: {
|
|
50
|
+
readonly peer: plugins.IWebSocketPeer;
|
|
51
|
+
} | plugins.IWebSocketPeer;
|
|
52
|
+
}
|
|
53
|
+
export interface INativeMessageCreateBinaryChannelOptions {
|
|
54
|
+
readonly direction: 'receive';
|
|
55
|
+
readonly target: {
|
|
56
|
+
readonly peer: plugins.IWebSocketPeer;
|
|
57
|
+
} | plugins.IWebSocketPeer;
|
|
58
|
+
readonly authorization: unknown;
|
|
59
|
+
readonly maxMessageBytes?: number;
|
|
60
|
+
}
|
|
61
|
+
export interface INativeMessageReceiver {
|
|
62
|
+
readonly closed: Promise<void>;
|
|
63
|
+
receive(): Promise<Uint8Array | undefined>;
|
|
64
|
+
reject(reasonArg?: unknown): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
export interface INativeMessageSender {
|
|
67
|
+
readonly closed: Promise<void>;
|
|
68
|
+
send(messageArg: Uint8Array): Promise<void>;
|
|
69
|
+
close(): Promise<void>;
|
|
70
|
+
}
|
|
71
|
+
export interface INativeMessageReceiveGrant {
|
|
72
|
+
readonly descriptor: INativeMessageDescriptor;
|
|
73
|
+
readonly receiver: INativeMessageReceiver;
|
|
74
|
+
readonly opened: Promise<INativeMessageReceiver>;
|
|
75
|
+
readonly revoke: (reasonArg?: unknown) => Promise<void>;
|
|
76
|
+
readonly dispose: () => void;
|
|
77
|
+
}
|
|
78
|
+
export interface INativeMessageCapabilityStatus {
|
|
79
|
+
readonly protocolMajor: 1;
|
|
80
|
+
readonly capabilities: readonly (typeof NATIVE_MESSAGE_PROTOCOL)[];
|
|
81
|
+
readonly connection: 'none' | 'client' | 'server';
|
|
82
|
+
}
|
|
83
|
+
export interface INativeMessageStats {
|
|
84
|
+
readonly connection: 'none' | 'client' | 'server';
|
|
85
|
+
readonly negotiated: boolean;
|
|
86
|
+
readonly activeChannels: number;
|
|
87
|
+
readonly receiveGrants: number;
|
|
88
|
+
readonly pendingMessages: number;
|
|
89
|
+
readonly pendingMessageBytes: number;
|
|
90
|
+
readonly reassemblyBytes: number;
|
|
91
|
+
readonly completedMessages: number;
|
|
92
|
+
readonly sharedQueuedPayloadBytes: number;
|
|
93
|
+
readonly rawQueueFrames: number;
|
|
94
|
+
readonly rawQueueBytes: number;
|
|
95
|
+
readonly processingRawBytes: number;
|
|
96
|
+
readonly outboundControlFrames: number;
|
|
97
|
+
readonly outboundMessageFrames: number;
|
|
98
|
+
readonly tombstones: number;
|
|
99
|
+
readonly retainedRevalidations: number;
|
|
100
|
+
readonly serverConnections: number;
|
|
101
|
+
readonly serverChannels: number;
|
|
102
|
+
readonly serverRetainedBytes: number;
|
|
103
|
+
readonly serverRetainedRevalidations: number;
|
|
104
|
+
}
|
|
105
|
+
export type TNativeMessageRuntime = INativeByteRuntime;
|
|
106
|
+
export type TNativeMessageOpenFrame = {
|
|
107
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.OPEN;
|
|
108
|
+
readonly channelId: string;
|
|
109
|
+
readonly capability: string;
|
|
110
|
+
readonly maxMessageBytes: number;
|
|
111
|
+
};
|
|
112
|
+
export type TNativeMessageOpenAckFrame = {
|
|
113
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.OPEN_ACK;
|
|
114
|
+
readonly channelId: string;
|
|
115
|
+
readonly acceptedMaxMessageBytes: number;
|
|
116
|
+
};
|
|
117
|
+
export type TNativeMessageFragmentFrame = {
|
|
118
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.MESSAGE;
|
|
119
|
+
readonly channelId: string;
|
|
120
|
+
readonly sequence: number;
|
|
121
|
+
readonly totalLength: number;
|
|
122
|
+
readonly fragmentOffset: number;
|
|
123
|
+
readonly payload: Uint8Array;
|
|
124
|
+
};
|
|
125
|
+
export type TNativeMessageAckFrame = {
|
|
126
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.MESSAGE_ACK;
|
|
127
|
+
readonly channelId: string;
|
|
128
|
+
readonly sequence: number;
|
|
129
|
+
};
|
|
130
|
+
export type TNativeMessageCloseFrame = {
|
|
131
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.CLOSE;
|
|
132
|
+
readonly channelId: string;
|
|
133
|
+
};
|
|
134
|
+
export type TNativeMessageCloseAckFrame = {
|
|
135
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.CLOSE_ACK;
|
|
136
|
+
readonly channelId: string;
|
|
137
|
+
};
|
|
138
|
+
export type TNativeMessageResetFrame = {
|
|
139
|
+
readonly type: typeof NATIVE_MESSAGE_FRAME_TYPES.RESET;
|
|
140
|
+
readonly channelId: string;
|
|
141
|
+
readonly code: number;
|
|
142
|
+
readonly reason: string;
|
|
143
|
+
};
|
|
144
|
+
export type TNativeMessageFrame = TNativeMessageOpenFrame | TNativeMessageOpenAckFrame | TNativeMessageFragmentFrame | TNativeMessageAckFrame | TNativeMessageCloseFrame | TNativeMessageCloseAckFrame | TNativeMessageResetFrame;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@api.global/typedsocket",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.3.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A library for creating typed WebSocket connections, supporting bi-directional communication with type safety.",
|
|
6
6
|
"main": "dist_ts/index.js",
|
|
@@ -19,10 +19,10 @@
|
|
|
19
19
|
"@git.zone/tsbuild": "^4.4.2",
|
|
20
20
|
"@git.zone/tsbundle": "^2.11.3",
|
|
21
21
|
"@git.zone/tsrun": "^2.0.6",
|
|
22
|
-
"@git.zone/tstest": "^
|
|
22
|
+
"@git.zone/tstest": "^4.0.0",
|
|
23
23
|
"@push.rocks/smartenv": "^6.1.0",
|
|
24
24
|
"@push.rocks/smartserve": "^4.2.1",
|
|
25
|
-
"@types/node": "26.1.
|
|
25
|
+
"@types/node": "26.1.2"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@api.global/typedrequest": "^5.2.1",
|