@discordjs/rpc 0.2.0-dev.1786968995-99af6d8be → 0.2.0-dev.1788538586-ecea9ed57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js ADDED
@@ -0,0 +1,688 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
3
+
4
+ // src/client.ts
5
+ import { randomUUID as randomUUID2 } from "crypto";
6
+ import { AsyncEventEmitter as AsyncEventEmitter2 } from "@vladfrangu/async_event_emitter";
7
+ import { RPCEvents, RPCCommands, Routes, RouteBases } from "discord-api-types/v10";
8
+
9
+ // src/RPCEventError.ts
10
+ var RPCEventError = class extends Error {
11
+ static {
12
+ __name(this, "RPCEventError");
13
+ }
14
+ code;
15
+ data;
16
+ constructor(data) {
17
+ if (typeof data === "string") {
18
+ super(data);
19
+ } else {
20
+ super(data.message);
21
+ this.code = data.code;
22
+ this.data = data;
23
+ }
24
+ this.name = "RPCEventError";
25
+ }
26
+ };
27
+
28
+ // src/constants.ts
29
+ var Events = /* @__PURE__ */ ((Events2) => {
30
+ Events2["ApplicationReady"] = "APPLICATION_READY";
31
+ Events2["Disconnected"] = "DISCONNECTED";
32
+ return Events2;
33
+ })(Events || {});
34
+
35
+ // src/ipc.ts
36
+ import { Buffer as Buffer2 } from "buffer";
37
+ import { randomUUID } from "crypto";
38
+ import fs from "fs/promises";
39
+ import { createConnection, Socket } from "net";
40
+ import path from "path";
41
+ import process2 from "process";
42
+ import { AsyncEventEmitter } from "@vladfrangu/async_event_emitter";
43
+ async function canOpenFile(path2) {
44
+ try {
45
+ await fs.access(path2);
46
+ return true;
47
+ } catch {
48
+ return false;
49
+ }
50
+ }
51
+ __name(canOpenFile, "canOpenFile");
52
+ async function getIPCPath(id) {
53
+ if (process2.platform === "win32") {
54
+ return String.raw`\\?\pipe\discord-ipc-${id}`;
55
+ }
56
+ const prefix = process2.env.XDG_RUNTIME_DIR ?? process2.env.TMPDIR ?? "/tmp";
57
+ const bases = [prefix, path.join(prefix, "app", "com.discordapp.Discord"), path.join(prefix, "snap.discord")];
58
+ for (const base of bases) {
59
+ const candidate = path.join(base, `discord-ipc-${id}`);
60
+ if (await canOpenFile(candidate)) return candidate;
61
+ }
62
+ return path.join(prefix, `discord-ipc-${id}`);
63
+ }
64
+ __name(getIPCPath, "getIPCPath");
65
+ async function getIPC(id) {
66
+ const { promise, resolve, reject } = Promise.withResolvers();
67
+ const path2 = await getIPCPath(id);
68
+ const onError = /* @__PURE__ */ __name(async () => reject(new Error("Could not connect")), "onError");
69
+ const socket = createConnection(path2, () => {
70
+ socket.removeListener("error", onError);
71
+ resolve(socket);
72
+ });
73
+ socket.once("error", onError);
74
+ return promise;
75
+ }
76
+ __name(getIPC, "getIPC");
77
+ function encode(op, data) {
78
+ const stringifiedData = JSON.stringify(data);
79
+ const length = Buffer2.byteLength(stringifiedData);
80
+ const packet = Buffer2.allocUnsafe(8 + length);
81
+ packet.writeInt32LE(op, 0);
82
+ packet.writeInt32LE(length, 4);
83
+ packet.write(stringifiedData, 8, length);
84
+ return packet;
85
+ }
86
+ __name(encode, "encode");
87
+ var IPCTransport = class extends AsyncEventEmitter {
88
+ constructor(client) {
89
+ super();
90
+ this.client = client;
91
+ this.socket = new Socket();
92
+ this.working = {
93
+ op: 0,
94
+ len: 0,
95
+ buffer: Buffer2.from([])
96
+ };
97
+ }
98
+ client;
99
+ static {
100
+ __name(this, "IPCTransport");
101
+ }
102
+ socket;
103
+ working;
104
+ async connect() {
105
+ for (let id = 0; id < 10; id++) {
106
+ try {
107
+ this.socket = await getIPC(id);
108
+ break;
109
+ } catch (error) {
110
+ if (id === 9) throw error;
111
+ }
112
+ }
113
+ this.socket.on("close", this.onClose.bind(this));
114
+ this.socket.on("error", this.onError.bind(this));
115
+ this.emit("open");
116
+ this.socket.write(
117
+ encode(0 /* Handshake */, {
118
+ v: 1,
119
+ client_id: this.client.clientId
120
+ })
121
+ );
122
+ this.socket.pause();
123
+ this.socket.on("readable", this.decode.bind(this));
124
+ }
125
+ async decode() {
126
+ let packet;
127
+ const chunks = [];
128
+ while ((packet = this.socket.read()) !== null) {
129
+ chunks.push(packet);
130
+ }
131
+ if (chunks.length === 0) return;
132
+ const packets = Buffer2.concat([this.working.buffer, ...chunks]);
133
+ if (this.working.buffer.byteLength === 0) {
134
+ this.working.op = packets.readInt32LE(0);
135
+ this.working.len = packets.readInt32LE(4);
136
+ }
137
+ this.working.buffer = packets;
138
+ const { op, len } = this.working;
139
+ let data;
140
+ try {
141
+ data = JSON.parse(packets.subarray(8, len + 8).toString());
142
+ } catch {
143
+ return;
144
+ }
145
+ this.working.buffer = Buffer2.from([]);
146
+ switch (op) {
147
+ case 3 /* Ping */:
148
+ this.send(data, 4 /* Pong */);
149
+ break;
150
+ case 1 /* Frame */:
151
+ if (!data) {
152
+ return;
153
+ }
154
+ this.emit("message", data);
155
+ break;
156
+ case 2 /* Close */:
157
+ this.emit("close", data);
158
+ break;
159
+ default:
160
+ break;
161
+ }
162
+ }
163
+ onClose(data) {
164
+ this.socket.removeAllListeners();
165
+ this.socket = new Socket();
166
+ this.working.buffer = Buffer2.from([]);
167
+ const error = typeof data === "boolean" ? new Error("socket closed") : data;
168
+ this.emit("close", error);
169
+ }
170
+ onError(error) {
171
+ this.emit("error", error);
172
+ }
173
+ send(data, op = 1 /* Frame */) {
174
+ this.socket.write(encode(op, data));
175
+ }
176
+ async close(options) {
177
+ const { promise, resolve, reject } = Promise.withResolvers();
178
+ const signal = options?.signal ?? AbortSignal.timeout(1e4);
179
+ const onAbort = /* @__PURE__ */ __name((_) => reject(signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason))), "onAbort");
180
+ this.once("close", (error) => {
181
+ signal.removeEventListener("abort", onAbort);
182
+ resolve(error);
183
+ });
184
+ signal.addEventListener("abort", onAbort);
185
+ this.send({}, 2 /* Close */);
186
+ this.socket.end();
187
+ return promise;
188
+ }
189
+ /**
190
+ * Manual ping method
191
+ */
192
+ ping() {
193
+ this.send(randomUUID(), 3 /* Ping */);
194
+ }
195
+ };
196
+
197
+ // src/util.ts
198
+ import { createRequire } from "module";
199
+ var register = /* @__PURE__ */ __name(async () => {
200
+ const require2 = createRequire(import.meta.url);
201
+ try {
202
+ const { app } = require2("electron");
203
+ return app.setAsDefaultProtocolClient.bind(app);
204
+ } catch {
205
+ try {
206
+ return require2("register-scheme");
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+ }, "register");
212
+ function getPid() {
213
+ if (typeof globalThis.process !== "undefined") {
214
+ return process.pid;
215
+ }
216
+ return null;
217
+ }
218
+ __name(getPid, "getPid");
219
+ function isValidTimestamp(timestamp) {
220
+ return Number.isInteger(timestamp) && timestamp >= 0 && timestamp <= 2147483647e3;
221
+ }
222
+ __name(isValidTimestamp, "isValidTimestamp");
223
+
224
+ // src/client.ts
225
+ var RPCClient = class extends AsyncEventEmitter2 {
226
+ static {
227
+ __name(this, "RPCClient");
228
+ }
229
+ options;
230
+ accessToken;
231
+ clientId;
232
+ clientSecret;
233
+ readyTimestamp;
234
+ application;
235
+ user;
236
+ /**
237
+ * The transport for the IPC
238
+ */
239
+ transport;
240
+ /**
241
+ * Map of nonces being expected from the transport
242
+ */
243
+ #expectedNonces;
244
+ constructor(options = {}) {
245
+ super();
246
+ this.options = options;
247
+ this.accessToken = "";
248
+ this.clientId = "";
249
+ this.clientSecret = "";
250
+ this.readyTimestamp = null;
251
+ this.application = null;
252
+ this.user = null;
253
+ this.transport = new IPCTransport(this);
254
+ this.transport.on("message", this.#onRpcMessage.bind(this));
255
+ this.#expectedNonces = /* @__PURE__ */ new Map();
256
+ }
257
+ /**
258
+ * Returns the Date for when the client became ready
259
+ */
260
+ get readyAt() {
261
+ if (this.readyTimestamp === null) return null;
262
+ return new Date(this.readyTimestamp);
263
+ }
264
+ /**
265
+ * Returns true if the client is currently ready
266
+ */
267
+ get ready() {
268
+ return this.readyTimestamp !== null;
269
+ }
270
+ /**
271
+ * Search and connect to RPC
272
+ */
273
+ async connect(options) {
274
+ const { promise, resolve, reject } = Promise.withResolvers();
275
+ if (this.ready) {
276
+ resolve(this);
277
+ return promise;
278
+ }
279
+ const signal = options?.signal ?? AbortSignal.timeout(1e4);
280
+ const onAbort = /* @__PURE__ */ __name((_) => {
281
+ this.removeListener(RPCEvents.Ready, onReady);
282
+ this.transport.removeListener("close", onClose);
283
+ const reason = signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason));
284
+ reject(reason);
285
+ }, "onAbort");
286
+ const onReady = /* @__PURE__ */ __name(() => {
287
+ signal.removeEventListener("abort", onAbort);
288
+ this.readyTimestamp = Date.now();
289
+ resolve(this);
290
+ }, "onReady");
291
+ const onClose = /* @__PURE__ */ __name((data) => {
292
+ signal.removeEventListener("abort", onAbort);
293
+ this.removeListener(RPCEvents.Ready, onReady);
294
+ for (const expNonce of this.#expectedNonces.values()) {
295
+ expNonce.reject(new RPCEventError("connection closed"));
296
+ }
297
+ this.#expectedNonces.clear();
298
+ this.readyTimestamp = null;
299
+ this.emit("DISCONNECTED" /* Disconnected */);
300
+ reject(new RPCEventError(JSON.stringify(data)));
301
+ }, "onClose");
302
+ signal.addEventListener("abort", onAbort);
303
+ this.once(RPCEvents.Ready, onReady);
304
+ this.transport.once("close", onClose);
305
+ try {
306
+ await this.transport.connect();
307
+ } catch (error) {
308
+ this.readyTimestamp = null;
309
+ signal.removeEventListener("abort", onAbort);
310
+ this.removeListener(RPCEvents.Ready, onReady);
311
+ this.transport.removeListener("close", onClose);
312
+ reject(error);
313
+ }
314
+ return promise;
315
+ }
316
+ /**
317
+ * Performs authentication flow. Automatically calls Client#connect if needed.
318
+ *
319
+ * @example
320
+ * logging in with a client id and secret
321
+ * ```ts
322
+ * client.login({ clientId: '1234567', clientSecret: 'abcdef123' });
323
+ * ```
324
+ */
325
+ async login({ clientId, clientSecret, accessToken }, options) {
326
+ if (!clientId) {
327
+ throw new Error("A client id must be provided to login");
328
+ }
329
+ this.clientId = clientId;
330
+ await this.connect(options);
331
+ if (!this.options.scopes) {
332
+ this.emit("APPLICATION_READY" /* ApplicationReady */);
333
+ return this;
334
+ }
335
+ if (accessToken) {
336
+ return this.authenticate(accessToken, options);
337
+ }
338
+ if (!clientSecret) {
339
+ throw new Error("A client secret must be provided for authorization if scopes are included");
340
+ }
341
+ this.clientSecret = clientSecret;
342
+ const authorizeArgs = { client_id: this.clientId, scopes: this.options.scopes };
343
+ if (this.options.username) authorizeArgs.username = this.options.username;
344
+ return this.authenticate(await this.authorize(authorizeArgs, options), options);
345
+ }
346
+ async request(cmd, args = {}, options) {
347
+ const signal = options?.signal ?? AbortSignal.timeout(1e4);
348
+ signal.throwIfAborted();
349
+ const { promise, resolve, reject } = Promise.withResolvers();
350
+ const nonce = randomUUID2();
351
+ const payload = {
352
+ cmd,
353
+ args,
354
+ nonce
355
+ };
356
+ if (cmd === RPCCommands.Subscribe || cmd === RPCCommands.Unsubscribe) {
357
+ payload.evt = options?.evt;
358
+ }
359
+ this.transport.send(payload);
360
+ this.#expectedNonces.set(nonce, { resolve, reject });
361
+ const onAbort = /* @__PURE__ */ __name((_) => {
362
+ this.#expectedNonces.delete(nonce);
363
+ const reason = signal.reason instanceof Error ? signal.reason : new Error(String(signal.reason));
364
+ reject(reason);
365
+ }, "onAbort");
366
+ signal.addEventListener("abort", onAbort, { once: true });
367
+ try {
368
+ return await promise;
369
+ } finally {
370
+ signal.removeEventListener("abort", onAbort);
371
+ }
372
+ }
373
+ /**
374
+ * Message handler
375
+ *
376
+ * @param message - message
377
+ */
378
+ #onRpcMessage(message) {
379
+ if (message.cmd === RPCCommands.Dispatch && message.evt === RPCEvents.Ready) {
380
+ if (message.data.user) {
381
+ this.user = message.data.user;
382
+ }
383
+ this.emit(RPCEvents.Ready, message.data);
384
+ } else if (message.cmd === RPCCommands.Dispatch) {
385
+ this.emit(message.evt, message.data);
386
+ } else {
387
+ if (!this.#expectedNonces.has(message.nonce)) {
388
+ return;
389
+ }
390
+ const { resolve, reject } = this.#expectedNonces.get(message.nonce);
391
+ if ("evt" in message && message.evt === RPCEvents.Error) {
392
+ reject(new RPCEventError(message.data));
393
+ } else {
394
+ resolve(message.data);
395
+ }
396
+ this.#expectedNonces.delete(message.nonce);
397
+ }
398
+ }
399
+ /**
400
+ * Authorize
401
+ *
402
+ * @param args - authorize args
403
+ */
404
+ async authorize(args, options) {
405
+ const { code } = await this.request(RPCCommands.Authorize, args, options);
406
+ const jsonBody = {
407
+ client_id: this.clientId,
408
+ client_secret: this.clientSecret,
409
+ code,
410
+ grant_type: "authorization_code"
411
+ };
412
+ if (this.options.redirectUri) {
413
+ jsonBody.redirect_uri = this.options.redirectUri;
414
+ }
415
+ const response = await fetch(`${RouteBases.api}${Routes.oauth2TokenExchange()}`, {
416
+ method: "POST",
417
+ headers: {
418
+ "Content-Type": "application/x-www-form-urlencoded"
419
+ },
420
+ body: new URLSearchParams(jsonBody),
421
+ ...options
422
+ });
423
+ if (!response.ok) {
424
+ throw new Error(response.statusText);
425
+ }
426
+ const data = await response.json();
427
+ if (!("access_token" in data)) {
428
+ throw new Error(JSON.stringify(response));
429
+ }
430
+ return data.access_token;
431
+ }
432
+ /**
433
+ * Authenticate
434
+ *
435
+ * @param accessToken - access token
436
+ */
437
+ async authenticate(accessToken, options) {
438
+ const { application, user } = await this.request(RPCCommands.Authenticate, { access_token: accessToken }, options);
439
+ this.accessToken = accessToken;
440
+ this.application = application;
441
+ this.user = user;
442
+ this.emit("APPLICATION_READY" /* ApplicationReady */);
443
+ return this;
444
+ }
445
+ /**
446
+ * Fetch a guild
447
+ *
448
+ * @param id - Guild id
449
+ * @param timeout - Timeout request
450
+ */
451
+ async getGuild(id, timeout, options) {
452
+ return this.request(RPCCommands.GetGuild, { guild_id: id, timeout }, options);
453
+ }
454
+ /**
455
+ * Fetch all guilds
456
+ *
457
+ * @param timeout - Timeout request
458
+ */
459
+ async getGuilds(timeout, options) {
460
+ return this.request(RPCCommands.GetGuilds, { timeout }, options);
461
+ }
462
+ /**
463
+ * Get a channel
464
+ *
465
+ * @param id - Channel id
466
+ */
467
+ async getChannel(id, options) {
468
+ return this.request(RPCCommands.GetChannel, { channel_id: id }, options);
469
+ }
470
+ /**
471
+ * Get all channels
472
+ *
473
+ * @param id - Guild id
474
+ */
475
+ async getChannels(id, options) {
476
+ const { channels } = await this.request(RPCCommands.GetChannels, { guild_id: id }, options);
477
+ return channels;
478
+ }
479
+ /**
480
+ * Create channel invite
481
+ *
482
+ * @param id - Channel id
483
+ */
484
+ async createChannelInvite(id, options) {
485
+ return this.request(RPCCommands.CreateChannelInvite, { channel_id: id }, options);
486
+ }
487
+ /**
488
+ * Tell discord which devices are certified
489
+ *
490
+ * @param devices - Certified devices to send to discord
491
+ */
492
+ async setCertifiedDevices(devices, options) {
493
+ return this.request(
494
+ RPCCommands.SetCertifiedDevices,
495
+ {
496
+ devices
497
+ },
498
+ options
499
+ );
500
+ }
501
+ /**
502
+ * Set the voice settings for a user, by id
503
+ *
504
+ * @param id - Id of the user to set
505
+ * @param settings - Settings to set
506
+ */
507
+ async setUserVoiceSettings(id, settings, options) {
508
+ return this.request(
509
+ RPCCommands.SetUserVoiceSettings,
510
+ {
511
+ user_id: id,
512
+ ...settings
513
+ },
514
+ options
515
+ );
516
+ }
517
+ /**
518
+ * Move the user to a voice channel
519
+ *
520
+ * @param id - Id of the voice channel
521
+ * @param args - select voice channel args
522
+ * @param options - request options
523
+ */
524
+ async selectVoiceChannel(id, args = {}, options) {
525
+ const svcArgs = { ...args, channel_id: id };
526
+ return this.request(RPCCommands.SelectVoiceChannel, svcArgs, options);
527
+ }
528
+ /**
529
+ * Move the user to a text channel
530
+ *
531
+ * @param id - Id of the text channel
532
+ * @param args - select text channel args
533
+ * @param options - request options
534
+ */
535
+ async selectTextChannel(id, args = {}, options) {
536
+ const stcArgs = { ...args, channel_id: id };
537
+ return this.request(RPCCommands.SelectTextChannel, stcArgs, options);
538
+ }
539
+ /**
540
+ * Get current voice settings
541
+ *
542
+ */
543
+ async getVoiceSettings(options) {
544
+ return this.request(RPCCommands.GetVoiceSettings, {}, options);
545
+ }
546
+ /**
547
+ * Set current voice settings, overriding the current settings until this session disconnects.
548
+ * This also locks the settings for any other rpc sessions which may be connected.
549
+ *
550
+ * @param args - Settings
551
+ */
552
+ async setVoiceSettings(args, options) {
553
+ return this.request(RPCCommands.SetVoiceSettings, args, options);
554
+ }
555
+ /**
556
+ * Sets the presence for the logged in user.
557
+ *
558
+ * @param activity - The rich presence to pass.
559
+ * @param pid - The application's process ID. Defaults to the executing process' PID.
560
+ * @remarks
561
+ * Clients may only update their activity 5 times per 20 seconds.
562
+ */
563
+ async setActivity(activity = {}, pid = getPid(), options) {
564
+ activity.instance = Boolean(activity.instance);
565
+ if (activity.timestamps) {
566
+ if ("start" in activity.timestamps && !isValidTimestamp(activity.timestamps.start)) {
567
+ throw new RangeError("timestamps.start must fit into a unix timestamp");
568
+ }
569
+ if ("end" in activity.timestamps && !isValidTimestamp(activity.timestamps.end)) {
570
+ throw new RangeError("timestamps.end must fit into a unix timestamp");
571
+ }
572
+ }
573
+ return this.request(
574
+ RPCCommands.SetActivity,
575
+ {
576
+ pid: pid ?? 0,
577
+ activity
578
+ },
579
+ options
580
+ );
581
+ }
582
+ /**
583
+ * Clears the currently set presence, if any. This will hide the "Playing X" message
584
+ * displayed below the user's name.
585
+ *
586
+ * @param pid - The application's process ID. Defaults to the executing process' PID.
587
+ */
588
+ async clearActivity(pid = getPid(), options) {
589
+ return this.request(
590
+ RPCCommands.SetActivity,
591
+ {
592
+ pid: pid ?? 0
593
+ },
594
+ options
595
+ );
596
+ }
597
+ /**
598
+ * Invite a user to join the game the RPC user is currently playing
599
+ *
600
+ * @param userId - The id of the user to invite
601
+ */
602
+ async sendJoinInvite(userId, options) {
603
+ return this.request(
604
+ RPCCommands.SendActivityJoinInvite,
605
+ {
606
+ user_id: userId
607
+ },
608
+ options
609
+ );
610
+ }
611
+ /**
612
+ * Reject a join request from a user
613
+ *
614
+ * @param userId - The id of the user whose request you wish to reject
615
+ */
616
+ async closeJoinRequest(userId, options) {
617
+ return this.request(
618
+ RPCCommands.CloseActivityJoinRequest,
619
+ {
620
+ user_id: userId
621
+ },
622
+ options
623
+ );
624
+ }
625
+ /**
626
+ * requires `relationships.read` scope
627
+ */
628
+ async getRelationships(options) {
629
+ return this.request(RPCCommands.GetRelationships, {}, options);
630
+ }
631
+ /**
632
+ * Fetches a user
633
+ */
634
+ async getUser(id, options) {
635
+ return this.request(RPCCommands.GetUser, { id }, options);
636
+ }
637
+ /**
638
+ * Fetches a user's profile picture
639
+ */
640
+ async getImage({ id, format, size }, options) {
641
+ return (await this.request(RPCCommands.GetImage, { type: "user", id, format, size }, options)).data_url;
642
+ }
643
+ /**
644
+ * Subscribe to an event
645
+ *
646
+ * @param event - Name of event e.g. `MESSAGE_CREATE`
647
+ * @param args - Args for event e.g. `{ channel_id: '1234' }`
648
+ */
649
+ async subscribe(...[event, args, options]) {
650
+ await this.request(RPCCommands.Subscribe, args, { evt: event, ...options });
651
+ return {
652
+ unsubscribe: /* @__PURE__ */ __name(async () => this.request(RPCCommands.Unsubscribe, args, { evt: event, ...options }), "unsubscribe")
653
+ };
654
+ }
655
+ /**
656
+ * Unsubscribe from an event
657
+ *
658
+ * @param event - Name of event e.g. `MESSAGE_CREATE`
659
+ * @param args - Args for event e.g. `{ channel_id: '1234' }`
660
+ */
661
+ async unsubscribe(...[event, args, options]) {
662
+ await this.request(RPCCommands.Unsubscribe, args, { evt: event, ...options });
663
+ return {
664
+ subscribe: /* @__PURE__ */ __name(async () => this.request(RPCCommands.Subscribe, args, { evt: event, ...options }), "subscribe")
665
+ };
666
+ }
667
+ /**
668
+ * Destroy the client
669
+ */
670
+ async destroy() {
671
+ await this.transport.close();
672
+ }
673
+ };
674
+
675
+ // src/index.ts
676
+ var version = "0.2.0-dev.1788538586-ecea9ed57";
677
+ export {
678
+ Events,
679
+ IPCTransport,
680
+ RPCClient,
681
+ RPCEventError,
682
+ encode,
683
+ getPid,
684
+ isValidTimestamp,
685
+ register,
686
+ version
687
+ };
688
+ //# sourceMappingURL=index.js.map