@helyx/bot 0.3.1 → 0.4.2

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.
@@ -0,0 +1,445 @@
1
+ import { z } from "zod";
2
+ export const SHARD_CONTRACT_VERSION = 1;
3
+ export const SHARD_CONTROL_MAX_BYTES = 64 * 1_024;
4
+ export const SHARD_CONTROL_TIMEOUT_MS = 10_000;
5
+ export const SHARD_HEALTH_STALE_MS = 30_000;
6
+ export const SHARD_LEASE_HEARTBEAT_TIMEOUT_MS = 20_000;
7
+ const snowflake = z.string().regex(/^\d{17,20}$/u);
8
+ const safeIdentifier = z.string().regex(/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/u);
9
+ const dateTime = z.iso.datetime({ offset: true });
10
+ const moduleId = z.string().regex(/^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)+$/u);
11
+ const mutationContext = z
12
+ .object({
13
+ actorUserId: snowflake,
14
+ correlationId: z.string().min(1).max(200),
15
+ })
16
+ .strict();
17
+ const permissionPolicy = z
18
+ .object({
19
+ preset: z.enum(["everyone", "moderators", "administrators", "custom"]),
20
+ allowedRoleIds: z.array(snowflake).max(100),
21
+ deniedRoleIds: z.array(snowflake).max(100),
22
+ })
23
+ .strict();
24
+ const permissionState = z
25
+ .object({
26
+ version: z.number().int().min(0),
27
+ module: permissionPolicy,
28
+ commands: z
29
+ .array(z
30
+ .object({
31
+ commandId: z.string().min(1).max(100),
32
+ version: z.number().int().min(0),
33
+ enabled: z.boolean(),
34
+ policy: permissionPolicy,
35
+ })
36
+ .strict())
37
+ .max(100),
38
+ })
39
+ .strict();
40
+ const configurationValue = z.record(z.string().min(1).max(100), z.union([
41
+ z.string().max(4_000),
42
+ z.boolean(),
43
+ z.number().finite(),
44
+ z.array(z.string().max(4_000)).max(100),
45
+ ]));
46
+ export const shardIdentitySchema = z
47
+ .object({
48
+ version: z.literal(SHARD_CONTRACT_VERSION),
49
+ mode: z.enum(["auto", "fixed"]),
50
+ scope: z.enum(["local", "coordinated"]),
51
+ generation: safeIdentifier,
52
+ deploymentOrder: z.number().int().positive().optional(),
53
+ supervisorId: z.uuid(),
54
+ shardId: z.number().int().min(0).max(4_095),
55
+ shardCount: z.number().int().min(1).max(4_096),
56
+ fencingToken: z.number().int().positive(),
57
+ })
58
+ .strict()
59
+ .superRefine((identity, context) => {
60
+ if (identity.shardId >= identity.shardCount)
61
+ context.addIssue({
62
+ code: "custom",
63
+ path: ["shardId"],
64
+ message: "must be lower than shardCount",
65
+ });
66
+ });
67
+ export const gatewayBotInformationSchema = z
68
+ .object({
69
+ url: z.url(),
70
+ shards: z.number().int().min(1).max(4_096),
71
+ session_start_limit: z
72
+ .object({
73
+ total: z.number().int().min(1),
74
+ remaining: z.number().int().min(0),
75
+ reset_after: z.number().int().min(0),
76
+ max_concurrency: z.number().int().min(1),
77
+ })
78
+ .strict(),
79
+ })
80
+ .strict();
81
+ export const shardProcessHealthSchema = z
82
+ .object({
83
+ shardId: z.number().int().min(0).max(4_095),
84
+ status: z.enum([
85
+ "starting",
86
+ "ready",
87
+ "disconnected",
88
+ "reconnecting",
89
+ "stopped",
90
+ "failed",
91
+ ]),
92
+ guildCount: z.number().int().min(0),
93
+ gatewayPingMs: z.number().finite().min(-1).max(300_000),
94
+ uptimeSeconds: z.number().finite().min(0),
95
+ restartCount: z.number().int().min(0),
96
+ eventLoopDelayMs: z.number().finite().min(0).max(300_000),
97
+ memoryRssBytes: z.number().int().min(0),
98
+ queueDepth: z.number().int().min(0).max(10_000),
99
+ observedAt: dateTime,
100
+ })
101
+ .strict();
102
+ const sessionStartBudgetSchema = z
103
+ .object({
104
+ total: z.number().int().min(1),
105
+ remaining: z.number().int().min(0),
106
+ resetAt: dateTime,
107
+ maxConcurrency: z.number().int().min(1),
108
+ observedAt: dateTime,
109
+ })
110
+ .strict();
111
+ export const shardHealthSnapshotSchema = z
112
+ .object({
113
+ version: z.literal(SHARD_CONTRACT_VERSION),
114
+ mode: z.enum(["off", "auto", "fixed"]),
115
+ scope: z.enum(["local", "coordinated"]),
116
+ status: z.enum(["healthy", "degraded", "starting", "unavailable", "stale"]),
117
+ observedAt: dateTime,
118
+ generation: safeIdentifier,
119
+ supervisorId: z.uuid(),
120
+ configuredShardCount: z.number().int().min(1).max(4_096),
121
+ readyShardCount: z.number().int().min(0).max(4_096),
122
+ coordination: z
123
+ .object({
124
+ redis: z.enum(["not_required", "healthy", "degraded", "unavailable"]),
125
+ database: z.enum(["healthy", "degraded", "unavailable"]),
126
+ })
127
+ .strict(),
128
+ sessionStarts: sessionStartBudgetSchema.optional(),
129
+ shards: z.array(shardProcessHealthSchema).max(4_096),
130
+ })
131
+ .strict()
132
+ .superRefine((health, context) => {
133
+ if (health.readyShardCount > health.configuredShardCount)
134
+ context.addIssue({
135
+ code: "custom",
136
+ path: ["readyShardCount"],
137
+ message: "cannot exceed configuredShardCount",
138
+ });
139
+ if (health.shards.some((shard) => shard.shardId >= health.configuredShardCount))
140
+ context.addIssue({
141
+ code: "custom",
142
+ path: ["shards"],
143
+ message: "contains a shard outside configuredShardCount",
144
+ });
145
+ });
146
+ export const shardControlOperationSchema = z.discriminatedUnion("kind", [
147
+ z.object({ kind: z.literal("guild.state.get"), guildId: snowflake }).strict(),
148
+ z
149
+ .object({
150
+ kind: z.literal("guild.module.status.set"),
151
+ guildId: snowflake,
152
+ moduleId,
153
+ enabled: z.boolean(),
154
+ ...mutationContext.shape,
155
+ })
156
+ .strict(),
157
+ z
158
+ .object({
159
+ kind: z.literal("guild.module.configuration.update"),
160
+ guildId: snowflake,
161
+ moduleId,
162
+ value: configurationValue,
163
+ expectedVersion: z.number().int().positive().nullable(),
164
+ ...mutationContext.shape,
165
+ })
166
+ .strict(),
167
+ z
168
+ .object({
169
+ kind: z.literal("guild.module.permissions.update"),
170
+ guildId: snowflake,
171
+ moduleId,
172
+ state: permissionState,
173
+ ...mutationContext.shape,
174
+ })
175
+ .strict(),
176
+ z
177
+ .object({
178
+ kind: z.literal("guild.module.logging.update"),
179
+ guildId: snowflake,
180
+ moduleId,
181
+ eventId: z.string().regex(/^[a-z][a-z0-9_-]*$/u),
182
+ enabled: z.boolean(),
183
+ expectedVersion: z.number().int().min(0),
184
+ ...mutationContext.shape,
185
+ })
186
+ .strict(),
187
+ z
188
+ .object({
189
+ kind: z.literal("guild.module.action.execute"),
190
+ guildId: snowflake,
191
+ moduleId,
192
+ actionId: z.string().regex(/^[a-z][a-z0-9_-]*$/u),
193
+ ...mutationContext.shape,
194
+ })
195
+ .strict(),
196
+ z.object({ kind: z.literal("privacy.providers.list") }).strict(),
197
+ z
198
+ .object({
199
+ kind: z.literal("privacy.capture"),
200
+ providerId: moduleId,
201
+ providerVersion: z.number().int().positive(),
202
+ requestId: z.uuid(),
203
+ subjectUserId: snowflake,
204
+ cutoffAt: dateTime,
205
+ cursor: z.string().min(1).max(2_048).optional(),
206
+ })
207
+ .strict(),
208
+ z
209
+ .object({
210
+ kind: z.literal("privacy.erase"),
211
+ providerId: moduleId,
212
+ providerVersion: z.number().int().positive(),
213
+ requestId: z.uuid(),
214
+ subjectUserId: snowflake,
215
+ executeThrough: dateTime,
216
+ cursor: z.string().min(1).max(2_048).optional(),
217
+ })
218
+ .strict(),
219
+ ]);
220
+ export const shardControlRequestSchema = z
221
+ .object({
222
+ version: z.literal(SHARD_CONTRACT_VERSION),
223
+ type: z.literal("helyx.control.request"),
224
+ requestId: z.uuid(),
225
+ generation: safeIdentifier,
226
+ fencingToken: z.number().int().positive(),
227
+ deadlineAt: dateTime,
228
+ operation: shardControlOperationSchema,
229
+ })
230
+ .strict();
231
+ export const shardControlResponseSchema = z.discriminatedUnion("ok", [
232
+ z
233
+ .object({
234
+ version: z.literal(SHARD_CONTRACT_VERSION),
235
+ type: z.literal("helyx.control.response"),
236
+ requestId: z.uuid(),
237
+ ok: z.literal(true),
238
+ result: z.unknown(),
239
+ })
240
+ .strict(),
241
+ z
242
+ .object({
243
+ version: z.literal(SHARD_CONTRACT_VERSION),
244
+ type: z.literal("helyx.control.response"),
245
+ requestId: z.uuid(),
246
+ ok: z.literal(false),
247
+ status: z.number().int().min(400).max(599),
248
+ message: z.string().min(1).max(300),
249
+ })
250
+ .strict(),
251
+ ]);
252
+ const shardCloudOperationSchema = z.discriminatedUnion("kind", [
253
+ z.object({ kind: z.literal("cloud.status") }).strict(),
254
+ z.object({ kind: z.literal("cloud.consent.get") }).strict(),
255
+ z
256
+ .object({
257
+ kind: z.literal("cloud.consent.update"),
258
+ supportInspectionEnabled: z.boolean(),
259
+ supportDataClasses: z.array(z.string().min(1).max(100)).max(5),
260
+ diagnosticsEnabled: z.boolean(),
261
+ })
262
+ .strict(),
263
+ z
264
+ .object({
265
+ kind: z.literal("cloud.enrol"),
266
+ token: z.string().min(1).max(200),
267
+ source: z.enum(["discord", "file", "startup"]),
268
+ })
269
+ .strict(),
270
+ z.object({ kind: z.literal("cloud.disconnect") }).strict(),
271
+ z.object({ kind: z.literal("cloud.rotate") }).strict(),
272
+ ]);
273
+ export const shardCloudRequestSchema = z
274
+ .object({
275
+ version: z.literal(SHARD_CONTRACT_VERSION),
276
+ type: z.literal("helyx.cloud.request"),
277
+ requestId: z.uuid(),
278
+ deadlineAt: dateTime,
279
+ operation: shardCloudOperationSchema,
280
+ })
281
+ .strict();
282
+ export const shardCloudResponseSchema = z.discriminatedUnion("ok", [
283
+ z
284
+ .object({
285
+ version: z.literal(SHARD_CONTRACT_VERSION),
286
+ type: z.literal("helyx.cloud.response"),
287
+ requestId: z.uuid(),
288
+ ok: z.literal(true),
289
+ result: z.unknown(),
290
+ })
291
+ .strict(),
292
+ z
293
+ .object({
294
+ version: z.literal(SHARD_CONTRACT_VERSION),
295
+ type: z.literal("helyx.cloud.response"),
296
+ requestId: z.uuid(),
297
+ ok: z.literal(false),
298
+ message: z.string().min(1).max(300),
299
+ })
300
+ .strict(),
301
+ ]);
302
+ export const shardOperationsHealthRequestSchema = z
303
+ .object({
304
+ version: z.literal(SHARD_CONTRACT_VERSION),
305
+ type: z.literal("helyx.operations.health.request"),
306
+ requestId: z.uuid(),
307
+ deadlineAt: dateTime,
308
+ })
309
+ .strict();
310
+ export const shardOperationsHealthResponseSchema = z
311
+ .object({
312
+ version: z.literal(SHARD_CONTRACT_VERSION),
313
+ type: z.literal("helyx.operations.health.response"),
314
+ requestId: z.uuid(),
315
+ health: shardHealthSnapshotSchema,
316
+ })
317
+ .strict();
318
+ export const supervisorMessageSchema = z.discriminatedUnion("type", [
319
+ shardControlRequestSchema,
320
+ shardCloudResponseSchema,
321
+ shardOperationsHealthResponseSchema,
322
+ z
323
+ .object({
324
+ version: z.literal(SHARD_CONTRACT_VERSION),
325
+ type: z.literal("helyx.lease.heartbeat"),
326
+ identity: shardIdentitySchema,
327
+ })
328
+ .strict(),
329
+ z
330
+ .object({
331
+ version: z.literal(SHARD_CONTRACT_VERSION),
332
+ type: z.literal("helyx.health.request"),
333
+ })
334
+ .strict(),
335
+ z
336
+ .object({
337
+ version: z.literal(SHARD_CONTRACT_VERSION),
338
+ type: z.literal("helyx.shutdown"),
339
+ reason: z.string().min(1).max(100),
340
+ })
341
+ .strict(),
342
+ ]);
343
+ export const workerMessageSchema = z.discriminatedUnion("type", [
344
+ shardControlResponseSchema,
345
+ shardCloudRequestSchema,
346
+ shardOperationsHealthRequestSchema,
347
+ z
348
+ .object({
349
+ version: z.literal(SHARD_CONTRACT_VERSION),
350
+ type: z.literal("helyx.health.update"),
351
+ identity: shardIdentitySchema,
352
+ health: shardProcessHealthSchema,
353
+ })
354
+ .strict(),
355
+ ]);
356
+ export function guildIdToShardId(guildId, shardCount) {
357
+ const parsedGuildId = snowflake.parse(guildId);
358
+ if (!Number.isSafeInteger(shardCount) || shardCount < 1 || shardCount > 4_096)
359
+ throw new Error("Shard count must be an integer between 1 and 4096");
360
+ return Number((BigInt(parsedGuildId) >> 22n) % BigInt(shardCount));
361
+ }
362
+ export function controlOperationGuildId(operation) {
363
+ return "guildId" in operation ? operation.guildId : undefined;
364
+ }
365
+ export function assertShardMessageSize(value) {
366
+ if (Buffer.byteLength(JSON.stringify(value), "utf8") > SHARD_CONTROL_MAX_BYTES)
367
+ throw new Error("Shard control message exceeds the byte limit");
368
+ }
369
+ export async function executeShardControlOperation(handler, operation) {
370
+ switch (operation.kind) {
371
+ case "guild.state.get":
372
+ return handler.getGuildState(operation.guildId);
373
+ case "guild.module.status.set": {
374
+ return handler.setModuleStatus({
375
+ guildId: operation.guildId,
376
+ moduleId: operation.moduleId,
377
+ enabled: operation.enabled,
378
+ actorUserId: operation.actorUserId,
379
+ correlationId: operation.correlationId,
380
+ });
381
+ }
382
+ case "guild.module.configuration.update": {
383
+ return handler.updateConfiguration({
384
+ guildId: operation.guildId,
385
+ moduleId: operation.moduleId,
386
+ value: operation.value,
387
+ expectedVersion: operation.expectedVersion,
388
+ actorUserId: operation.actorUserId,
389
+ correlationId: operation.correlationId,
390
+ });
391
+ }
392
+ case "guild.module.permissions.update": {
393
+ return handler.updatePermissions({
394
+ guildId: operation.guildId,
395
+ moduleId: operation.moduleId,
396
+ state: operation.state,
397
+ actorUserId: operation.actorUserId,
398
+ correlationId: operation.correlationId,
399
+ });
400
+ }
401
+ case "guild.module.logging.update": {
402
+ return handler.updateLoggingPolicy({
403
+ guildId: operation.guildId,
404
+ moduleId: operation.moduleId,
405
+ eventId: operation.eventId,
406
+ enabled: operation.enabled,
407
+ expectedVersion: operation.expectedVersion,
408
+ actorUserId: operation.actorUserId,
409
+ correlationId: operation.correlationId,
410
+ });
411
+ }
412
+ case "guild.module.action.execute": {
413
+ return handler.executeDashboardAction({
414
+ guildId: operation.guildId,
415
+ moduleId: operation.moduleId,
416
+ actionId: operation.actionId,
417
+ actorUserId: operation.actorUserId,
418
+ correlationId: operation.correlationId,
419
+ });
420
+ }
421
+ case "privacy.providers.list":
422
+ return handler.listPrivacyProviders();
423
+ case "privacy.capture": {
424
+ return handler.capturePrivacy({
425
+ providerId: operation.providerId,
426
+ providerVersion: operation.providerVersion,
427
+ requestId: operation.requestId,
428
+ subjectUserId: operation.subjectUserId,
429
+ cutoffAt: new Date(operation.cutoffAt),
430
+ ...(operation.cursor === undefined ? {} : { cursor: operation.cursor }),
431
+ });
432
+ }
433
+ case "privacy.erase": {
434
+ return handler.erasePrivacy({
435
+ providerId: operation.providerId,
436
+ providerVersion: operation.providerVersion,
437
+ requestId: operation.requestId,
438
+ subjectUserId: operation.subjectUserId,
439
+ executeThrough: new Date(operation.executeThrough),
440
+ ...(operation.cursor === undefined ? {} : { cursor: operation.cursor }),
441
+ });
442
+ }
443
+ }
444
+ }
445
+ //# sourceMappingURL=shard-contracts.js.map
@@ -0,0 +1,90 @@
1
+ import { randomUUID } from "node:crypto";
2
+ import { z } from "zod";
3
+ import { type ShardControlRequest, type ShardControlResponse, type ShardCloudRequest, type ShardCloudResponse, type ShardIdentity, type ShardProcessHealth } from "./shard-contracts.js";
4
+ declare const generationDescriptorSchema: z.ZodObject<{
5
+ version: z.ZodLiteral<1>;
6
+ applicationId: z.ZodString;
7
+ environment: z.ZodEnum<{
8
+ development: "development";
9
+ test: "test";
10
+ production: "production";
11
+ }>;
12
+ generation: z.ZodString;
13
+ shardCount: z.ZodNumber;
14
+ catalogueHash: z.ZodString;
15
+ }, z.core.$strict>;
16
+ export type ShardGenerationDescriptor = z.infer<typeof generationDescriptorSchema>;
17
+ declare const leaseSchema: z.ZodObject<{
18
+ generation: z.ZodString;
19
+ deploymentOrder: z.ZodNumber;
20
+ supervisorId: z.ZodUUID;
21
+ shardId: z.ZodNumber;
22
+ fencingToken: z.ZodNumber;
23
+ }, z.core.$strict>;
24
+ export type ShardLease = z.infer<typeof leaseSchema>;
25
+ declare const leaderLeaseSchema: z.ZodObject<{
26
+ generation: z.ZodString;
27
+ supervisorId: z.ZodUUID;
28
+ fencingToken: z.ZodNumber;
29
+ }, z.core.$strict>;
30
+ export type ShardLeaderLease = z.infer<typeof leaderLeaseSchema>;
31
+ export interface ShardCoordinator {
32
+ readonly supervisorId: ReturnType<typeof randomUUID>;
33
+ start(handler: (targetShardId: number, request: ShardControlRequest) => Promise<ShardControlResponse>, leaderHandler?: (request: ShardControlRequest) => Promise<ShardControlResponse>, cloudHandler?: (request: ShardCloudRequest) => Promise<ShardCloudResponse>): Promise<void>;
34
+ checkReady(): Promise<void>;
35
+ assertGeneration(descriptor: ShardGenerationDescriptor, proposedDeploymentOrder: number): Promise<number>;
36
+ refreshGeneration(descriptor: ShardGenerationDescriptor, deploymentOrder: number): Promise<boolean>;
37
+ claimShard(descriptor: ShardGenerationDescriptor, shardId: number, deploymentOrder: number): Promise<ShardLease | undefined>;
38
+ renewShard(lease: ShardLease): Promise<boolean>;
39
+ releaseShard(lease: ShardLease): Promise<boolean>;
40
+ getShardLease(shardId: number): Promise<ShardLease | undefined>;
41
+ getShardLeases(shardCount: number): Promise<ShardLease[]>;
42
+ acquireLeader(descriptor: ShardGenerationDescriptor, deploymentOrder: number): Promise<ShardLeaderLease | undefined>;
43
+ renewLeader(lease: ShardLeaderLease): Promise<boolean>;
44
+ releaseLeader(lease: ShardLeaderLease): Promise<boolean>;
45
+ getLeaderLease(): Promise<ShardLeaderLease | undefined>;
46
+ routeRemote(lease: ShardLease, request: ShardControlRequest): Promise<ShardControlResponse>;
47
+ routeLeader(lease: ShardLeaderLease, request: ShardControlRequest): Promise<ShardControlResponse>;
48
+ routeLeaderCloud(lease: ShardLeaderLease, request: ShardCloudRequest): Promise<ShardCloudResponse>;
49
+ reserveSessionStarts(count: number, available: number, resetAfterMs: number): Promise<boolean>;
50
+ acquireIdentifyPermit(shardId: number, maxConcurrency: number, timeoutMs: number): Promise<boolean>;
51
+ setHealth(identity: ShardIdentity, health: ShardProcessHealth): Promise<void>;
52
+ getHealth(shardCount: number): Promise<Array<{
53
+ identity: ShardIdentity;
54
+ health: ShardProcessHealth;
55
+ }>>;
56
+ stop(): Promise<void>;
57
+ }
58
+ export declare class RedisShardCoordinator implements ShardCoordinator {
59
+ #private;
60
+ readonly supervisorId: `${string}-${string}-${string}-${string}-${string}`;
61
+ constructor(redisUrl: string, namespace: string, options?: {
62
+ onError?: (error: Error) => void;
63
+ });
64
+ start(handler: (targetShardId: number, request: ShardControlRequest) => Promise<ShardControlResponse>, leaderHandler?: (request: ShardControlRequest) => Promise<ShardControlResponse>, cloudHandler?: (request: ShardCloudRequest) => Promise<ShardCloudResponse>): Promise<void>;
65
+ checkReady(): Promise<void>;
66
+ assertGeneration(descriptor: ShardGenerationDescriptor, proposedDeploymentOrder: number): Promise<number>;
67
+ refreshGeneration(descriptor: ShardGenerationDescriptor, deploymentOrder: number): Promise<boolean>;
68
+ claimShard(descriptor: ShardGenerationDescriptor, shardId: number, deploymentOrder: number): Promise<ShardLease | undefined>;
69
+ renewShard(lease: ShardLease): Promise<boolean>;
70
+ releaseShard(lease: ShardLease): Promise<boolean>;
71
+ getShardLease(shardId: number): Promise<ShardLease | undefined>;
72
+ getShardLeases(shardCount: number): Promise<ShardLease[]>;
73
+ acquireLeader(descriptor: ShardGenerationDescriptor, deploymentOrder: number): Promise<ShardLeaderLease | undefined>;
74
+ renewLeader(lease: ShardLeaderLease): Promise<boolean>;
75
+ releaseLeader(lease: ShardLeaderLease): Promise<boolean>;
76
+ getLeaderLease(): Promise<ShardLeaderLease | undefined>;
77
+ routeRemote(lease: ShardLease, request: ShardControlRequest): Promise<ShardControlResponse>;
78
+ routeLeader(lease: ShardLeaderLease, request: ShardControlRequest): Promise<ShardControlResponse>;
79
+ routeLeaderCloud(lease: ShardLeaderLease, request: ShardCloudRequest): Promise<ShardCloudResponse>;
80
+ reserveSessionStarts(count: number, available: number, resetAfterMs: number): Promise<boolean>;
81
+ acquireIdentifyPermit(shardId: number, maxConcurrency: number, timeoutMs: number): Promise<boolean>;
82
+ setHealth(identity: ShardIdentity, health: ShardProcessHealth): Promise<void>;
83
+ getHealth(shardCount: number): Promise<Array<{
84
+ identity: ShardIdentity;
85
+ health: ShardProcessHealth;
86
+ }>>;
87
+ stop(): Promise<void>;
88
+ }
89
+ export {};
90
+ //# sourceMappingURL=shard-coordinator.d.ts.map