@ajna-inc/webrtc 0.2.1 → 0.6.1
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/.npmvc/attestations.jsonld +32 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs +10 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs +7 -0
- package/build/_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateParam.mjs +9 -0
- package/build/index.d.mts +11 -0
- package/build/index.mjs +12 -0
- package/build/webrtc/WebRTCApi.d.mts +131 -0
- package/build/webrtc/WebRTCApi.d.mts.map +1 -0
- package/build/webrtc/WebRTCApi.mjs +161 -0
- package/build/webrtc/WebRTCApi.mjs.map +1 -0
- package/build/webrtc/WebRTCEvents.d.mts +115 -0
- package/build/webrtc/WebRTCEvents.d.mts.map +1 -0
- package/build/webrtc/WebRTCEvents.mjs +20 -0
- package/build/webrtc/WebRTCEvents.mjs.map +1 -0
- package/build/webrtc/WebRTCModule.d.mts +63 -0
- package/build/webrtc/WebRTCModule.d.mts.map +1 -0
- package/build/webrtc/WebRTCModule.mjs +51 -0
- package/build/webrtc/WebRTCModule.mjs.map +1 -0
- package/build/webrtc/handlers/AnswerHandler.mjs +23 -0
- package/build/webrtc/handlers/AnswerHandler.mjs.map +1 -0
- package/build/webrtc/handlers/EndHandler.mjs +23 -0
- package/build/webrtc/handlers/EndHandler.mjs.map +1 -0
- package/build/webrtc/handlers/IceHandler.mjs +23 -0
- package/build/webrtc/handlers/IceHandler.mjs.map +1 -0
- package/build/webrtc/handlers/OfferHandler.mjs +23 -0
- package/build/webrtc/handlers/OfferHandler.mjs.map +1 -0
- package/build/webrtc/handlers/ProposeHandler.mjs +23 -0
- package/build/webrtc/handlers/ProposeHandler.mjs.map +1 -0
- package/build/webrtc/handlers/RenegotiateHandler.mjs +23 -0
- package/build/webrtc/handlers/RenegotiateHandler.mjs.map +1 -0
- package/build/webrtc/handlers/index.mjs +6 -0
- package/build/webrtc/messages/AnswerMessage.d.mts +29 -0
- package/build/webrtc/messages/AnswerMessage.d.mts.map +1 -0
- package/build/webrtc/messages/AnswerMessage.mjs +44 -0
- package/build/webrtc/messages/AnswerMessage.mjs.map +1 -0
- package/build/webrtc/messages/EndMessage.d.mts +19 -0
- package/build/webrtc/messages/EndMessage.d.mts.map +1 -0
- package/build/webrtc/messages/EndMessage.mjs +31 -0
- package/build/webrtc/messages/EndMessage.mjs.map +1 -0
- package/build/webrtc/messages/IceMessage.d.mts +21 -0
- package/build/webrtc/messages/IceMessage.d.mts.map +1 -0
- package/build/webrtc/messages/IceMessage.mjs +38 -0
- package/build/webrtc/messages/IceMessage.mjs.map +1 -0
- package/build/webrtc/messages/OfferMessage.d.mts +56 -0
- package/build/webrtc/messages/OfferMessage.d.mts.map +1 -0
- package/build/webrtc/messages/OfferMessage.mjs +86 -0
- package/build/webrtc/messages/OfferMessage.mjs.map +1 -0
- package/build/webrtc/messages/ProposeMessage.d.mts +70 -0
- package/build/webrtc/messages/ProposeMessage.d.mts.map +1 -0
- package/build/webrtc/messages/ProposeMessage.mjs +76 -0
- package/build/webrtc/messages/ProposeMessage.mjs.map +1 -0
- package/build/webrtc/messages/RenegotiateMessage.d.mts +59 -0
- package/build/webrtc/messages/RenegotiateMessage.d.mts.map +1 -0
- package/build/webrtc/messages/RenegotiateMessage.mjs +56 -0
- package/build/webrtc/messages/RenegotiateMessage.mjs.map +1 -0
- package/build/webrtc/messages/index.d.mts +6 -0
- package/build/webrtc/messages/index.mjs +6 -0
- package/build/webrtc/repository/WebRTCCallRecord.d.mts +32 -0
- package/build/webrtc/repository/WebRTCCallRecord.d.mts.map +1 -0
- package/build/webrtc/repository/WebRTCCallRecord.mjs +31 -0
- package/build/webrtc/repository/WebRTCCallRecord.mjs.map +1 -0
- package/build/webrtc/repository/WebRTCCallRepository.d.mts +10 -0
- package/build/webrtc/repository/WebRTCCallRepository.d.mts.map +1 -0
- package/build/webrtc/repository/WebRTCCallRepository.mjs +23 -0
- package/build/webrtc/repository/WebRTCCallRepository.mjs.map +1 -0
- package/build/webrtc/services/WebRTCService.d.mts +93 -0
- package/build/webrtc/services/WebRTCService.d.mts.map +1 -0
- package/build/webrtc/services/WebRTCService.mjs +244 -0
- package/build/webrtc/services/WebRTCService.mjs.map +1 -0
- package/package.json +19 -15
- package/README.md +0 -222
- package/build/index.d.ts +0 -8
- package/build/index.js +0 -29
- package/build/index.js.map +0 -1
- package/build/webrtc/WebRTCApi.d.ts +0 -125
- package/build/webrtc/WebRTCApi.js +0 -186
- package/build/webrtc/WebRTCApi.js.map +0 -1
- package/build/webrtc/WebRTCEvents.d.ts +0 -110
- package/build/webrtc/WebRTCEvents.js +0 -19
- package/build/webrtc/WebRTCEvents.js.map +0 -1
- package/build/webrtc/WebRTCModule.d.ts +0 -56
- package/build/webrtc/WebRTCModule.js +0 -40
- package/build/webrtc/WebRTCModule.js.map +0 -1
- package/build/webrtc/handlers/AnswerHandler.d.ts +0 -9
- package/build/webrtc/handlers/AnswerHandler.js +0 -31
- package/build/webrtc/handlers/AnswerHandler.js.map +0 -1
- package/build/webrtc/handlers/EndHandler.d.ts +0 -9
- package/build/webrtc/handlers/EndHandler.js +0 -31
- package/build/webrtc/handlers/EndHandler.js.map +0 -1
- package/build/webrtc/handlers/IceHandler.d.ts +0 -9
- package/build/webrtc/handlers/IceHandler.js +0 -31
- package/build/webrtc/handlers/IceHandler.js.map +0 -1
- package/build/webrtc/handlers/OfferHandler.d.ts +0 -9
- package/build/webrtc/handlers/OfferHandler.js +0 -31
- package/build/webrtc/handlers/OfferHandler.js.map +0 -1
- package/build/webrtc/handlers/ProposeHandler.d.ts +0 -9
- package/build/webrtc/handlers/ProposeHandler.js +0 -31
- package/build/webrtc/handlers/ProposeHandler.js.map +0 -1
- package/build/webrtc/handlers/RenegotiateHandler.d.ts +0 -9
- package/build/webrtc/handlers/RenegotiateHandler.js +0 -31
- package/build/webrtc/handlers/RenegotiateHandler.js.map +0 -1
- package/build/webrtc/handlers/index.d.ts +0 -6
- package/build/webrtc/handlers/index.js +0 -23
- package/build/webrtc/handlers/index.js.map +0 -1
- package/build/webrtc/messages/AnswerMessage.d.ts +0 -23
- package/build/webrtc/messages/AnswerMessage.js +0 -52
- package/build/webrtc/messages/AnswerMessage.js.map +0 -1
- package/build/webrtc/messages/EndMessage.d.ts +0 -13
- package/build/webrtc/messages/EndMessage.js +0 -37
- package/build/webrtc/messages/EndMessage.js.map +0 -1
- package/build/webrtc/messages/IceMessage.d.ts +0 -15
- package/build/webrtc/messages/IceMessage.js +0 -43
- package/build/webrtc/messages/IceMessage.js.map +0 -1
- package/build/webrtc/messages/OfferMessage.d.ts +0 -49
- package/build/webrtc/messages/OfferMessage.js +0 -102
- package/build/webrtc/messages/OfferMessage.js.map +0 -1
- package/build/webrtc/messages/ProposeMessage.d.ts +0 -63
- package/build/webrtc/messages/ProposeMessage.js +0 -84
- package/build/webrtc/messages/ProposeMessage.js.map +0 -1
- package/build/webrtc/messages/RenegotiateMessage.d.ts +0 -52
- package/build/webrtc/messages/RenegotiateMessage.js +0 -65
- package/build/webrtc/messages/RenegotiateMessage.js.map +0 -1
- package/build/webrtc/messages/index.d.ts +0 -6
- package/build/webrtc/messages/index.js +0 -23
- package/build/webrtc/messages/index.js.map +0 -1
- package/build/webrtc/repository/WebRTCCallRecord.d.ts +0 -29
- package/build/webrtc/repository/WebRTCCallRecord.js +0 -30
- package/build/webrtc/repository/WebRTCCallRecord.js.map +0 -1
- package/build/webrtc/repository/WebRTCCallRepository.d.ts +0 -5
- package/build/webrtc/repository/WebRTCCallRepository.js +0 -30
- package/build/webrtc/repository/WebRTCCallRepository.js.map +0 -1
- package/build/webrtc/services/WebRTCService.d.ts +0 -86
- package/build/webrtc/services/WebRTCService.js +0 -229
- package/build/webrtc/services/WebRTCService.js.map +0 -1
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { __decorateMetadata } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorateMetadata.mjs";
|
|
2
|
+
import { __decorate } from "../../_virtual/_@oxc-project_runtime@0.99.0/helpers/decorate.mjs";
|
|
3
|
+
import { OfferMessage } from "../messages/OfferMessage.mjs";
|
|
4
|
+
import { ProposeMessage } from "../messages/ProposeMessage.mjs";
|
|
5
|
+
import { AnswerMessage } from "../messages/AnswerMessage.mjs";
|
|
6
|
+
import { IceMessage } from "../messages/IceMessage.mjs";
|
|
7
|
+
import { RenegotiateMessage } from "../messages/RenegotiateMessage.mjs";
|
|
8
|
+
import { EndMessage } from "../messages/EndMessage.mjs";
|
|
9
|
+
import "../messages/index.mjs";
|
|
10
|
+
import { WebRTCEvents } from "../WebRTCEvents.mjs";
|
|
11
|
+
import { WebRTCCallRecord } from "../repository/WebRTCCallRecord.mjs";
|
|
12
|
+
import { WebRTCCallRepository } from "../repository/WebRTCCallRepository.mjs";
|
|
13
|
+
import { EventEmitter } from "@credo-ts/core";
|
|
14
|
+
import { injectable } from "tsyringe";
|
|
15
|
+
|
|
16
|
+
//#region src/webrtc/services/WebRTCService.ts
|
|
17
|
+
var _ref, _ref2;
|
|
18
|
+
let WebRTCService = class WebRTCService$1 {
|
|
19
|
+
constructor(repo, events) {
|
|
20
|
+
this.repo = repo;
|
|
21
|
+
this.events = events;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Create a propose message to initiate a call
|
|
25
|
+
*/
|
|
26
|
+
createPropose(options) {
|
|
27
|
+
return { message: new ProposeMessage({
|
|
28
|
+
threadId: options.threadId,
|
|
29
|
+
parentThreadId: options.parentThreadId,
|
|
30
|
+
media: options.media,
|
|
31
|
+
data: options.data,
|
|
32
|
+
topology: options.topology,
|
|
33
|
+
trickle: options.trickle,
|
|
34
|
+
policy: options.policy,
|
|
35
|
+
iceServers: options.iceServers,
|
|
36
|
+
reason: options.reason
|
|
37
|
+
}) };
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Create an offer message with SDP
|
|
41
|
+
*/
|
|
42
|
+
createOffer(agentContext, connection, threadId, parentThreadId, sdp, iceServers, policy, trickle) {
|
|
43
|
+
return {
|
|
44
|
+
message: new OfferMessage({
|
|
45
|
+
threadId,
|
|
46
|
+
parentThreadId,
|
|
47
|
+
sdp,
|
|
48
|
+
iceServers,
|
|
49
|
+
policy,
|
|
50
|
+
trickle
|
|
51
|
+
}),
|
|
52
|
+
record: new WebRTCCallRecord({
|
|
53
|
+
connectionId: connection.id,
|
|
54
|
+
threadId,
|
|
55
|
+
state: "offered",
|
|
56
|
+
role: "caller"
|
|
57
|
+
})
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Create an answer message with SDP
|
|
62
|
+
*/
|
|
63
|
+
createAnswer(agentContext, connection, threadId, parentThreadId, sdp, iceServers) {
|
|
64
|
+
return { message: new AnswerMessage({
|
|
65
|
+
threadId,
|
|
66
|
+
parentThreadId,
|
|
67
|
+
sdp,
|
|
68
|
+
iceServers
|
|
69
|
+
}) };
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Create an ICE candidate message
|
|
73
|
+
*/
|
|
74
|
+
createIce(threadId, parentThreadId, candidate, endOfCandidates) {
|
|
75
|
+
return new IceMessage({
|
|
76
|
+
threadId,
|
|
77
|
+
parentThreadId,
|
|
78
|
+
candidate,
|
|
79
|
+
endOfCandidates
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Create a renegotiate message (for ICE restart, track changes, etc.)
|
|
84
|
+
*/
|
|
85
|
+
createRenegotiate(options) {
|
|
86
|
+
return new RenegotiateMessage({
|
|
87
|
+
threadId: options.threadId,
|
|
88
|
+
parentThreadId: options.parentThreadId,
|
|
89
|
+
reason: options.reason,
|
|
90
|
+
iceRestart: options.iceRestart,
|
|
91
|
+
iceServers: options.iceServers,
|
|
92
|
+
policy: options.policy
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Create an end call message
|
|
97
|
+
*/
|
|
98
|
+
createEnd(threadId, parentThreadId, reason) {
|
|
99
|
+
return new EndMessage({
|
|
100
|
+
threadId,
|
|
101
|
+
parentThreadId,
|
|
102
|
+
reason
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Process incoming propose message
|
|
107
|
+
*/
|
|
108
|
+
async processPropose(messageContext) {
|
|
109
|
+
const thid = messageContext.message.threadId ?? messageContext.message.id;
|
|
110
|
+
const msg = messageContext.message;
|
|
111
|
+
this.events.emit(messageContext.agentContext, {
|
|
112
|
+
type: WebRTCEvents.IncomingPropose,
|
|
113
|
+
payload: {
|
|
114
|
+
context: messageContext,
|
|
115
|
+
thid,
|
|
116
|
+
pthid: msg.thread?.parentThreadId,
|
|
117
|
+
media: msg.media,
|
|
118
|
+
data: msg.data,
|
|
119
|
+
topology: msg.topology,
|
|
120
|
+
trickle: msg.trickle,
|
|
121
|
+
policy: msg.policy,
|
|
122
|
+
iceServers: msg.iceServers,
|
|
123
|
+
reason: msg.reason
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Process incoming offer message
|
|
129
|
+
*/
|
|
130
|
+
async processOffer(messageContext) {
|
|
131
|
+
const connection = messageContext.assertReadyConnection();
|
|
132
|
+
const thid = messageContext.message.threadId;
|
|
133
|
+
const msg = messageContext.message;
|
|
134
|
+
const record = new WebRTCCallRecord({
|
|
135
|
+
connectionId: connection.id,
|
|
136
|
+
threadId: thid,
|
|
137
|
+
state: "offered",
|
|
138
|
+
role: "callee"
|
|
139
|
+
});
|
|
140
|
+
await this.repo.save(messageContext.agentContext, record);
|
|
141
|
+
this.events.emit(messageContext.agentContext, {
|
|
142
|
+
type: WebRTCEvents.IncomingOffer,
|
|
143
|
+
payload: {
|
|
144
|
+
context: messageContext,
|
|
145
|
+
thid,
|
|
146
|
+
pthid: msg.thread?.parentThreadId,
|
|
147
|
+
sdp: msg.sdp,
|
|
148
|
+
iceServers: msg.iceServers,
|
|
149
|
+
policy: msg.policy,
|
|
150
|
+
trickle: msg.trickle
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Process incoming answer message
|
|
156
|
+
*/
|
|
157
|
+
async processAnswer(messageContext) {
|
|
158
|
+
const connection = messageContext.assertReadyConnection();
|
|
159
|
+
const thid = messageContext.message.threadId;
|
|
160
|
+
const msg = messageContext.message;
|
|
161
|
+
const [record] = await this.repo.findByQuery(messageContext.agentContext, {
|
|
162
|
+
connectionId: connection.id,
|
|
163
|
+
threadId: thid
|
|
164
|
+
});
|
|
165
|
+
if (record) {
|
|
166
|
+
record.state = "answered";
|
|
167
|
+
await this.repo.update(messageContext.agentContext, record);
|
|
168
|
+
}
|
|
169
|
+
this.events.emit(messageContext.agentContext, {
|
|
170
|
+
type: WebRTCEvents.IncomingAnswer,
|
|
171
|
+
payload: {
|
|
172
|
+
context: messageContext,
|
|
173
|
+
thid,
|
|
174
|
+
pthid: msg.thread?.parentThreadId,
|
|
175
|
+
sdp: msg.sdp,
|
|
176
|
+
iceServers: msg.iceServers
|
|
177
|
+
}
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Process incoming ICE candidate message
|
|
182
|
+
*/
|
|
183
|
+
async processIce(messageContext) {
|
|
184
|
+
const thid = messageContext.message.threadId;
|
|
185
|
+
this.events.emit(messageContext.agentContext, {
|
|
186
|
+
type: WebRTCEvents.IncomingIce,
|
|
187
|
+
payload: {
|
|
188
|
+
context: messageContext,
|
|
189
|
+
thid,
|
|
190
|
+
pthid: messageContext.message.thread?.parentThreadId,
|
|
191
|
+
candidate: messageContext.message.candidate ?? {},
|
|
192
|
+
endOfCandidates: messageContext.message.endOfCandidates
|
|
193
|
+
}
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Process incoming renegotiate message
|
|
198
|
+
*/
|
|
199
|
+
async processRenegotiate(messageContext) {
|
|
200
|
+
const thid = messageContext.message.threadId;
|
|
201
|
+
const msg = messageContext.message;
|
|
202
|
+
this.events.emit(messageContext.agentContext, {
|
|
203
|
+
type: WebRTCEvents.RenegotiateRequested,
|
|
204
|
+
payload: {
|
|
205
|
+
context: messageContext,
|
|
206
|
+
thid,
|
|
207
|
+
pthid: msg.thread?.parentThreadId,
|
|
208
|
+
reason: msg.reason,
|
|
209
|
+
iceRestart: msg.iceRestart,
|
|
210
|
+
iceServers: msg.iceServers,
|
|
211
|
+
policy: msg.policy
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Process incoming end call message
|
|
217
|
+
*/
|
|
218
|
+
async processEnd(messageContext) {
|
|
219
|
+
const connection = messageContext.assertReadyConnection();
|
|
220
|
+
const thid = messageContext.message.threadId;
|
|
221
|
+
const [record] = await this.repo.findByQuery(messageContext.agentContext, {
|
|
222
|
+
connectionId: connection.id,
|
|
223
|
+
threadId: thid
|
|
224
|
+
});
|
|
225
|
+
if (record) {
|
|
226
|
+
record.state = "ended";
|
|
227
|
+
await this.repo.update(messageContext.agentContext, record);
|
|
228
|
+
}
|
|
229
|
+
this.events.emit(messageContext.agentContext, {
|
|
230
|
+
type: WebRTCEvents.CallEnded,
|
|
231
|
+
payload: {
|
|
232
|
+
context: messageContext,
|
|
233
|
+
thid,
|
|
234
|
+
pthid: messageContext.message.thread?.parentThreadId,
|
|
235
|
+
reason: messageContext.message.reason
|
|
236
|
+
}
|
|
237
|
+
});
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
WebRTCService = __decorate([injectable(), __decorateMetadata("design:paramtypes", [typeof (_ref = typeof WebRTCCallRepository !== "undefined" && WebRTCCallRepository) === "function" ? _ref : Object, typeof (_ref2 = typeof EventEmitter !== "undefined" && EventEmitter) === "function" ? _ref2 : Object])], WebRTCService);
|
|
241
|
+
|
|
242
|
+
//#endregion
|
|
243
|
+
export { WebRTCService };
|
|
244
|
+
//# sourceMappingURL=WebRTCService.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"WebRTCService.mjs","names":["WebRTCService","repo: WebRTCCallRepository","events: EventEmitter"],"sources":["../../../src/webrtc/services/WebRTCService.ts"],"sourcesContent":["import type { AgentContext } from '@credo-ts/core'\nimport type { DidCommInboundMessageContext, DidCommOutboundMessageContext } from '@credo-ts/didcomm'\nimport type { DidCommConnectionRecord } from '@credo-ts/didcomm'\n\nimport { injectable } from 'tsyringe'\nimport { EventEmitter } from '@credo-ts/core'\n\nimport { AnswerMessage, EndMessage, IceMessage, OfferMessage, ProposeMessage, RenegotiateMessage } from '../messages'\nimport type { IcePolicy, IceServerConfig } from '../messages/OfferMessage'\nimport type { MediaType } from '../messages/ProposeMessage'\nimport type { RenegotiateReason } from '../messages/RenegotiateMessage'\nimport { WebRTCEvents } from '../WebRTCEvents'\nimport { WebRTCCallRecord } from '../repository/WebRTCCallRecord'\nimport { WebRTCCallRepository } from '../repository/WebRTCCallRepository'\n\n@injectable()\nexport class WebRTCService {\n public constructor(private repo: WebRTCCallRepository, private events: EventEmitter) {}\n\n // Outbound creators\n\n /**\n * Create a propose message to initiate a call\n */\n public createPropose(options: {\n threadId?: string\n parentThreadId?: string\n media?: MediaType[]\n data?: boolean\n topology?: 'mesh' | 'sfu'\n trickle?: boolean\n policy?: IcePolicy\n iceServers?: IceServerConfig[]\n reason?: string\n }) {\n const message = new ProposeMessage({\n threadId: options.threadId,\n parentThreadId: options.parentThreadId,\n media: options.media,\n data: options.data,\n topology: options.topology,\n trickle: options.trickle,\n policy: options.policy,\n iceServers: options.iceServers,\n reason: options.reason,\n })\n return { message }\n }\n\n /**\n * Create an offer message with SDP\n */\n public createOffer(\n agentContext: AgentContext,\n connection: DidCommConnectionRecord,\n threadId: string,\n parentThreadId: string | undefined,\n sdp: string,\n iceServers?: IceServerConfig[],\n policy?: IcePolicy,\n trickle?: boolean\n ) {\n const message = new OfferMessage({ threadId, parentThreadId, sdp, iceServers, policy, trickle })\n const record = new WebRTCCallRecord({ connectionId: connection.id, threadId, state: 'offered', role: 'caller' })\n return { message, record }\n }\n\n /**\n * Create an answer message with SDP\n */\n public createAnswer(\n agentContext: AgentContext,\n connection: DidCommConnectionRecord,\n threadId: string,\n parentThreadId: string | undefined,\n sdp: string,\n iceServers?: IceServerConfig[]\n ) {\n const message = new AnswerMessage({ threadId, parentThreadId, sdp, iceServers })\n return { message }\n }\n\n /**\n * Create an ICE candidate message\n */\n public createIce(\n threadId: string,\n parentThreadId: string | undefined,\n candidate: Record<string, unknown> | undefined,\n endOfCandidates?: boolean\n ) {\n return new IceMessage({ threadId, parentThreadId, candidate, endOfCandidates })\n }\n\n /**\n * Create a renegotiate message (for ICE restart, track changes, etc.)\n */\n public createRenegotiate(options: {\n threadId: string\n parentThreadId?: string\n reason: RenegotiateReason | string\n iceRestart?: boolean\n iceServers?: IceServerConfig[]\n policy?: IcePolicy\n }) {\n return new RenegotiateMessage({\n threadId: options.threadId,\n parentThreadId: options.parentThreadId,\n reason: options.reason,\n iceRestart: options.iceRestart,\n iceServers: options.iceServers,\n policy: options.policy,\n })\n }\n\n /**\n * Create an end call message\n */\n public createEnd(threadId: string, parentThreadId: string | undefined, reason?: string) {\n return new EndMessage({ threadId, parentThreadId, reason })\n }\n\n // Inbound processors\n\n /**\n * Process incoming propose message\n */\n public async processPropose(messageContext: DidCommInboundMessageContext<ProposeMessage>): Promise<void> {\n const thid = messageContext.message.threadId ?? messageContext.message.id\n const msg = messageContext.message\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingPropose,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n media: msg.media,\n data: msg.data,\n topology: msg.topology,\n trickle: msg.trickle,\n policy: msg.policy,\n iceServers: msg.iceServers,\n reason: msg.reason,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming offer message\n */\n public async processOffer(messageContext: DidCommInboundMessageContext<OfferMessage>): Promise<void> {\n const connection = messageContext.assertReadyConnection()\n const thid = messageContext.message.threadId\n const msg = messageContext.message\n\n const record = new WebRTCCallRecord({\n connectionId: connection.id,\n threadId: thid,\n state: 'offered',\n role: 'callee',\n })\n await this.repo.save(messageContext.agentContext, record)\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingOffer,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n sdp: msg.sdp,\n iceServers: msg.iceServers,\n policy: msg.policy,\n trickle: msg.trickle,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming answer message\n */\n public async processAnswer(messageContext: DidCommInboundMessageContext<AnswerMessage>): Promise<void> {\n const connection = messageContext.assertReadyConnection()\n const thid = messageContext.message.threadId\n const msg = messageContext.message\n\n const [record] = await this.repo.findByQuery(messageContext.agentContext, {\n connectionId: connection.id,\n threadId: thid,\n })\n if (record) {\n record.state = 'answered'\n await this.repo.update(messageContext.agentContext, record)\n }\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingAnswer,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n sdp: msg.sdp,\n iceServers: msg.iceServers,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming ICE candidate message\n */\n public async processIce(messageContext: DidCommInboundMessageContext<IceMessage>): Promise<void> {\n const thid = messageContext.message.threadId\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.IncomingIce,\n payload: {\n context: messageContext,\n thid,\n pthid: messageContext.message.thread?.parentThreadId,\n candidate: messageContext.message.candidate ?? {},\n endOfCandidates: messageContext.message.endOfCandidates,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming renegotiate message\n */\n public async processRenegotiate(messageContext: DidCommInboundMessageContext<RenegotiateMessage>): Promise<void> {\n const thid = messageContext.message.threadId\n const msg = messageContext.message\n\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.RenegotiateRequested,\n payload: {\n context: messageContext,\n thid,\n pthid: msg.thread?.parentThreadId,\n reason: msg.reason,\n iceRestart: msg.iceRestart,\n iceServers: msg.iceServers,\n policy: msg.policy,\n },\n } as any)\n return\n }\n\n /**\n * Process incoming end call message\n */\n public async processEnd(messageContext: DidCommInboundMessageContext<EndMessage>): Promise<void> {\n const connection = messageContext.assertReadyConnection()\n const thid = messageContext.message.threadId\n const [record] = await this.repo.findByQuery(messageContext.agentContext, {\n connectionId: connection.id,\n threadId: thid,\n })\n if (record) {\n record.state = 'ended'\n await this.repo.update(messageContext.agentContext, record)\n }\n this.events.emit(messageContext.agentContext, {\n type: WebRTCEvents.CallEnded,\n payload: {\n context: messageContext,\n thid,\n pthid: messageContext.message.thread?.parentThreadId,\n reason: messageContext.message.reason,\n },\n } as any)\n return\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,28 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ajna-inc/webrtc",
|
|
3
|
-
"
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
3
|
+
"exports": {
|
|
4
|
+
".": "./build/index.mjs",
|
|
5
|
+
"./package.json": "./package.json"
|
|
6
|
+
},
|
|
7
|
+
"version": "0.6.1",
|
|
7
8
|
"files": [
|
|
8
|
-
"build"
|
|
9
|
+
"build",
|
|
10
|
+
".npmvc"
|
|
9
11
|
],
|
|
12
|
+
"license": "Apache-2.0",
|
|
10
13
|
"publishConfig": {
|
|
11
14
|
"access": "public"
|
|
12
15
|
},
|
|
13
16
|
"dependencies": {
|
|
14
|
-
"class-transformer": "
|
|
15
|
-
"class-validator": "^0.14.
|
|
16
|
-
"
|
|
17
|
-
|
|
18
|
-
"peerDependencies": {
|
|
19
|
-
"@credo-ts/core": "^0.5.17"
|
|
17
|
+
"class-transformer": "0.5.1",
|
|
18
|
+
"class-validator": "^0.14.1",
|
|
19
|
+
"@credo-ts/core": "0.6.1",
|
|
20
|
+
"@credo-ts/didcomm": "0.6.1"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
|
-
"
|
|
23
|
+
"reflect-metadata": "0.2.2",
|
|
24
|
+
"typescript": "~5.9.3"
|
|
23
25
|
},
|
|
26
|
+
"publisher": "did:key:z6MktNpDRgzA26pH13MxEPU4nmB6BwxxgCajhGHERPCrPGpD",
|
|
24
27
|
"scripts": {
|
|
25
|
-
"build": "
|
|
26
|
-
|
|
27
|
-
|
|
28
|
+
"build": "tsdown --config-loader unconfig"
|
|
29
|
+
},
|
|
30
|
+
"types": "./build/index.d.mts",
|
|
31
|
+
"module": "./build/index.mjs"
|
|
28
32
|
}
|
package/README.md
DELETED
|
@@ -1,222 +0,0 @@
|
|
|
1
|
-
# @ajna-inc/webrtc
|
|
2
|
-
|
|
3
|
-
DIDComm v2 signaling protocol for WebRTC P2P calls with full NAT/firewall traversal support.
|
|
4
|
-
|
|
5
|
-
- PIURI: `https://didcomm.org/webrtc/1.0`
|
|
6
|
-
- Messages: `propose`, `offer`, `answer`, `ice`, `renegotiate`, `end`
|
|
7
|
-
- Advertises support via Discover Features; works with mediators and message pickup.
|
|
8
|
-
|
|
9
|
-
## Features
|
|
10
|
-
|
|
11
|
-
- **Module-level ICE server defaults** - Configure STUN/TURN servers once
|
|
12
|
-
- **ICE policy control** - `all`, `relay-preferred`, or `relay-only` for strict firewall environments
|
|
13
|
-
- **ICE restart support** - Recover from failed connections
|
|
14
|
-
- **Trickle ICE** - Efficient candidate exchange
|
|
15
|
-
- **Propose message** - Share ICE servers before SDP exchange
|
|
16
|
-
|
|
17
|
-
## Install
|
|
18
|
-
|
|
19
|
-
This package is part of the monorepo. Add the module to your Agent options:
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
import { WebRTCModule } from '@ajna-inc/webrtc'
|
|
23
|
-
|
|
24
|
-
const agent = new Agent({
|
|
25
|
-
config: { /* ... */ },
|
|
26
|
-
dependencies: agentDependencies,
|
|
27
|
-
modules: {
|
|
28
|
-
webrtc: new WebRTCModule({
|
|
29
|
-
// Configure default ICE servers (optional - has sensible defaults)
|
|
30
|
-
iceServers: [
|
|
31
|
-
{ urls: 'stun:stun.l.google.com:19302' },
|
|
32
|
-
{ urls: 'turn:turn.example.org:3478', username: 'user', credential: 'pass' },
|
|
33
|
-
],
|
|
34
|
-
// Default ICE policy: 'all' | 'relay-preferred' | 'relay-only'
|
|
35
|
-
defaultPolicy: 'relay-preferred',
|
|
36
|
-
// Enable trickle ICE by default
|
|
37
|
-
defaultTrickle: true,
|
|
38
|
-
}),
|
|
39
|
-
},
|
|
40
|
-
})
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
## NAT/Firewall Traversal
|
|
44
|
-
|
|
45
|
-
For peers behind restrictive NAT or firewalls, use TURN servers:
|
|
46
|
-
|
|
47
|
-
```ts
|
|
48
|
-
const agent = new Agent({
|
|
49
|
-
modules: {
|
|
50
|
-
webrtc: new WebRTCModule({
|
|
51
|
-
iceServers: [
|
|
52
|
-
// STUN for simple NAT
|
|
53
|
-
{ urls: 'stun:stun.l.google.com:19302' },
|
|
54
|
-
// TURN for symmetric NAT and firewalls
|
|
55
|
-
{ urls: 'turn:turn.yourserver.com:3478', username: 'user', credential: 'pass' },
|
|
56
|
-
// TURNS (TLS) for stricter firewalls
|
|
57
|
-
{ urls: 'turns:turn.yourserver.com:5349', username: 'user', credential: 'pass' },
|
|
58
|
-
],
|
|
59
|
-
// Force relay-only for maximum compatibility (hides IP addresses too)
|
|
60
|
-
defaultPolicy: 'relay-only',
|
|
61
|
-
}),
|
|
62
|
-
},
|
|
63
|
-
})
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Frontend usage (browser)
|
|
67
|
-
|
|
68
|
-
Below is a setup for P2P WebRTC using Credo TS for signaling.
|
|
69
|
-
|
|
70
|
-
```ts
|
|
71
|
-
// Get configured ICE servers from module
|
|
72
|
-
const iceServers = agent.modules.webrtc.getDefaultIceServers()
|
|
73
|
-
|
|
74
|
-
// Subscribe to inbound signaling
|
|
75
|
-
agent.events.on('WebRTCEvents.IncomingPropose', async ({ payload }) => {
|
|
76
|
-
const { thid, iceServers, policy, media } = payload
|
|
77
|
-
// Caller is proposing a call - you can accept by sending an offer
|
|
78
|
-
// The iceServers from propose can be used to configure RTCPeerConnection
|
|
79
|
-
console.log('Incoming call proposal:', { media, iceServers })
|
|
80
|
-
})
|
|
81
|
-
|
|
82
|
-
agent.events.on('WebRTCEvents.IncomingOffer', async ({ payload }) => {
|
|
83
|
-
const { thid, sdp, iceServers, policy, context } = payload
|
|
84
|
-
|
|
85
|
-
// Use ICE servers from offer (or fall back to module defaults)
|
|
86
|
-
const pc = new RTCPeerConnection({
|
|
87
|
-
iceServers: iceServers ?? agent.modules.webrtc.getDefaultIceServers(),
|
|
88
|
-
iceTransportPolicy: policy === 'relay-only' ? 'relay' : 'all',
|
|
89
|
-
})
|
|
90
|
-
peers.set(thid, pc)
|
|
91
|
-
|
|
92
|
-
await pc.setRemoteDescription({ type: 'offer', sdp })
|
|
93
|
-
const answer = await pc.createAnswer()
|
|
94
|
-
await pc.setLocalDescription(answer)
|
|
95
|
-
|
|
96
|
-
await agent.modules.webrtc.acceptCall({
|
|
97
|
-
connectionId: context.connection!.id,
|
|
98
|
-
threadId: thid,
|
|
99
|
-
sdp: answer.sdp!,
|
|
100
|
-
})
|
|
101
|
-
})
|
|
102
|
-
|
|
103
|
-
agent.events.on('WebRTCEvents.IncomingAnswer', async ({ payload }) => {
|
|
104
|
-
const { thid, sdp, iceServers } = payload
|
|
105
|
-
const pc = peers.get(thid)
|
|
106
|
-
if (!pc) return
|
|
107
|
-
|
|
108
|
-
// If callee provided additional ICE servers, you might want to restart ICE
|
|
109
|
-
await pc.setRemoteDescription({ type: 'answer', sdp })
|
|
110
|
-
})
|
|
111
|
-
|
|
112
|
-
agent.events.on('WebRTCEvents.IncomingIce', async ({ payload }) => {
|
|
113
|
-
const { thid, candidate, endOfCandidates } = payload
|
|
114
|
-
const pc = peers.get(thid)
|
|
115
|
-
if (!pc) return
|
|
116
|
-
if (endOfCandidates) await pc.addIceCandidate(null)
|
|
117
|
-
else await pc.addIceCandidate(candidate as RTCIceCandidateInit)
|
|
118
|
-
})
|
|
119
|
-
|
|
120
|
-
// Handle renegotiation requests (e.g., ICE restart)
|
|
121
|
-
agent.events.on('WebRTCEvents.RenegotiateRequested', async ({ payload }) => {
|
|
122
|
-
const { thid, iceRestart, iceServers, reason } = payload
|
|
123
|
-
const pc = peers.get(thid)
|
|
124
|
-
if (!pc) return
|
|
125
|
-
|
|
126
|
-
if (iceRestart) {
|
|
127
|
-
// Perform ICE restart
|
|
128
|
-
const offer = await pc.createOffer({ iceRestart: true })
|
|
129
|
-
await pc.setLocalDescription(offer)
|
|
130
|
-
// Send new offer...
|
|
131
|
-
}
|
|
132
|
-
})
|
|
133
|
-
|
|
134
|
-
// Start call (caller)
|
|
135
|
-
async function startCall(connectionId: string, localStream: MediaStream) {
|
|
136
|
-
const thid = crypto.randomUUID()
|
|
137
|
-
|
|
138
|
-
// Use module's default ICE servers
|
|
139
|
-
const iceServers = agent.modules.webrtc.getDefaultIceServers()
|
|
140
|
-
|
|
141
|
-
const pc = new RTCPeerConnection({ iceServers })
|
|
142
|
-
peers.set(thid, pc)
|
|
143
|
-
|
|
144
|
-
// Handle ICE connection failures
|
|
145
|
-
pc.oniceconnectionstatechange = () => {
|
|
146
|
-
if (pc.iceConnectionState === 'failed') {
|
|
147
|
-
// Request ICE restart
|
|
148
|
-
agent.modules.webrtc.restartIce({ connectionId, threadId: thid })
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
// Render remote stream
|
|
153
|
-
pc.ontrack = e => (remoteVideo.srcObject = e.streams[0])
|
|
154
|
-
|
|
155
|
-
// Send ICE via DIDComm
|
|
156
|
-
pc.onicecandidate = e => agent.modules.webrtc.sendIce({
|
|
157
|
-
connectionId,
|
|
158
|
-
threadId: thid,
|
|
159
|
-
candidate: e.candidate ?? undefined,
|
|
160
|
-
endOfCandidates: e.candidate == null,
|
|
161
|
-
})
|
|
162
|
-
|
|
163
|
-
// Add local tracks
|
|
164
|
-
for (const track of localStream.getTracks()) pc.addTrack(track, localStream)
|
|
165
|
-
|
|
166
|
-
const offer = await pc.createOffer({ offerToReceiveVideo: true, offerToReceiveAudio: true })
|
|
167
|
-
await pc.setLocalDescription(offer)
|
|
168
|
-
|
|
169
|
-
// Start call - ICE servers are automatically included from module config
|
|
170
|
-
await agent.modules.webrtc.startCall({
|
|
171
|
-
connectionId,
|
|
172
|
-
threadId: thid,
|
|
173
|
-
sdp: offer.sdp!,
|
|
174
|
-
// Optionally override policy for this specific call
|
|
175
|
-
policy: 'relay-preferred',
|
|
176
|
-
})
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
// Request ICE restart when connection fails
|
|
180
|
-
async function handleConnectionFailure(connectionId: string, thid: string) {
|
|
181
|
-
await agent.modules.webrtc.restartIce({
|
|
182
|
-
connectionId,
|
|
183
|
-
threadId: thid,
|
|
184
|
-
// Optionally provide new ICE servers
|
|
185
|
-
iceServers: [{ urls: 'turn:backup-turn.example.org:3478', username: 'u', credential: 'p' }],
|
|
186
|
-
})
|
|
187
|
-
}
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
## API Reference
|
|
191
|
-
|
|
192
|
-
### WebRTCApi Methods
|
|
193
|
-
|
|
194
|
-
| Method | Description |
|
|
195
|
-
|--------|-------------|
|
|
196
|
-
| `proposeCall()` | Send a call proposal with ICE servers before offer |
|
|
197
|
-
| `startCall()` | Send SDP offer with ICE servers |
|
|
198
|
-
| `acceptCall()` | Send SDP answer |
|
|
199
|
-
| `sendIce()` | Send ICE candidate |
|
|
200
|
-
| `renegotiate()` | Request renegotiation (track changes, codec changes) |
|
|
201
|
-
| `restartIce()` | Request ICE restart (connection recovery) |
|
|
202
|
-
| `endCall()` | End the call |
|
|
203
|
-
| `getDefaultIceServers()` | Get configured default ICE servers |
|
|
204
|
-
|
|
205
|
-
### Events
|
|
206
|
-
|
|
207
|
-
| Event | Description |
|
|
208
|
-
|-------|-------------|
|
|
209
|
-
| `IncomingPropose` | Call proposal received (includes ICE servers) |
|
|
210
|
-
| `IncomingOffer` | SDP offer received |
|
|
211
|
-
| `IncomingAnswer` | SDP answer received |
|
|
212
|
-
| `IncomingIce` | ICE candidate received |
|
|
213
|
-
| `RenegotiateRequested` | Renegotiation requested (e.g., ICE restart) |
|
|
214
|
-
| `CallEnded` | Call ended |
|
|
215
|
-
|
|
216
|
-
## Notes
|
|
217
|
-
|
|
218
|
-
- This module moves only signaling over DIDComm; media flows via WebRTC/DTLS-SRTP.
|
|
219
|
-
- For NAT traversal, configure TURN servers in the module config or per-call.
|
|
220
|
-
- Use `relay-only` policy for maximum firewall compatibility (also hides IP addresses).
|
|
221
|
-
- Works with mediators and message pickup (offline delivery), as with any DIDComm message.
|
|
222
|
-
|
package/build/index.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
export { WebRTCModule, WebRTCModuleConfigToken } from './webrtc/WebRTCModule';
|
|
2
|
-
export type { WebRTCModuleConfig, WebRTCIceServerConfig } from './webrtc/WebRTCModule';
|
|
3
|
-
export { WebRTCApi } from './webrtc/WebRTCApi';
|
|
4
|
-
export { WebRTCEvents, type IceServerEventConfig, type IncomingProposeEvent, type IncomingOfferEvent, type IncomingAnswerEvent, type IncomingIceEvent, type RenegotiateRequestedEvent, type CallEndedEvent, } from './webrtc/WebRTCEvents';
|
|
5
|
-
export * from './webrtc/messages';
|
|
6
|
-
export type { IcePolicy, IceServerConfig } from './webrtc/messages/OfferMessage';
|
|
7
|
-
export type { MediaType } from './webrtc/messages/ProposeMessage';
|
|
8
|
-
export type { RenegotiateReason } from './webrtc/messages/RenegotiateMessage';
|
package/build/index.js
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
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
|
-
exports.WebRTCEvents = exports.WebRTCApi = exports.WebRTCModuleConfigToken = exports.WebRTCModule = void 0;
|
|
18
|
-
// Module and API
|
|
19
|
-
var WebRTCModule_1 = require("./webrtc/WebRTCModule");
|
|
20
|
-
Object.defineProperty(exports, "WebRTCModule", { enumerable: true, get: function () { return WebRTCModule_1.WebRTCModule; } });
|
|
21
|
-
Object.defineProperty(exports, "WebRTCModuleConfigToken", { enumerable: true, get: function () { return WebRTCModule_1.WebRTCModuleConfigToken; } });
|
|
22
|
-
var WebRTCApi_1 = require("./webrtc/WebRTCApi");
|
|
23
|
-
Object.defineProperty(exports, "WebRTCApi", { enumerable: true, get: function () { return WebRTCApi_1.WebRTCApi; } });
|
|
24
|
-
// Events
|
|
25
|
-
var WebRTCEvents_1 = require("./webrtc/WebRTCEvents");
|
|
26
|
-
Object.defineProperty(exports, "WebRTCEvents", { enumerable: true, get: function () { return WebRTCEvents_1.WebRTCEvents; } });
|
|
27
|
-
// Messages
|
|
28
|
-
__exportStar(require("./webrtc/messages"), exports);
|
|
29
|
-
//# sourceMappingURL=index.js.map
|
package/build/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iBAAiB;AACjB,sDAA6E;AAApE,4GAAA,YAAY,OAAA;AAAE,uHAAA,uBAAuB,OAAA;AAE9C,gDAA8C;AAArC,sGAAA,SAAS,OAAA;AAElB,SAAS;AACT,sDAS8B;AAR5B,4GAAA,YAAY,OAAA;AAUd,WAAW;AACX,oDAAiC"}
|