vantmetry 0.0.2 → 0.0.4
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/core/tracker.d.ts +1 -0
- package/core/transport.d.ts +3 -0
- package/core/types.d.ts +1 -0
- package/index.js +8 -5
- package/{init-DeOqWgSl.js → init-BfWOgJup.js} +104 -83
- package/next/index.js +1 -1
- package/package.json +1 -1
- package/react/index.js +1 -1
- package/src/core/listeners.ts +17 -6
- package/src/core/tracker.ts +16 -1
- package/src/core/transport.ts +18 -2
- package/src/core/types.ts +1 -0
- package/src/index.ts +3 -0
package/core/tracker.d.ts
CHANGED
|
@@ -15,6 +15,7 @@ export declare class VantmetryTracker implements VantmetryInstance {
|
|
|
15
15
|
info(message: string, details?: LogDetails): void;
|
|
16
16
|
debug(message: string, details?: LogDetails): void;
|
|
17
17
|
flush(): Promise<void>;
|
|
18
|
+
destroy(): Promise<void>;
|
|
18
19
|
private addToBuffer;
|
|
19
20
|
captureAutoError(payload: LogPayload): void;
|
|
20
21
|
private getSignature;
|
package/core/transport.d.ts
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { VantmetryConfig } from './types';
|
|
2
2
|
export declare class TransportManager {
|
|
3
3
|
private wtSession;
|
|
4
|
+
private wtInitPromise;
|
|
4
5
|
private readonly endpoint;
|
|
5
6
|
private readonly wtEndpoint;
|
|
6
7
|
private readonly debug;
|
|
7
8
|
constructor(config: VantmetryConfig);
|
|
8
9
|
private initWT;
|
|
10
|
+
private connectWT;
|
|
9
11
|
send(payload: string): Promise<void>;
|
|
12
|
+
close(): void;
|
|
10
13
|
}
|
package/core/types.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export interface VantmetryInstance {
|
|
|
13
13
|
info: (message: string, details?: LogDetails) => void;
|
|
14
14
|
debug: (message: string, details?: LogDetails) => void;
|
|
15
15
|
flush: () => Promise<void>;
|
|
16
|
+
destroy: () => Promise<void>;
|
|
16
17
|
}
|
|
17
18
|
declare global {
|
|
18
19
|
interface Window {
|
package/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { g as t } from "./init-
|
|
2
|
-
import { V as i, i as g, a as
|
|
3
|
-
const
|
|
1
|
+
import { g as t } from "./init-BfWOgJup.js";
|
|
2
|
+
import { V as i, i as g, a as u } from "./init-BfWOgJup.js";
|
|
3
|
+
const o = {
|
|
4
4
|
get isReady() {
|
|
5
5
|
return t().isReady;
|
|
6
6
|
},
|
|
@@ -18,11 +18,14 @@ const n = {
|
|
|
18
18
|
},
|
|
19
19
|
flush() {
|
|
20
20
|
return t().flush();
|
|
21
|
+
},
|
|
22
|
+
destroy() {
|
|
23
|
+
return t().destroy();
|
|
21
24
|
}
|
|
22
25
|
};
|
|
23
26
|
export {
|
|
24
27
|
i as VantmetryTracker,
|
|
25
28
|
g as init,
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
u as initGlobalListeners,
|
|
30
|
+
o as logger
|
|
28
31
|
};
|
|
@@ -1,37 +1,40 @@
|
|
|
1
|
-
let
|
|
2
|
-
function T(
|
|
3
|
-
|
|
1
|
+
let f = null;
|
|
2
|
+
function T(i) {
|
|
3
|
+
f = i;
|
|
4
4
|
}
|
|
5
|
-
function
|
|
6
|
-
if (!
|
|
5
|
+
function A() {
|
|
6
|
+
if (!f)
|
|
7
7
|
throw new Error("[Vantmetry] Not initialized. Call init() before using logger.");
|
|
8
|
-
return
|
|
8
|
+
return f;
|
|
9
9
|
}
|
|
10
10
|
function E() {
|
|
11
|
-
return
|
|
11
|
+
return f !== null;
|
|
12
12
|
}
|
|
13
|
-
const
|
|
13
|
+
const c = {
|
|
14
14
|
ERROR: "ERROR",
|
|
15
15
|
INFO: "INFO",
|
|
16
16
|
WARN: "WARN",
|
|
17
17
|
DEBUG: "DEBUG"
|
|
18
|
-
},
|
|
19
|
-
class
|
|
18
|
+
}, S = "https://ingestor.vantmetry.com:4433";
|
|
19
|
+
class b {
|
|
20
20
|
wtSession = null;
|
|
21
|
+
wtInitPromise = null;
|
|
21
22
|
endpoint;
|
|
22
23
|
wtEndpoint;
|
|
23
24
|
debug;
|
|
24
25
|
constructor(e) {
|
|
25
|
-
const t = (e.ingestorUrl ??
|
|
26
|
+
const t = (e.ingestorUrl ?? S).replace(/\/$/, "");
|
|
26
27
|
this.endpoint = `${t}/api/ingestor/push/tcp?public_key=${e.publicKey}`, this.wtEndpoint = `${t}/api/ingestor/push/udp?public_key=${e.publicKey}`;
|
|
27
28
|
try {
|
|
28
29
|
this.debug = typeof window < "u" && !!window.localStorage?.getItem("vantmetry_debug");
|
|
29
30
|
} catch {
|
|
30
31
|
this.debug = !1;
|
|
31
32
|
}
|
|
32
|
-
this.initWT();
|
|
33
33
|
}
|
|
34
|
-
|
|
34
|
+
initWT() {
|
|
35
|
+
return this.wtInitPromise ? this.wtInitPromise : (this.wtInitPromise = this.connectWT(), this.wtInitPromise);
|
|
36
|
+
}
|
|
37
|
+
async connectWT() {
|
|
35
38
|
if ("WebTransport" in window) {
|
|
36
39
|
await new Promise((e) => setTimeout(e, 200));
|
|
37
40
|
try {
|
|
@@ -42,7 +45,7 @@ class S {
|
|
|
42
45
|
}
|
|
43
46
|
}
|
|
44
47
|
async send(e) {
|
|
45
|
-
if (this.wtSession)
|
|
48
|
+
if (await this.initWT(), this.wtSession)
|
|
46
49
|
try {
|
|
47
50
|
const s = (await this.wtSession.createUnidirectionalStream()).getWriter();
|
|
48
51
|
await s.write(new TextEncoder().encode(e)), await s.close();
|
|
@@ -64,8 +67,11 @@ class S {
|
|
|
64
67
|
this.debug && console.error("Vantmetry send failed", t);
|
|
65
68
|
});
|
|
66
69
|
}
|
|
70
|
+
close() {
|
|
71
|
+
this.wtSession && (this.wtSession.close(), this.wtSession = null);
|
|
72
|
+
}
|
|
67
73
|
}
|
|
68
|
-
const
|
|
74
|
+
const u = {
|
|
69
75
|
// Matches standard email formats
|
|
70
76
|
email: /\b[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}\b/g,
|
|
71
77
|
// Matches standard CC groupings: 4-4-4-[3-4] with required separators, or Amex 4-6-5 format.
|
|
@@ -93,36 +99,36 @@ const c = {
|
|
|
93
99
|
"client_secret",
|
|
94
100
|
"auth"
|
|
95
101
|
]);
|
|
96
|
-
function
|
|
97
|
-
let e =
|
|
98
|
-
return e = e.replace(
|
|
102
|
+
function d(i) {
|
|
103
|
+
let e = i;
|
|
104
|
+
return e = e.replace(u.email, (t) => {
|
|
99
105
|
const s = t.split("@");
|
|
100
106
|
if (s.length !== 2)
|
|
101
107
|
return t;
|
|
102
|
-
const [
|
|
103
|
-
return `${
|
|
104
|
-
}), e = e.replace(
|
|
105
|
-
const s = t.replace(/[-\s]/g, ""),
|
|
106
|
-
return "*".repeat(s.length - 4) +
|
|
107
|
-
}), e = e.replace(
|
|
108
|
+
const [n, a] = s;
|
|
109
|
+
return `${n.charAt(0)}***@${a}`;
|
|
110
|
+
}), e = e.replace(u.creditCard, (t) => {
|
|
111
|
+
const s = t.replace(/[-\s]/g, ""), n = s.slice(-4);
|
|
112
|
+
return "*".repeat(s.length - 4) + n;
|
|
113
|
+
}), e = e.replace(u.ssn, (t) => `***-**-${t.slice(-4)}`), e = e.replace(u.jwt, "[JWT REDACTED]"), e = e.replace(u.authHeader, "$1 [TOKEN REDACTED]"), e;
|
|
108
114
|
}
|
|
109
|
-
function h(
|
|
110
|
-
if (typeof
|
|
111
|
-
return
|
|
112
|
-
if (!
|
|
113
|
-
return
|
|
114
|
-
if (e.has(
|
|
115
|
+
function h(i, e = /* @__PURE__ */ new WeakSet()) {
|
|
116
|
+
if (typeof i == "string")
|
|
117
|
+
return d(i);
|
|
118
|
+
if (!i || typeof i != "object")
|
|
119
|
+
return i;
|
|
120
|
+
if (e.has(i))
|
|
115
121
|
return "[Circular]";
|
|
116
|
-
if (e.add(
|
|
117
|
-
return
|
|
122
|
+
if (e.add(i), Array.isArray(i))
|
|
123
|
+
return i.map((s) => h(s, e));
|
|
118
124
|
const t = {};
|
|
119
|
-
for (const [s,
|
|
120
|
-
const
|
|
121
|
-
if (p.has(
|
|
125
|
+
for (const [s, n] of Object.entries(i)) {
|
|
126
|
+
const a = s.toLowerCase();
|
|
127
|
+
if (p.has(a) || Array.from(p).some((r) => a.includes(r))) {
|
|
122
128
|
t[s] = "[REDACTED]";
|
|
123
129
|
continue;
|
|
124
130
|
}
|
|
125
|
-
typeof
|
|
131
|
+
typeof n == "string" ? t[s] = d(n) : typeof n == "object" && n !== null ? t[s] = h(n, e) : t[s] = n;
|
|
126
132
|
}
|
|
127
133
|
return t;
|
|
128
134
|
}
|
|
@@ -139,32 +145,37 @@ class _ {
|
|
|
139
145
|
TTL_MS = 6e4;
|
|
140
146
|
MAX_EVENTS_PER_SEC = 100;
|
|
141
147
|
constructor(e) {
|
|
142
|
-
this.transport = new
|
|
148
|
+
this.transport = new b(e);
|
|
143
149
|
}
|
|
144
150
|
// --- Public API ---
|
|
145
151
|
error(e, t) {
|
|
146
|
-
this.addToBuffer({ severity:
|
|
152
|
+
this.addToBuffer({ severity: c.ERROR, type: "manual", message: e, details: t });
|
|
147
153
|
}
|
|
148
154
|
warn(e, t) {
|
|
149
|
-
this.addToBuffer({ severity:
|
|
155
|
+
this.addToBuffer({ severity: c.WARN, type: "manual", message: e, details: t });
|
|
150
156
|
}
|
|
151
157
|
info(e, t) {
|
|
152
|
-
this.addToBuffer({ severity:
|
|
158
|
+
this.addToBuffer({ severity: c.INFO, type: "manual", message: e, details: t });
|
|
153
159
|
}
|
|
154
160
|
debug(e, t) {
|
|
155
|
-
this.addToBuffer({ severity:
|
|
161
|
+
this.addToBuffer({ severity: c.DEBUG, type: "manual", message: e, details: t });
|
|
156
162
|
}
|
|
157
163
|
async flush() {
|
|
158
|
-
if (this.buffer.length === 0)
|
|
164
|
+
if (this.buffer.length === 0) {
|
|
165
|
+
this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = null);
|
|
159
166
|
return;
|
|
167
|
+
}
|
|
160
168
|
const e = Date.now();
|
|
161
169
|
for (const s of this.buffer)
|
|
162
170
|
this.sentErrors.set(this.getSignature(s), e);
|
|
163
|
-
for (const [s,
|
|
164
|
-
e -
|
|
171
|
+
for (const [s, n] of this.sentErrors.entries())
|
|
172
|
+
e - n >= this.TTL_MS && this.sentErrors.delete(s);
|
|
165
173
|
const t = JSON.stringify(this.buffer);
|
|
166
174
|
this.buffer = [], this.flushTimer && (clearTimeout(this.flushTimer), this.flushTimer = null), await this.transport.send(t);
|
|
167
175
|
}
|
|
176
|
+
async destroy() {
|
|
177
|
+
this.transport.close(), await this.flush();
|
|
178
|
+
}
|
|
168
179
|
// --- Internal Logic ---
|
|
169
180
|
addToBuffer(e) {
|
|
170
181
|
if (!this.isReady)
|
|
@@ -174,20 +185,23 @@ class _ {
|
|
|
174
185
|
this.isReady = !1, console.error("[Vantmetry] Logging disabled to save browser CPU due to infinite loop detection.");
|
|
175
186
|
return;
|
|
176
187
|
}
|
|
177
|
-
const s = this.getSignature(e),
|
|
178
|
-
if (
|
|
188
|
+
const s = this.getSignature(e), n = this.sentErrors.get(s);
|
|
189
|
+
if (n && t - n < this.TTL_MS)
|
|
179
190
|
return;
|
|
180
|
-
const
|
|
181
|
-
if (
|
|
182
|
-
|
|
191
|
+
const a = this.buffer.find((y) => this.getSignature(y) === s);
|
|
192
|
+
if (a) {
|
|
193
|
+
a.count = (a.count || 1) + 1;
|
|
183
194
|
return;
|
|
184
195
|
}
|
|
185
|
-
|
|
196
|
+
let { message: r, stack: o } = e;
|
|
197
|
+
const { details: l } = e;
|
|
198
|
+
r instanceof Error && (o = o ?? r.stack, r = r.message || String(r));
|
|
199
|
+
const g = typeof r == "string" ? d(r) : r, w = typeof l == "object" ? h(l) : l, m = typeof o == "string" ? d(o) : o;
|
|
186
200
|
this.buffer.push({
|
|
187
201
|
...e,
|
|
188
202
|
message: g,
|
|
189
|
-
details:
|
|
190
|
-
stack:
|
|
203
|
+
details: w,
|
|
204
|
+
stack: m,
|
|
191
205
|
count: 1,
|
|
192
206
|
ts: Date.now(),
|
|
193
207
|
url: window.location.href,
|
|
@@ -203,60 +217,67 @@ class _ {
|
|
|
203
217
|
return `${e.type}:${e.severity}:${e.message}`;
|
|
204
218
|
}
|
|
205
219
|
}
|
|
206
|
-
function
|
|
220
|
+
function k(i) {
|
|
207
221
|
const e = console.error;
|
|
208
222
|
console.error = function(...t) {
|
|
209
|
-
if (e.apply(console, t), !
|
|
210
|
-
|
|
223
|
+
if (e.apply(console, t), !i._isCapturingConsoleError) {
|
|
224
|
+
i._isCapturingConsoleError = !0;
|
|
211
225
|
try {
|
|
212
|
-
let s,
|
|
213
|
-
const
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
226
|
+
let s, n;
|
|
227
|
+
const a = t.findIndex((o) => o instanceof Error), r = t[a];
|
|
228
|
+
if (r) {
|
|
229
|
+
const o = t.slice(0, a).filter((l) => typeof l == "string").join(" ");
|
|
230
|
+
s = o ? `${o}: ${r.message || String(r)}` : r.message || String(r), n = r.stack;
|
|
231
|
+
} else
|
|
232
|
+
s = t.map((o) => {
|
|
233
|
+
if (typeof o == "string") return o;
|
|
234
|
+
try {
|
|
235
|
+
return JSON.stringify(o);
|
|
236
|
+
} catch {
|
|
237
|
+
return String(o);
|
|
238
|
+
}
|
|
239
|
+
}).join(" ");
|
|
240
|
+
i.captureAutoError({
|
|
222
241
|
type: "console.error",
|
|
223
242
|
message: s || "Unknown console.error",
|
|
224
|
-
stack:
|
|
225
|
-
severity:
|
|
243
|
+
stack: n,
|
|
244
|
+
severity: c.ERROR
|
|
226
245
|
});
|
|
227
246
|
} finally {
|
|
228
|
-
|
|
247
|
+
i._isCapturingConsoleError = !1;
|
|
229
248
|
}
|
|
230
249
|
}
|
|
231
250
|
}, window.addEventListener("error", function(t) {
|
|
232
|
-
|
|
251
|
+
i.captureAutoError({
|
|
233
252
|
type: "crash",
|
|
234
253
|
message: t.message || "Script error.",
|
|
235
254
|
stack: t.error?.stack,
|
|
236
255
|
loc: `${t.filename}:${t.lineno}:${t.colno}`,
|
|
237
|
-
severity:
|
|
256
|
+
severity: c.ERROR
|
|
238
257
|
});
|
|
239
258
|
}, { capture: !0 }), window.addEventListener("unhandledrejection", function(t) {
|
|
240
|
-
const s = t.reason;
|
|
241
|
-
|
|
259
|
+
const s = t.reason, n = s instanceof Error;
|
|
260
|
+
i.captureAutoError({
|
|
242
261
|
type: "promise",
|
|
243
|
-
message:
|
|
244
|
-
stack:
|
|
245
|
-
severity:
|
|
262
|
+
message: n ? s.message : String(s),
|
|
263
|
+
stack: n ? s.stack : new Error(`Unhandled rejection: ${String(s)}`).stack,
|
|
264
|
+
severity: c.ERROR
|
|
246
265
|
});
|
|
247
|
-
}, { capture: !0 }),
|
|
248
|
-
document.visibilityState === "hidden" &&
|
|
266
|
+
}, { capture: !0 }), window.addEventListener("visibilitychange", function() {
|
|
267
|
+
document.visibilityState === "hidden" && i.flush();
|
|
268
|
+
}), window.addEventListener("pagehide", () => {
|
|
269
|
+
i.destroy();
|
|
249
270
|
});
|
|
250
271
|
}
|
|
251
|
-
function
|
|
272
|
+
function I(i) {
|
|
252
273
|
if (E())
|
|
253
274
|
return;
|
|
254
|
-
const e = new _(
|
|
255
|
-
T(e),
|
|
275
|
+
const e = new _(i);
|
|
276
|
+
T(e), k(e);
|
|
256
277
|
}
|
|
257
278
|
export {
|
|
258
279
|
_ as V,
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
280
|
+
k as a,
|
|
281
|
+
A as g,
|
|
282
|
+
I as i
|
|
262
283
|
};
|
package/next/index.js
CHANGED
package/package.json
CHANGED
package/react/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { jsx as s } from "react/jsx-runtime";
|
|
2
2
|
import { createContext as i, Component as a, useEffect as u, useContext as c } from "react";
|
|
3
3
|
import { logger as o } from "../index.js";
|
|
4
|
-
import { i as m } from "../init-
|
|
4
|
+
import { i as m } from "../init-BfWOgJup.js";
|
|
5
5
|
const n = i(null);
|
|
6
6
|
function h({ publicKey: t, ingestorUrl: r, children: e }) {
|
|
7
7
|
return u(() => {
|
package/src/core/listeners.ts
CHANGED
|
@@ -13,9 +13,14 @@ export function initGlobalListeners(tracker: VantmetryTracker) {
|
|
|
13
13
|
let message: string;
|
|
14
14
|
let stack: string | undefined;
|
|
15
15
|
|
|
16
|
-
const
|
|
16
|
+
const errorIndex = args.findIndex((arg) => arg instanceof Error);
|
|
17
|
+
const errorObj = args[errorIndex] as Error | undefined;
|
|
17
18
|
if (errorObj) {
|
|
18
|
-
|
|
19
|
+
const prefix = args
|
|
20
|
+
.slice(0, errorIndex)
|
|
21
|
+
.filter((a) => typeof a === 'string')
|
|
22
|
+
.join(' ');
|
|
23
|
+
message = prefix ? `${prefix}: ${errorObj.message || String(errorObj)}` : errorObj.message || String(errorObj);
|
|
19
24
|
stack = errorObj.stack;
|
|
20
25
|
} else {
|
|
21
26
|
message = args
|
|
@@ -53,18 +58,24 @@ export function initGlobalListeners(tracker: VantmetryTracker) {
|
|
|
53
58
|
|
|
54
59
|
window.addEventListener('unhandledrejection', function (event: PromiseRejectionEvent) {
|
|
55
60
|
const reason = event.reason;
|
|
61
|
+
const isError = reason instanceof Error;
|
|
56
62
|
tracker.captureAutoError({
|
|
57
63
|
type: 'promise',
|
|
58
|
-
message:
|
|
59
|
-
stack: reason
|
|
64
|
+
message: isError ? reason.message : String(reason),
|
|
65
|
+
stack: isError ? reason.stack : new Error(`Unhandled rejection: ${String(reason)}`).stack,
|
|
60
66
|
severity: LogLevel.ERROR,
|
|
61
67
|
});
|
|
62
68
|
}, { capture: true });
|
|
63
69
|
|
|
64
|
-
// Flush on page unload
|
|
65
|
-
|
|
70
|
+
// Flush on page unload or visibility change
|
|
71
|
+
window.addEventListener('visibilitychange', function () {
|
|
66
72
|
if (document.visibilityState === 'hidden') {
|
|
67
73
|
void tracker.flush();
|
|
68
74
|
}
|
|
69
75
|
});
|
|
76
|
+
|
|
77
|
+
// Enable bfcache restoration by closing transport on navigate away
|
|
78
|
+
window.addEventListener('pagehide', () => {
|
|
79
|
+
void tracker.destroy();
|
|
80
|
+
});
|
|
70
81
|
}
|
package/src/core/tracker.ts
CHANGED
|
@@ -43,6 +43,10 @@ export class VantmetryTracker implements VantmetryInstance {
|
|
|
43
43
|
|
|
44
44
|
public async flush() {
|
|
45
45
|
if (this.buffer.length === 0) {
|
|
46
|
+
if (this.flushTimer) {
|
|
47
|
+
clearTimeout(this.flushTimer);
|
|
48
|
+
this.flushTimer = null;
|
|
49
|
+
}
|
|
46
50
|
return;
|
|
47
51
|
}
|
|
48
52
|
|
|
@@ -69,6 +73,11 @@ export class VantmetryTracker implements VantmetryInstance {
|
|
|
69
73
|
await this.transport.send(dataPayload);
|
|
70
74
|
}
|
|
71
75
|
|
|
76
|
+
public async destroy() {
|
|
77
|
+
this.transport.close();
|
|
78
|
+
await this.flush();
|
|
79
|
+
}
|
|
80
|
+
|
|
72
81
|
// --- Internal Logic ---
|
|
73
82
|
|
|
74
83
|
private addToBuffer(payload: LogPayload) {
|
|
@@ -106,7 +115,13 @@ export class VantmetryTracker implements VantmetryInstance {
|
|
|
106
115
|
return;
|
|
107
116
|
}
|
|
108
117
|
|
|
109
|
-
|
|
118
|
+
let { message, stack } = payload;
|
|
119
|
+
const { details } = payload;
|
|
120
|
+
|
|
121
|
+
if (message instanceof Error) {
|
|
122
|
+
stack = stack ?? message.stack;
|
|
123
|
+
message = message.message || String(message);
|
|
124
|
+
}
|
|
110
125
|
|
|
111
126
|
const maskedMessage = typeof message === 'string' ? maskPII(message) : message;
|
|
112
127
|
const maskedDetails = typeof details === 'object' ? maskObjectPII(details) : details;
|
package/src/core/transport.ts
CHANGED
|
@@ -4,6 +4,7 @@ const DEFAULT_INGESTOR_URL = 'https://ingestor.vantmetry.com:4433';
|
|
|
4
4
|
|
|
5
5
|
export class TransportManager {
|
|
6
6
|
private wtSession: WebTransport | null = null;
|
|
7
|
+
private wtInitPromise: Promise<void> | null = null;
|
|
7
8
|
private readonly endpoint: string;
|
|
8
9
|
private readonly wtEndpoint: string;
|
|
9
10
|
private readonly debug: boolean;
|
|
@@ -18,11 +19,17 @@ export class TransportManager {
|
|
|
18
19
|
} catch {
|
|
19
20
|
this.debug = false;
|
|
20
21
|
}
|
|
22
|
+
}
|
|
21
23
|
|
|
22
|
-
|
|
24
|
+
private initWT(): Promise<void> {
|
|
25
|
+
if (this.wtInitPromise) {
|
|
26
|
+
return this.wtInitPromise;
|
|
27
|
+
}
|
|
28
|
+
this.wtInitPromise = this.connectWT();
|
|
29
|
+
return this.wtInitPromise;
|
|
23
30
|
}
|
|
24
31
|
|
|
25
|
-
private async
|
|
32
|
+
private async connectWT(): Promise<void> {
|
|
26
33
|
if (!('WebTransport' in window)) {
|
|
27
34
|
return;
|
|
28
35
|
}
|
|
@@ -46,6 +53,8 @@ export class TransportManager {
|
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
public async send(payload: string): Promise<void> {
|
|
56
|
+
await this.initWT();
|
|
57
|
+
|
|
49
58
|
if (this.wtSession) {
|
|
50
59
|
try {
|
|
51
60
|
const stream = await this.wtSession.createUnidirectionalStream();
|
|
@@ -79,4 +88,11 @@ export class TransportManager {
|
|
|
79
88
|
}
|
|
80
89
|
});
|
|
81
90
|
}
|
|
91
|
+
|
|
92
|
+
public close() {
|
|
93
|
+
if (this.wtSession) {
|
|
94
|
+
this.wtSession.close();
|
|
95
|
+
this.wtSession = null;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
82
98
|
}
|
package/src/core/types.ts
CHANGED