@meshagent/meshagent 0.0.11 → 0.0.12
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/browser/agent-client.d.ts +88 -0
- package/dist/browser/agent-client.js +174 -0
- package/dist/browser/agent.d.ts +103 -0
- package/dist/browser/agent.js +229 -0
- package/dist/browser/client.d.ts +90 -0
- package/dist/browser/client.js +449 -0
- package/dist/browser/completer.d.ts +9 -0
- package/dist/browser/completer.js +25 -0
- package/dist/browser/data-types.d.ts +44 -0
- package/dist/browser/data-types.js +119 -0
- package/dist/browser/database-client.d.ts +77 -0
- package/dist/browser/database-client.js +113 -0
- package/dist/browser/developer-client.d.ts +13 -0
- package/dist/browser/developer-client.js +35 -0
- package/dist/browser/document.d.ts +84 -0
- package/dist/browser/document.js +531 -0
- package/dist/browser/entrypoint.d.ts +49722 -0
- package/dist/browser/entrypoint.js +8659 -0
- package/dist/browser/event-emitter.d.ts +13 -0
- package/dist/browser/event-emitter.js +38 -0
- package/dist/browser/helpers.d.ts +26 -0
- package/dist/browser/helpers.js +79 -0
- package/dist/browser/index.d.ts +24 -0
- package/dist/browser/index.js +40 -0
- package/dist/browser/messaging-client.d.ts +76 -0
- package/dist/browser/messaging-client.js +248 -0
- package/dist/browser/participant-token.d.ts +36 -0
- package/dist/browser/participant-token.js +104 -0
- package/dist/browser/participant.d.ts +18 -0
- package/dist/browser/participant.js +42 -0
- package/dist/browser/protocol.d.ts +87 -0
- package/dist/browser/protocol.js +305 -0
- package/dist/browser/queues-client.d.ts +26 -0
- package/dist/browser/queues-client.js +47 -0
- package/dist/browser/requirement.d.ts +25 -0
- package/dist/browser/requirement.js +49 -0
- package/dist/browser/response.d.ts +60 -0
- package/dist/browser/response.js +138 -0
- package/dist/browser/room-client.d.ts +43 -0
- package/dist/browser/room-client.js +109 -0
- package/dist/browser/room-event.d.ts +60 -0
- package/dist/browser/room-event.js +82 -0
- package/dist/browser/room-server-client.d.ts +19 -0
- package/dist/browser/room-server-client.js +50 -0
- package/dist/browser/runtime.d.ts +6 -0
- package/dist/browser/runtime.js +8 -0
- package/dist/browser/schema.d.ts +83 -0
- package/dist/browser/schema.js +321 -0
- package/dist/browser/storage-client.d.ts +38 -0
- package/dist/browser/storage-client.js +86 -0
- package/dist/browser/stream-controller.d.ts +8 -0
- package/dist/browser/stream-controller.js +55 -0
- package/dist/browser/sync-client.d.ts +33 -0
- package/dist/browser/sync-client.js +123 -0
- package/dist/browser/utils.d.ts +14 -0
- package/dist/browser/utils.js +59 -0
- package/dist/node/agent-client.d.ts +88 -0
- package/dist/node/agent-client.js +174 -0
- package/dist/node/agent.d.ts +103 -0
- package/dist/node/agent.js +229 -0
- package/dist/node/client.d.ts +90 -0
- package/dist/node/client.js +449 -0
- package/dist/node/completer.d.ts +9 -0
- package/dist/node/completer.js +25 -0
- package/dist/node/data-types.d.ts +44 -0
- package/dist/node/data-types.js +119 -0
- package/dist/node/database-client.d.ts +77 -0
- package/dist/node/database-client.js +113 -0
- package/dist/node/developer-client.d.ts +13 -0
- package/dist/node/developer-client.js +35 -0
- package/dist/node/document.d.ts +84 -0
- package/dist/node/document.js +531 -0
- package/dist/node/entrypoint.d.ts +49722 -0
- package/dist/node/entrypoint.js +6321 -0
- package/dist/node/event-emitter.d.ts +13 -0
- package/dist/node/event-emitter.js +38 -0
- package/dist/node/helpers.d.ts +26 -0
- package/dist/node/helpers.js +79 -0
- package/dist/node/index.d.ts +24 -0
- package/dist/node/index.js +40 -0
- package/dist/node/messaging-client.d.ts +76 -0
- package/dist/node/messaging-client.js +248 -0
- package/dist/node/participant-token.d.ts +36 -0
- package/dist/node/participant-token.js +104 -0
- package/dist/node/participant.d.ts +18 -0
- package/dist/node/participant.js +42 -0
- package/dist/node/protocol.d.ts +87 -0
- package/dist/node/protocol.js +305 -0
- package/dist/node/queues-client.d.ts +26 -0
- package/dist/node/queues-client.js +47 -0
- package/dist/node/requirement.d.ts +25 -0
- package/dist/node/requirement.js +49 -0
- package/dist/node/response.d.ts +60 -0
- package/dist/node/response.js +138 -0
- package/dist/node/room-client.d.ts +43 -0
- package/dist/node/room-client.js +109 -0
- package/dist/node/room-event.d.ts +60 -0
- package/dist/node/room-event.js +82 -0
- package/dist/node/room-server-client.d.ts +19 -0
- package/dist/node/room-server-client.js +50 -0
- package/dist/node/runtime.d.ts +6 -0
- package/dist/node/runtime.js +8 -0
- package/dist/node/schema.d.ts +83 -0
- package/dist/node/schema.js +321 -0
- package/dist/node/storage-client.d.ts +38 -0
- package/dist/node/storage-client.js +86 -0
- package/dist/node/stream-controller.d.ts +8 -0
- package/dist/node/stream-controller.js +55 -0
- package/dist/node/sync-client.d.ts +33 -0
- package/dist/node/sync-client.js +123 -0
- package/dist/node/utils.d.ts +14 -0
- package/dist/node/utils.js +59 -0
- package/package.json +36 -22
- package/README.md +0 -0
- package/babel.config.cjs +0 -3
- package/client.js +0 -422
- package/dist/entrypoint.js +0 -11262
- package/dist/entrypoint.js.map +0 -7
- package/document-server-client.js +0 -246
- package/entrypoint.js +0 -11568
- package/index.js +0 -2
- package/protocol.js +0 -459
- package/server.js +0 -310
- package/test/assert.js +0 -19
- package/test/document-server-client.test.js +0 -33
- package/test/document.test.js +0 -313
- package/test/protocol.test.js +0 -64
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export type EventHandler<T> = (event: T) => void;
|
|
2
|
+
export type EventName = string | symbol;
|
|
3
|
+
export declare class EventEmitter<T> {
|
|
4
|
+
private eventMap;
|
|
5
|
+
constructor();
|
|
6
|
+
addListener: (eventName: EventName, callback: EventHandler<T>) => void;
|
|
7
|
+
removeListener: (eventName: EventName, callback: EventHandler<T>) => void;
|
|
8
|
+
notifyListeners: (eventName: EventName, event: T) => void;
|
|
9
|
+
on: (eventName: EventName, callback: EventHandler<T>) => void;
|
|
10
|
+
off: (eventName: EventName, callback: EventHandler<T>) => void;
|
|
11
|
+
emit: (eventName: EventName, event: T) => void;
|
|
12
|
+
dispose(): void;
|
|
13
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.EventEmitter = void 0;
|
|
4
|
+
class EventEmitter {
|
|
5
|
+
constructor() {
|
|
6
|
+
this.addListener = (eventName, callback) => {
|
|
7
|
+
const listeners = this.eventMap.get(eventName);
|
|
8
|
+
if (listeners) {
|
|
9
|
+
listeners.push(callback);
|
|
10
|
+
}
|
|
11
|
+
else {
|
|
12
|
+
this.eventMap.set(eventName, [callback]);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
this.removeListener = (eventName, callback) => {
|
|
16
|
+
const listeners = this.eventMap.get(eventName) || [];
|
|
17
|
+
this.eventMap.set(eventName, listeners.filter((listener) => listener !== callback));
|
|
18
|
+
};
|
|
19
|
+
this.notifyListeners = (eventName, event) => {
|
|
20
|
+
const listeners = this.eventMap.get(eventName) || [];
|
|
21
|
+
listeners.forEach((listener) => listener(event));
|
|
22
|
+
};
|
|
23
|
+
this.on = (eventName, callback) => {
|
|
24
|
+
this.addListener(eventName, callback);
|
|
25
|
+
};
|
|
26
|
+
this.off = (eventName, callback) => {
|
|
27
|
+
this.removeListener(eventName, callback);
|
|
28
|
+
};
|
|
29
|
+
this.emit = (eventName, event) => {
|
|
30
|
+
this.notifyListeners(eventName, event);
|
|
31
|
+
};
|
|
32
|
+
this.eventMap = new Map();
|
|
33
|
+
}
|
|
34
|
+
dispose() {
|
|
35
|
+
this.eventMap.clear();
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.EventEmitter = EventEmitter;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { MeshSchema } from './schema';
|
|
2
|
+
import { RoomClient } from './room-client';
|
|
3
|
+
import { ParticipantToken } from './participant-token';
|
|
4
|
+
import { WebSocketClientProtocol } from './protocol';
|
|
5
|
+
export declare function validateSchemaName(name: string): void;
|
|
6
|
+
export declare function deploySchema({ room, schema, name, overwrite }: {
|
|
7
|
+
room: RoomClient;
|
|
8
|
+
schema: MeshSchema;
|
|
9
|
+
name: string;
|
|
10
|
+
overwrite?: boolean;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
export declare function meshagentBaseUrl(baseUrl?: string): string;
|
|
13
|
+
export declare function websocketRoomUrl({ roomName, baseUrl }: {
|
|
14
|
+
roomName: string;
|
|
15
|
+
baseUrl?: string;
|
|
16
|
+
}): string;
|
|
17
|
+
export declare function participantToken({ participantName, roomName, role }: {
|
|
18
|
+
participantName: string;
|
|
19
|
+
roomName: string;
|
|
20
|
+
role?: string;
|
|
21
|
+
}): ParticipantToken;
|
|
22
|
+
export declare function websocketProtocol({ participantName, roomName, role }: {
|
|
23
|
+
participantName: string;
|
|
24
|
+
roomName: string;
|
|
25
|
+
role?: string;
|
|
26
|
+
}): Promise<WebSocketClientProtocol>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateSchemaName = validateSchemaName;
|
|
4
|
+
exports.deploySchema = deploySchema;
|
|
5
|
+
exports.meshagentBaseUrl = meshagentBaseUrl;
|
|
6
|
+
exports.websocketRoomUrl = websocketRoomUrl;
|
|
7
|
+
exports.participantToken = participantToken;
|
|
8
|
+
exports.websocketProtocol = websocketProtocol;
|
|
9
|
+
const schema_1 = require("./schema");
|
|
10
|
+
const participant_token_1 = require("./participant-token");
|
|
11
|
+
const protocol_1 = require("./protocol");
|
|
12
|
+
function validateSchemaName(name) {
|
|
13
|
+
if (name.includes('.')) {
|
|
14
|
+
throw new schema_1.MeshSchemaValidationException("schema name cannot contain '.'");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
async function deploySchema({ room, schema, name, overwrite = true }) {
|
|
18
|
+
validateSchemaName(name);
|
|
19
|
+
const handle = await room.storage.open(`.schemas/${name}.json`, { overwrite });
|
|
20
|
+
const data = Buffer.from(JSON.stringify(schema.toJson()), 'utf-8');
|
|
21
|
+
await room.storage.write(handle, data);
|
|
22
|
+
await room.storage.close(handle);
|
|
23
|
+
}
|
|
24
|
+
function meshagentBaseUrl(baseUrl) {
|
|
25
|
+
if (baseUrl) {
|
|
26
|
+
return baseUrl;
|
|
27
|
+
}
|
|
28
|
+
return process.env.MESHAGENT_API_URL || 'https://api.meshagent.com';
|
|
29
|
+
}
|
|
30
|
+
function websocketRoomUrl({ roomName, baseUrl }) {
|
|
31
|
+
if (!baseUrl) {
|
|
32
|
+
const envApiUrl = process.env.MESHAGENT_API_URL;
|
|
33
|
+
if (!envApiUrl) {
|
|
34
|
+
baseUrl = 'wss://api.meshagent.com';
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
if (envApiUrl.startsWith('https:')) {
|
|
38
|
+
baseUrl = 'wss:' + envApiUrl.substring('https:'.length);
|
|
39
|
+
}
|
|
40
|
+
else if (envApiUrl.startsWith('http:')) {
|
|
41
|
+
baseUrl = 'ws:' + envApiUrl.substring('http:'.length);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
baseUrl = envApiUrl;
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
return `${baseUrl}/rooms/${roomName}`;
|
|
49
|
+
}
|
|
50
|
+
function participantToken({ participantName, roomName, role }) {
|
|
51
|
+
const projectId = process.env.MESHAGENT_PROJECT_ID;
|
|
52
|
+
const apiKeyId = process.env.MESHAGENT_KEY_ID;
|
|
53
|
+
const secret = process.env.MESHAGENT_SECRET;
|
|
54
|
+
if (!projectId) {
|
|
55
|
+
throw new Error('MESHAGENT_PROJECT_ID must be set. You can find this in the Meshagent Studio under API keys.');
|
|
56
|
+
}
|
|
57
|
+
if (!apiKeyId) {
|
|
58
|
+
throw new Error('MESHAGENT_KEY_ID must be set. You can find this in the Meshagent Studio under API keys.');
|
|
59
|
+
}
|
|
60
|
+
if (!secret) {
|
|
61
|
+
throw new Error('MESHAGENT_SECRET must be set. You can find this in the Meshagent Studio under API keys.');
|
|
62
|
+
}
|
|
63
|
+
const token = new participant_token_1.ParticipantToken({ name: participantName, projectId, apiKeyId });
|
|
64
|
+
token.addRoomGrant(roomName);
|
|
65
|
+
if (role) {
|
|
66
|
+
token.addRoleGrant(role);
|
|
67
|
+
}
|
|
68
|
+
return token;
|
|
69
|
+
}
|
|
70
|
+
async function websocketProtocol({ participantName, roomName, role }) {
|
|
71
|
+
const url = websocketRoomUrl({ roomName });
|
|
72
|
+
const token = participantToken({ participantName, roomName, role });
|
|
73
|
+
const secret = process.env.MESHAGENT_SECRET;
|
|
74
|
+
if (!secret) {
|
|
75
|
+
throw new Error('MESHAGENT_SECRET must be set in the environment.');
|
|
76
|
+
}
|
|
77
|
+
const jwt = await token.toJwt({ token: secret });
|
|
78
|
+
return new protocol_1.WebSocketClientProtocol({ url, token: jwt });
|
|
79
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
export * from './agent';
|
|
2
|
+
export * from './event-emitter';
|
|
3
|
+
export * from './client';
|
|
4
|
+
export * from './completer';
|
|
5
|
+
export * from './data-types';
|
|
6
|
+
export * from './database-client';
|
|
7
|
+
export * from './developer-client';
|
|
8
|
+
export * from './document';
|
|
9
|
+
export * from './messaging-client';
|
|
10
|
+
export * from './participant-token';
|
|
11
|
+
export * from './participant';
|
|
12
|
+
export * from './protocol';
|
|
13
|
+
export * from './queues-client';
|
|
14
|
+
export * from './requirement';
|
|
15
|
+
export * from './response';
|
|
16
|
+
export * from './room-client';
|
|
17
|
+
export * from './room-event';
|
|
18
|
+
export * from './room-server-client';
|
|
19
|
+
export * from './runtime';
|
|
20
|
+
export * from './schema';
|
|
21
|
+
export * from './storage-client';
|
|
22
|
+
export * from './stream-controller';
|
|
23
|
+
export * from './sync-client';
|
|
24
|
+
export * from './helpers';
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./agent"), exports);
|
|
18
|
+
__exportStar(require("./event-emitter"), exports);
|
|
19
|
+
__exportStar(require("./client"), exports);
|
|
20
|
+
__exportStar(require("./completer"), exports);
|
|
21
|
+
__exportStar(require("./data-types"), exports);
|
|
22
|
+
__exportStar(require("./database-client"), exports);
|
|
23
|
+
__exportStar(require("./developer-client"), exports);
|
|
24
|
+
__exportStar(require("./document"), exports);
|
|
25
|
+
__exportStar(require("./messaging-client"), exports);
|
|
26
|
+
__exportStar(require("./participant-token"), exports);
|
|
27
|
+
__exportStar(require("./participant"), exports);
|
|
28
|
+
__exportStar(require("./protocol"), exports);
|
|
29
|
+
__exportStar(require("./queues-client"), exports);
|
|
30
|
+
__exportStar(require("./requirement"), exports);
|
|
31
|
+
__exportStar(require("./response"), exports);
|
|
32
|
+
__exportStar(require("./room-client"), exports);
|
|
33
|
+
__exportStar(require("./room-event"), exports);
|
|
34
|
+
__exportStar(require("./room-server-client"), exports);
|
|
35
|
+
__exportStar(require("./runtime"), exports);
|
|
36
|
+
__exportStar(require("./schema"), exports);
|
|
37
|
+
__exportStar(require("./storage-client"), exports);
|
|
38
|
+
__exportStar(require("./stream-controller"), exports);
|
|
39
|
+
__exportStar(require("./sync-client"), exports);
|
|
40
|
+
__exportStar(require("./helpers"), exports);
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { EventEmitter } from "./event-emitter";
|
|
2
|
+
import { RoomClient } from "./room-client";
|
|
3
|
+
import { Participant, RemoteParticipant } from "./participant";
|
|
4
|
+
import { RoomMessageEvent } from "./room-event";
|
|
5
|
+
import { StreamController } from "./stream-controller";
|
|
6
|
+
export declare class MessageStreamChunk {
|
|
7
|
+
header: Record<string, any>;
|
|
8
|
+
data?: Uint8Array;
|
|
9
|
+
constructor({ header, data }: {
|
|
10
|
+
header: Record<string, any>;
|
|
11
|
+
data?: Uint8Array;
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
export declare class MessagingClient extends EventEmitter<RoomMessageEvent> {
|
|
15
|
+
private client;
|
|
16
|
+
private _streamWriters;
|
|
17
|
+
private _streamReaders;
|
|
18
|
+
private _onStreamAcceptCallback?;
|
|
19
|
+
private _participants;
|
|
20
|
+
constructor({ room }: {
|
|
21
|
+
room: RoomClient;
|
|
22
|
+
});
|
|
23
|
+
createStream({ to, header }: {
|
|
24
|
+
to: Participant;
|
|
25
|
+
header: Record<string, any>;
|
|
26
|
+
}): Promise<MessageStreamWriter>;
|
|
27
|
+
sendMessage({ to, type, message, attachment }: {
|
|
28
|
+
to: Participant;
|
|
29
|
+
type: string;
|
|
30
|
+
message: Record<string, any>;
|
|
31
|
+
attachment?: Uint8Array;
|
|
32
|
+
}): Promise<void>;
|
|
33
|
+
enable(onStreamAccept?: (reader: MessageStreamReader) => void): Promise<void>;
|
|
34
|
+
disable(): Promise<void>;
|
|
35
|
+
broadcastMessage({ type, message, attachment }: {
|
|
36
|
+
type: string;
|
|
37
|
+
message: Record<string, any>;
|
|
38
|
+
attachment?: Uint8Array;
|
|
39
|
+
}): Promise<void>;
|
|
40
|
+
get remoteParticipants(): Iterable<RemoteParticipant>;
|
|
41
|
+
private _handleMessageSend;
|
|
42
|
+
private _onParticipantEnabled;
|
|
43
|
+
private _onParticipantAttributes;
|
|
44
|
+
private _onParticipantDisabled;
|
|
45
|
+
private _onMessagingEnabled;
|
|
46
|
+
private _onStreamOpen;
|
|
47
|
+
private _onStreamAccept;
|
|
48
|
+
private _onStreamReject;
|
|
49
|
+
private _onStreamChunk;
|
|
50
|
+
private _onStreamClose;
|
|
51
|
+
dispose(): void;
|
|
52
|
+
}
|
|
53
|
+
export declare class MessageStreamWriter {
|
|
54
|
+
private _streamId;
|
|
55
|
+
private _to;
|
|
56
|
+
private _client;
|
|
57
|
+
constructor({ streamId, to, client }: {
|
|
58
|
+
streamId: string;
|
|
59
|
+
to: Participant;
|
|
60
|
+
client: MessagingClient;
|
|
61
|
+
});
|
|
62
|
+
write(chunk: MessageStreamChunk): Promise<void>;
|
|
63
|
+
close(): Promise<void>;
|
|
64
|
+
}
|
|
65
|
+
export declare class MessageStreamReader {
|
|
66
|
+
_streamId: string;
|
|
67
|
+
_to: Participant;
|
|
68
|
+
_client: MessagingClient;
|
|
69
|
+
_controller: StreamController<MessageStreamChunk>;
|
|
70
|
+
constructor({ streamId, to, client, controller }: {
|
|
71
|
+
streamId: string;
|
|
72
|
+
to: Participant;
|
|
73
|
+
client: MessagingClient;
|
|
74
|
+
controller: StreamController<MessageStreamChunk>;
|
|
75
|
+
});
|
|
76
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MessageStreamReader = exports.MessageStreamWriter = exports.MessagingClient = exports.MessageStreamChunk = void 0;
|
|
4
|
+
const uuid_1 = require("uuid");
|
|
5
|
+
const event_emitter_1 = require("./event-emitter");
|
|
6
|
+
const participant_1 = require("./participant");
|
|
7
|
+
const room_event_1 = require("./room-event");
|
|
8
|
+
const utils_1 = require("./utils");
|
|
9
|
+
const stream_controller_1 = require("./stream-controller");
|
|
10
|
+
const completer_1 = require("./completer");
|
|
11
|
+
class MessageStreamChunk {
|
|
12
|
+
constructor({ header, data }) {
|
|
13
|
+
this.header = header;
|
|
14
|
+
this.data = data;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
exports.MessageStreamChunk = MessageStreamChunk;
|
|
18
|
+
class MessagingClient extends event_emitter_1.EventEmitter {
|
|
19
|
+
constructor({ room }) {
|
|
20
|
+
super();
|
|
21
|
+
this._streamWriters = {};
|
|
22
|
+
this._streamReaders = {};
|
|
23
|
+
this._participants = {};
|
|
24
|
+
this.client = room;
|
|
25
|
+
this.client.protocol.addHandler("messaging.send", this._handleMessageSend.bind(this));
|
|
26
|
+
}
|
|
27
|
+
async createStream({ to, header }) {
|
|
28
|
+
const streamId = (0, uuid_1.v4)();
|
|
29
|
+
const completer = new completer_1.Completer();
|
|
30
|
+
this._streamWriters[streamId] = completer;
|
|
31
|
+
await this.sendMessage({
|
|
32
|
+
to,
|
|
33
|
+
type: "stream.open",
|
|
34
|
+
message: { stream_id: streamId, header },
|
|
35
|
+
});
|
|
36
|
+
return completer.fut;
|
|
37
|
+
}
|
|
38
|
+
async sendMessage({ to, type, message, attachment }) {
|
|
39
|
+
await this.client.sendRequest("messaging.send", {
|
|
40
|
+
to_participant_id: to.id,
|
|
41
|
+
type,
|
|
42
|
+
message,
|
|
43
|
+
}, attachment);
|
|
44
|
+
}
|
|
45
|
+
async enable(onStreamAccept) {
|
|
46
|
+
await this.client.sendRequest("messaging.enable", {});
|
|
47
|
+
this._onStreamAcceptCallback = onStreamAccept;
|
|
48
|
+
}
|
|
49
|
+
async disable() {
|
|
50
|
+
await this.client.sendRequest("messaging.disable", {});
|
|
51
|
+
}
|
|
52
|
+
async broadcastMessage({ type, message, attachment }) {
|
|
53
|
+
await this.client.sendRequest("messaging.broadcast", { type, message }, attachment);
|
|
54
|
+
}
|
|
55
|
+
get remoteParticipants() {
|
|
56
|
+
return Object.values(this._participants);
|
|
57
|
+
}
|
|
58
|
+
async _handleMessageSend(protocol, messageId, type, bytes) {
|
|
59
|
+
const headerStr = (0, utils_1.splitMessageHeader)(bytes || new Uint8Array());
|
|
60
|
+
const payload = (0, utils_1.splitMessagePayload)(bytes || new Uint8Array());
|
|
61
|
+
const header = JSON.parse(headerStr);
|
|
62
|
+
const message = new room_event_1.RoomMessage({
|
|
63
|
+
fromParticipantId: header["from_participant_id"],
|
|
64
|
+
type: header["type"],
|
|
65
|
+
message: header["message"],
|
|
66
|
+
attachment: payload,
|
|
67
|
+
});
|
|
68
|
+
switch (message.type) {
|
|
69
|
+
case "messaging.enabled":
|
|
70
|
+
this._onMessagingEnabled(message);
|
|
71
|
+
break;
|
|
72
|
+
case "participant.attributes":
|
|
73
|
+
this._onParticipantAttributes(message);
|
|
74
|
+
break;
|
|
75
|
+
case "participant.enabled":
|
|
76
|
+
this._onParticipantEnabled(message);
|
|
77
|
+
break;
|
|
78
|
+
case "participant.disabled":
|
|
79
|
+
this._onParticipantDisabled(message);
|
|
80
|
+
break;
|
|
81
|
+
case "stream.open":
|
|
82
|
+
this._onStreamOpen(message);
|
|
83
|
+
break;
|
|
84
|
+
case "stream.accept":
|
|
85
|
+
this._onStreamAccept(message);
|
|
86
|
+
break;
|
|
87
|
+
case "stream.reject":
|
|
88
|
+
this._onStreamReject(message);
|
|
89
|
+
break;
|
|
90
|
+
case "stream.chunk":
|
|
91
|
+
this._onStreamChunk(message);
|
|
92
|
+
break;
|
|
93
|
+
case "stream.close":
|
|
94
|
+
this._onStreamClose(message);
|
|
95
|
+
break;
|
|
96
|
+
}
|
|
97
|
+
const messageEvent = { message };
|
|
98
|
+
this.client.emit(messageEvent);
|
|
99
|
+
this.emit("message", messageEvent);
|
|
100
|
+
}
|
|
101
|
+
_onParticipantEnabled(message) {
|
|
102
|
+
const data = message.message;
|
|
103
|
+
const p = new participant_1.RemoteParticipant(this.client, data["id"], data["role"]);
|
|
104
|
+
for (const [k, v] of Object.entries(data["attributes"] || {})) {
|
|
105
|
+
p._attributes[k] = v;
|
|
106
|
+
}
|
|
107
|
+
this._participants[data["id"]] = p;
|
|
108
|
+
this.emit("participant_added", { message });
|
|
109
|
+
}
|
|
110
|
+
_onParticipantAttributes(message) {
|
|
111
|
+
const part = this._participants[message.fromParticipantId];
|
|
112
|
+
if (!part)
|
|
113
|
+
return;
|
|
114
|
+
const attrObj = message.message["attributes"];
|
|
115
|
+
for (const [k, v] of Object.entries(attrObj)) {
|
|
116
|
+
part._attributes[k] = v;
|
|
117
|
+
}
|
|
118
|
+
this.emit("participant_attributes_updated", { message });
|
|
119
|
+
}
|
|
120
|
+
_onParticipantDisabled(message) {
|
|
121
|
+
const part = this._participants[message.message["id"]];
|
|
122
|
+
if (part) {
|
|
123
|
+
delete this._participants[message.message["id"]];
|
|
124
|
+
this.emit("participant_removed", { message });
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
_onMessagingEnabled(message) {
|
|
128
|
+
const participants = message.message["participants"];
|
|
129
|
+
for (const data of participants) {
|
|
130
|
+
const rp = new participant_1.RemoteParticipant(this.client, data["id"], data["role"]);
|
|
131
|
+
for (const [k, v] of Object.entries(data["attributes"] || {})) {
|
|
132
|
+
rp._attributes[k] = v;
|
|
133
|
+
}
|
|
134
|
+
this._participants[data["id"]] = rp;
|
|
135
|
+
}
|
|
136
|
+
this.emit("messaging_enabled", { message });
|
|
137
|
+
}
|
|
138
|
+
_onStreamOpen(message) {
|
|
139
|
+
const from = [...this.remoteParticipants]
|
|
140
|
+
.find((x) => x.id === message.fromParticipantId);
|
|
141
|
+
if (!from)
|
|
142
|
+
return;
|
|
143
|
+
const streamId = message.message["stream_id"];
|
|
144
|
+
const controller = new stream_controller_1.StreamController();
|
|
145
|
+
const reader = new MessageStreamReader({
|
|
146
|
+
streamId,
|
|
147
|
+
to: from,
|
|
148
|
+
client: this,
|
|
149
|
+
controller,
|
|
150
|
+
});
|
|
151
|
+
try {
|
|
152
|
+
if (!this._onStreamAcceptCallback) {
|
|
153
|
+
throw new Error("streams are not allowed by this client");
|
|
154
|
+
}
|
|
155
|
+
this._onStreamAcceptCallback(reader);
|
|
156
|
+
this.sendMessage({
|
|
157
|
+
to: from,
|
|
158
|
+
type: "stream.accept",
|
|
159
|
+
message: { stream_id: streamId },
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
catch (e) {
|
|
163
|
+
this.sendMessage({
|
|
164
|
+
to: from,
|
|
165
|
+
type: "stream.reject",
|
|
166
|
+
message: { stream_id: streamId, error: String(e) },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
this._streamReaders[streamId] = reader;
|
|
170
|
+
this.emit("stream_opened", { message });
|
|
171
|
+
}
|
|
172
|
+
_onStreamAccept(message) {
|
|
173
|
+
const streamId = message.message["stream_id"];
|
|
174
|
+
const writerCompleter = this._streamWriters[streamId];
|
|
175
|
+
if (!writerCompleter)
|
|
176
|
+
return;
|
|
177
|
+
const from = [...this.remoteParticipants].find((x) => x.id === message.fromParticipantId);
|
|
178
|
+
if (!from)
|
|
179
|
+
return;
|
|
180
|
+
writerCompleter.complete(new MessageStreamWriter({
|
|
181
|
+
streamId,
|
|
182
|
+
to: from,
|
|
183
|
+
client: this,
|
|
184
|
+
}));
|
|
185
|
+
}
|
|
186
|
+
_onStreamReject(message) {
|
|
187
|
+
const streamId = message.message["stream_id"];
|
|
188
|
+
const writerCompleter = this._streamWriters[streamId];
|
|
189
|
+
if (!writerCompleter)
|
|
190
|
+
return;
|
|
191
|
+
writerCompleter.completeError(new Error("The stream was rejected by the remote client"));
|
|
192
|
+
}
|
|
193
|
+
_onStreamChunk(message) {
|
|
194
|
+
const streamId = message.message["stream_id"];
|
|
195
|
+
const reader = this._streamReaders[streamId];
|
|
196
|
+
if (!reader)
|
|
197
|
+
return;
|
|
198
|
+
reader._controller.add(new MessageStreamChunk({
|
|
199
|
+
header: message.message,
|
|
200
|
+
data: message.attachment,
|
|
201
|
+
}));
|
|
202
|
+
}
|
|
203
|
+
_onStreamClose(message) {
|
|
204
|
+
const streamId = message.message["stream_id"];
|
|
205
|
+
const reader = this._streamReaders[streamId];
|
|
206
|
+
if (!reader)
|
|
207
|
+
return;
|
|
208
|
+
reader._controller.close();
|
|
209
|
+
delete this._streamReaders[streamId];
|
|
210
|
+
}
|
|
211
|
+
dispose() {
|
|
212
|
+
super.dispose();
|
|
213
|
+
this.client.protocol.removeHandler("messaging.send");
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
exports.MessagingClient = MessagingClient;
|
|
217
|
+
class MessageStreamWriter {
|
|
218
|
+
constructor({ streamId, to, client }) {
|
|
219
|
+
this._streamId = streamId;
|
|
220
|
+
this._to = to;
|
|
221
|
+
this._client = client;
|
|
222
|
+
}
|
|
223
|
+
async write(chunk) {
|
|
224
|
+
await this._client.sendMessage({
|
|
225
|
+
to: this._to,
|
|
226
|
+
type: "stream.chunk",
|
|
227
|
+
message: { stream_id: this._streamId, header: chunk.header },
|
|
228
|
+
attachment: chunk.data,
|
|
229
|
+
});
|
|
230
|
+
}
|
|
231
|
+
async close() {
|
|
232
|
+
await this._client.sendMessage({
|
|
233
|
+
to: this._to,
|
|
234
|
+
type: "stream.close",
|
|
235
|
+
message: { stream_id: this._streamId },
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
exports.MessageStreamWriter = MessageStreamWriter;
|
|
240
|
+
class MessageStreamReader {
|
|
241
|
+
constructor({ streamId, to, client, controller }) {
|
|
242
|
+
this._streamId = streamId;
|
|
243
|
+
this._to = to;
|
|
244
|
+
this._client = client;
|
|
245
|
+
this._controller = controller;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.MessageStreamReader = MessageStreamReader;
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
export declare class ParticipantGrant {
|
|
2
|
+
name: string;
|
|
3
|
+
scope?: string;
|
|
4
|
+
constructor({ name, scope }: {
|
|
5
|
+
name: string;
|
|
6
|
+
scope?: string;
|
|
7
|
+
});
|
|
8
|
+
toJson(): Record<string, any>;
|
|
9
|
+
static fromJson(json: Record<string, any>): ParticipantGrant;
|
|
10
|
+
}
|
|
11
|
+
export declare class ParticipantToken {
|
|
12
|
+
name: string;
|
|
13
|
+
projectId?: string;
|
|
14
|
+
apiKeyId?: string;
|
|
15
|
+
grants: ParticipantGrant[];
|
|
16
|
+
extra?: Record<string, any>;
|
|
17
|
+
constructor({ name, projectId, apiKeyId, extra, grants, }: {
|
|
18
|
+
name: string;
|
|
19
|
+
projectId: string;
|
|
20
|
+
apiKeyId: string;
|
|
21
|
+
extra?: Record<string, any>;
|
|
22
|
+
grants?: ParticipantGrant[];
|
|
23
|
+
});
|
|
24
|
+
get isAgent(): boolean;
|
|
25
|
+
addRoleGrant(role: string): void;
|
|
26
|
+
addRoomGrant(roomName: string): void;
|
|
27
|
+
toJson(): Record<string, any>;
|
|
28
|
+
toJwt({ token }: {
|
|
29
|
+
token?: string;
|
|
30
|
+
}): Promise<string>;
|
|
31
|
+
static fromJson(json: Record<string, any>): ParticipantToken;
|
|
32
|
+
static fromJwt(jwtStr: string, options?: {
|
|
33
|
+
token?: string;
|
|
34
|
+
verify?: boolean;
|
|
35
|
+
}): Promise<ParticipantToken>;
|
|
36
|
+
}
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ParticipantToken = exports.ParticipantGrant = void 0;
|
|
4
|
+
const jose_1 = require("jose");
|
|
5
|
+
class ParticipantGrant {
|
|
6
|
+
constructor({ name, scope }) {
|
|
7
|
+
this.name = name;
|
|
8
|
+
this.scope = scope;
|
|
9
|
+
}
|
|
10
|
+
toJson() {
|
|
11
|
+
return {
|
|
12
|
+
name: this.name,
|
|
13
|
+
scope: this.scope,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
static fromJson(json) {
|
|
17
|
+
return new ParticipantGrant({
|
|
18
|
+
name: json["name"],
|
|
19
|
+
scope: json["scope"],
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
exports.ParticipantGrant = ParticipantGrant;
|
|
24
|
+
class ParticipantToken {
|
|
25
|
+
constructor({ name, projectId, apiKeyId, extra, grants, }) {
|
|
26
|
+
this.name = name;
|
|
27
|
+
this.projectId = projectId;
|
|
28
|
+
this.apiKeyId = apiKeyId;
|
|
29
|
+
this.extra = extra ?? {};
|
|
30
|
+
this.grants = grants ?? [];
|
|
31
|
+
}
|
|
32
|
+
get isAgent() {
|
|
33
|
+
for (const grant of this.grants) {
|
|
34
|
+
if (grant.name === "role" && grant.scope === "agent") {
|
|
35
|
+
return true;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
addRoleGrant(role) {
|
|
41
|
+
this.grants.push(new ParticipantGrant({ name: "role", scope: role }));
|
|
42
|
+
}
|
|
43
|
+
addRoomGrant(roomName) {
|
|
44
|
+
this.grants.push(new ParticipantGrant({ name: "room", scope: roomName }));
|
|
45
|
+
}
|
|
46
|
+
toJson() {
|
|
47
|
+
return {
|
|
48
|
+
name: this.name,
|
|
49
|
+
...(this.projectId ? { sub: this.projectId } : {}),
|
|
50
|
+
...(this.apiKeyId ? { kid: this.apiKeyId } : {}),
|
|
51
|
+
grants: this.grants.map((g) => g.toJson()),
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async toJwt({ token }) {
|
|
55
|
+
const secret = token || process.env.MESHAGENT_SECRET;
|
|
56
|
+
if (!secret) {
|
|
57
|
+
throw new Error("No secret provided. Provide `token` or set MESHAGENT_SECRET in environment.");
|
|
58
|
+
}
|
|
59
|
+
const secretKey = new TextEncoder().encode(secret);
|
|
60
|
+
const payload = {
|
|
61
|
+
...this.toJson(),
|
|
62
|
+
...this.extra,
|
|
63
|
+
};
|
|
64
|
+
const jwt = await new jose_1.SignJWT(payload)
|
|
65
|
+
.setProtectedHeader({ alg: "HS256", typ: "JWT" })
|
|
66
|
+
.sign(secretKey);
|
|
67
|
+
return jwt;
|
|
68
|
+
}
|
|
69
|
+
static fromJson(json) {
|
|
70
|
+
const { name, sub, grants, kid, ...rest } = json;
|
|
71
|
+
const extra = { ...rest };
|
|
72
|
+
return new ParticipantToken({
|
|
73
|
+
name: name,
|
|
74
|
+
projectId: sub,
|
|
75
|
+
apiKeyId: kid,
|
|
76
|
+
grants: grants?.map((g) => ParticipantGrant.fromJson(g)),
|
|
77
|
+
extra,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
static async fromJwt(jwtStr, options) {
|
|
81
|
+
const { token, verify = true } = options || {};
|
|
82
|
+
if (verify) {
|
|
83
|
+
const secret = token || process.env.MESHAGENT_SECRET;
|
|
84
|
+
if (!secret) {
|
|
85
|
+
throw new Error("No secret provided to verify JWT. Provide `token` or set MESHAGENT_SECRET");
|
|
86
|
+
}
|
|
87
|
+
const secretKey = new TextEncoder().encode(secret);
|
|
88
|
+
const { payload } = await (0, jose_1.jwtVerify)(jwtStr, secretKey, {
|
|
89
|
+
algorithms: ["HS256"],
|
|
90
|
+
});
|
|
91
|
+
return ParticipantToken.fromJson(payload);
|
|
92
|
+
}
|
|
93
|
+
else {
|
|
94
|
+
try {
|
|
95
|
+
const payload = (0, jose_1.decodeJwt)(jwtStr);
|
|
96
|
+
return ParticipantToken.fromJson(payload);
|
|
97
|
+
}
|
|
98
|
+
catch (err) {
|
|
99
|
+
throw new Error("Failed to decode JWT");
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
exports.ParticipantToken = ParticipantToken;
|