sonamu 0.9.4 → 0.9.6
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/ai/providers/rtzr/utils.js +2 -2
- package/dist/api/config.d.ts +13 -2
- package/dist/api/config.d.ts.map +1 -1
- package/dist/api/config.js +1 -1
- package/dist/api/context.d.ts +17 -7
- package/dist/api/context.d.ts.map +1 -1
- package/dist/api/context.js +1 -1
- package/dist/api/decorators.d.ts +18 -0
- package/dist/api/decorators.d.ts.map +1 -1
- package/dist/api/decorators.js +54 -3
- package/dist/api/index.js +8 -3
- package/dist/api/sonamu.d.ts +24 -9
- package/dist/api/sonamu.d.ts.map +1 -1
- package/dist/api/sonamu.js +365 -79
- package/dist/api/websocket-helpers.d.ts +24 -0
- package/dist/api/websocket-helpers.d.ts.map +1 -0
- package/dist/api/websocket-helpers.js +77 -0
- package/dist/bin/cli.js +12 -4
- package/dist/database/upsert-builder.js +4 -4
- package/dist/dict/sonamu-dictionary.js +6 -6
- package/dist/entity/entity-manager.js +1 -1
- package/dist/entity/entity.js +3 -3
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -4
- package/dist/migration/code-generation.d.ts.map +1 -1
- package/dist/migration/code-generation.js +8 -9
- package/dist/stream/index.d.ts +6 -0
- package/dist/stream/index.d.ts.map +1 -1
- package/dist/stream/index.js +13 -2
- package/dist/stream/ws-audience-resolver.d.ts +15 -0
- package/dist/stream/ws-audience-resolver.d.ts.map +1 -0
- package/dist/stream/ws-audience-resolver.js +31 -0
- package/dist/stream/ws-audience.d.ts +28 -0
- package/dist/stream/ws-audience.d.ts.map +1 -0
- package/dist/stream/ws-audience.js +46 -0
- package/dist/stream/ws-cluster-bus.d.ts +23 -0
- package/dist/stream/ws-cluster-bus.d.ts.map +1 -0
- package/dist/stream/ws-cluster-bus.js +18 -0
- package/dist/stream/ws-core.d.ts +15 -0
- package/dist/stream/ws-core.d.ts.map +1 -0
- package/dist/stream/ws-core.js +1 -0
- package/dist/stream/ws-delivery.d.ts +24 -0
- package/dist/stream/ws-delivery.d.ts.map +1 -0
- package/dist/stream/ws-delivery.js +103 -0
- package/dist/stream/ws-local-connection-store.d.ts +10 -0
- package/dist/stream/ws-local-connection-store.d.ts.map +1 -0
- package/dist/stream/ws-local-connection-store.js +44 -0
- package/dist/stream/ws-presence-store.d.ts +61 -0
- package/dist/stream/ws-presence-store.d.ts.map +1 -0
- package/dist/stream/ws-presence-store.js +236 -0
- package/dist/stream/ws-registry.d.ts +42 -0
- package/dist/stream/ws-registry.d.ts.map +1 -0
- package/dist/stream/ws-registry.js +108 -0
- package/dist/stream/ws.d.ts +52 -0
- package/dist/stream/ws.d.ts.map +1 -0
- package/dist/stream/ws.js +397 -0
- package/dist/syncer/api-parser.d.ts.map +1 -1
- package/dist/syncer/api-parser.js +72 -2
- package/dist/syncer/checksum.d.ts.map +1 -1
- package/dist/syncer/checksum.js +13 -12
- package/dist/syncer/code-generator.d.ts.map +1 -1
- package/dist/syncer/code-generator.js +7 -4
- package/dist/syncer/event-batcher.d.ts +27 -0
- package/dist/syncer/event-batcher.d.ts.map +1 -0
- package/dist/syncer/event-batcher.js +69 -0
- package/dist/syncer/file-patterns.d.ts +48 -26
- package/dist/syncer/file-patterns.d.ts.map +1 -1
- package/dist/syncer/file-patterns.js +71 -23
- package/dist/syncer/file-tracking.d.ts +13 -0
- package/dist/syncer/file-tracking.d.ts.map +1 -0
- package/dist/syncer/file-tracking.js +33 -0
- package/dist/syncer/index.js +2 -2
- package/dist/syncer/module-loader.d.ts +2 -11
- package/dist/syncer/module-loader.d.ts.map +1 -1
- package/dist/syncer/module-loader.js +3 -3
- package/dist/syncer/syncer-actions.d.ts +39 -6
- package/dist/syncer/syncer-actions.d.ts.map +1 -1
- package/dist/syncer/syncer-actions.js +125 -10
- package/dist/syncer/syncer.d.ts +33 -19
- package/dist/syncer/syncer.d.ts.map +1 -1
- package/dist/syncer/syncer.js +168 -168
- package/dist/syncer/watcher.d.ts +8 -0
- package/dist/syncer/watcher.d.ts.map +1 -0
- package/dist/syncer/watcher.js +105 -0
- package/dist/tasks/workflow-manager.d.ts.map +1 -1
- package/dist/tasks/workflow-manager.js +2 -1
- package/dist/template/implementations/services.template.d.ts.map +1 -1
- package/dist/template/implementations/services.template.js +36 -1
- package/dist/testing/bootstrap.d.ts.map +1 -1
- package/dist/testing/bootstrap.js +8 -1
- package/dist/testing/data-explorer.d.ts.map +1 -1
- package/dist/testing/data-explorer.js +5 -3
- package/dist/testing/fixture-manager.js +1 -1
- package/dist/types/types.d.ts +2 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/types.js +2 -2
- package/dist/ui/api.d.ts.map +1 -1
- package/dist/ui/api.js +4 -3
- package/dist/ui/cdd-service.js +1 -1
- package/dist/ui-web/assets/{index-C5KUjXm0.js → index-BmThfg-s.js} +39 -39
- package/dist/ui-web/assets/index-D4rYm-Xz.css +1 -0
- package/dist/ui-web/index.html +2 -2
- package/dist/utils/async-utils.d.ts +27 -3
- package/dist/utils/async-utils.d.ts.map +1 -1
- package/dist/utils/async-utils.js +56 -6
- package/dist/utils/formatter.d.ts +7 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +95 -60
- package/dist/utils/fs-utils.d.ts +2 -0
- package/dist/utils/fs-utils.d.ts.map +1 -1
- package/dist/utils/fs-utils.js +10 -2
- package/dist/utils/process-utils.d.ts +6 -0
- package/dist/utils/process-utils.d.ts.map +1 -1
- package/dist/utils/process-utils.js +16 -3
- package/dist/utils/utils.d.ts +1 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +2 -2
- package/package.json +7 -5
- package/src/ai/providers/rtzr/utils.ts +1 -1
- package/src/api/__tests__/sonamu.websocket.test.ts +64 -0
- package/src/api/__tests__/websocket-context.types.test.ts +58 -0
- package/src/api/config.ts +28 -2
- package/src/api/context.ts +21 -7
- package/src/api/decorators.ts +101 -1
- package/src/api/sonamu.ts +529 -127
- package/src/api/websocket-helpers.ts +122 -0
- package/src/bin/cli.ts +10 -2
- package/src/database/upsert-builder.ts +3 -3
- package/src/dict/sonamu-dictionary.ts +3 -3
- package/src/entity/entity.ts +1 -1
- package/src/index.ts +6 -0
- package/src/migration/code-generation.ts +6 -11
- package/src/shared/app.shared.ts.txt +312 -4
- package/src/shared/web.shared.ts.txt +340 -4
- package/src/stream/__tests__/ws-contracts.test.ts +381 -0
- package/src/stream/__tests__/ws.test.ts +449 -0
- package/src/stream/index.ts +6 -0
- package/src/stream/ws-audience-resolver.ts +35 -0
- package/src/stream/ws-audience.ts +62 -0
- package/src/stream/ws-cluster-bus.ts +32 -0
- package/src/stream/ws-core.ts +16 -0
- package/src/stream/ws-delivery.ts +138 -0
- package/src/stream/ws-local-connection-store.ts +44 -0
- package/src/stream/ws-presence-store.ts +326 -0
- package/src/stream/ws-registry.ts +138 -0
- package/src/stream/ws.ts +591 -0
- package/src/syncer/__tests__/api-parser.websocket-type-ref.test.ts +78 -0
- package/src/syncer/api-parser.ts +112 -1
- package/src/syncer/checksum.ts +23 -29
- package/src/syncer/code-generator.ts +4 -1
- package/src/syncer/event-batcher.ts +72 -0
- package/src/syncer/file-patterns.ts +98 -30
- package/src/syncer/file-tracking.ts +27 -0
- package/src/syncer/module-loader.ts +5 -12
- package/src/syncer/syncer-actions.ts +179 -17
- package/src/syncer/syncer.ts +250 -287
- package/src/syncer/watcher.ts +128 -0
- package/src/tasks/workflow-manager.ts +1 -0
- package/src/template/__tests__/services.template.websocket.test.ts +79 -0
- package/src/template/implementations/services.template.ts +69 -0
- package/src/testing/bootstrap.ts +8 -1
- package/src/testing/data-explorer.ts +3 -2
- package/src/types/types.ts +20 -2
- package/src/ui/api.ts +10 -1
- package/src/utils/async-utils.ts +71 -4
- package/src/utils/formatter.ts +114 -75
- package/src/utils/fs-utils.ts +9 -0
- package/src/utils/process-utils.ts +17 -0
- package/src/utils/utils.ts +1 -1
- package/dist/ui-web/assets/index-Dr8pRJC_.css +0 -1
|
@@ -0,0 +1,397 @@
|
|
|
1
|
+
import { __esmMin } from "../_virtual/rolldown_runtime.js";
|
|
2
|
+
import { WebSocketRegistry, init_ws_registry } from "./ws-registry.js";
|
|
3
|
+
import { z as z$1 } from "zod";
|
|
4
|
+
import { randomUUID } from "node:crypto";
|
|
5
|
+
|
|
6
|
+
//#region src/stream/ws.ts
|
|
7
|
+
function createWebSocketRuntime(options = {}) {
|
|
8
|
+
return new WebSocketRuntime(options);
|
|
9
|
+
}
|
|
10
|
+
function normalizeMessage(raw) {
|
|
11
|
+
if (typeof raw === "string") {
|
|
12
|
+
return raw;
|
|
13
|
+
}
|
|
14
|
+
if (raw instanceof Buffer) {
|
|
15
|
+
return raw.toString("utf-8");
|
|
16
|
+
}
|
|
17
|
+
if (raw instanceof ArrayBuffer) {
|
|
18
|
+
return Buffer.from(raw).toString("utf-8");
|
|
19
|
+
}
|
|
20
|
+
if (Array.isArray(raw)) {
|
|
21
|
+
return Buffer.concat(raw.filter((chunk) => chunk instanceof Buffer)).toString("utf-8");
|
|
22
|
+
}
|
|
23
|
+
return JSON.stringify(raw);
|
|
24
|
+
}
|
|
25
|
+
function safeParseEnvelope(raw) {
|
|
26
|
+
try {
|
|
27
|
+
const parsed = JSON.parse(raw);
|
|
28
|
+
const validated = WebSocketEnvelopeSchema.safeParse(parsed);
|
|
29
|
+
return validated.success ? validated.data : null;
|
|
30
|
+
} catch {
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
function truncateCloseReason(reason) {
|
|
35
|
+
if (!reason) {
|
|
36
|
+
return undefined;
|
|
37
|
+
}
|
|
38
|
+
return Buffer.byteLength(reason, "utf-8") <= 123 ? reason : Buffer.from(reason).subarray(0, 123).toString("utf-8");
|
|
39
|
+
}
|
|
40
|
+
function isPromiseLike(value) {
|
|
41
|
+
return typeof value === "object" && value !== null && "then" in value && "catch" in value;
|
|
42
|
+
}
|
|
43
|
+
var WS_CONNECTING, WS_OPEN, WS_CLOSED, WS_CLOSE_CODE_GOING_AWAY, WS_CLOSE_CODE_INVALID_FRAME_PAYLOAD_DATA, WS_CLOSE_CODE_POLICY_VIOLATION, WS_CLOSE_CODE_MESSAGE_TOO_BIG, WS_CLOSE_CODE_INTERNAL_ERROR, WS_CLOSE_CODE_TRY_AGAIN_LATER, MAX_PENDING_MESSAGES, MAX_PENDING_OUTBOUND_MESSAGES, MAX_SOCKET_BUFFERED_AMOUNT, OUTBOUND_BATCH_SIZE, OUTBOUND_RETRY_DELAY_MS, WebSocketEnvelopeSchema, WebSocketRuntime, WebSocketConnectionImpl;
|
|
44
|
+
var init_ws = __esmMin((() => {
|
|
45
|
+
init_ws_registry();
|
|
46
|
+
WS_CONNECTING = 0;
|
|
47
|
+
WS_OPEN = 1;
|
|
48
|
+
WS_CLOSED = 3;
|
|
49
|
+
WS_CLOSE_CODE_GOING_AWAY = 1001;
|
|
50
|
+
WS_CLOSE_CODE_INVALID_FRAME_PAYLOAD_DATA = 1007;
|
|
51
|
+
WS_CLOSE_CODE_POLICY_VIOLATION = 1008;
|
|
52
|
+
WS_CLOSE_CODE_MESSAGE_TOO_BIG = 1009;
|
|
53
|
+
WS_CLOSE_CODE_INTERNAL_ERROR = 1011;
|
|
54
|
+
WS_CLOSE_CODE_TRY_AGAIN_LATER = 1013;
|
|
55
|
+
MAX_PENDING_MESSAGES = 100;
|
|
56
|
+
MAX_PENDING_OUTBOUND_MESSAGES = 1e3;
|
|
57
|
+
MAX_SOCKET_BUFFERED_AMOUNT = 1048576;
|
|
58
|
+
OUTBOUND_BATCH_SIZE = 50;
|
|
59
|
+
OUTBOUND_RETRY_DELAY_MS = 5;
|
|
60
|
+
WebSocketEnvelopeSchema = z$1.object({
|
|
61
|
+
event: z$1.string(),
|
|
62
|
+
data: z$1.unknown()
|
|
63
|
+
});
|
|
64
|
+
WebSocketRuntime = class {
|
|
65
|
+
registry;
|
|
66
|
+
constructor(options = {}) {
|
|
67
|
+
const registryOptions = {
|
|
68
|
+
nodeId: options.nodeId,
|
|
69
|
+
presenceStore: options.presenceStore,
|
|
70
|
+
clusterBus: options.clusterBus
|
|
71
|
+
};
|
|
72
|
+
this.registry = new WebSocketRegistry(registryOptions);
|
|
73
|
+
}
|
|
74
|
+
registerConnection(socket, options) {
|
|
75
|
+
return new WebSocketConnectionImpl(socket, {
|
|
76
|
+
...options,
|
|
77
|
+
registry: this.registry
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
activateConnection(connectionId) {
|
|
81
|
+
this.registry.activate(connectionId);
|
|
82
|
+
}
|
|
83
|
+
broadcast(event, data, namespace) {
|
|
84
|
+
this.registry.broadcast(event, data, namespace);
|
|
85
|
+
}
|
|
86
|
+
publishToRoom(roomId, event, data, namespace) {
|
|
87
|
+
this.registry.publishToRoom(roomId, event, data, namespace);
|
|
88
|
+
}
|
|
89
|
+
publishToUser(userId, event, data, namespace) {
|
|
90
|
+
this.registry.publishToUser(userId, event, data, namespace);
|
|
91
|
+
}
|
|
92
|
+
publishToAudience(audience, event, data) {
|
|
93
|
+
this.registry.publishToAudience(audience, event, data);
|
|
94
|
+
}
|
|
95
|
+
async shutdown(code = WS_CLOSE_CODE_GOING_AWAY, reason = "Server shutting down") {
|
|
96
|
+
await this.registry.shutdown(code, reason);
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
WebSocketConnectionImpl = class {
|
|
100
|
+
id = randomUUID();
|
|
101
|
+
transport = "ws";
|
|
102
|
+
namespace;
|
|
103
|
+
closeCallbacks = [];
|
|
104
|
+
messageHandlers = new Map();
|
|
105
|
+
pendingMessages = [];
|
|
106
|
+
pendingOutboundMessages = [];
|
|
107
|
+
closePromise;
|
|
108
|
+
resolveClosePromise;
|
|
109
|
+
heartbeatMs;
|
|
110
|
+
maxPayload;
|
|
111
|
+
eventSchemasIn;
|
|
112
|
+
eventSchemasOut;
|
|
113
|
+
closedInternal = false;
|
|
114
|
+
closeStarted = false;
|
|
115
|
+
awaitingPong = false;
|
|
116
|
+
heartbeatTimer = null;
|
|
117
|
+
messageQueue = Promise.resolve();
|
|
118
|
+
outboundFlushScheduled = false;
|
|
119
|
+
constructor(socket, options) {
|
|
120
|
+
this.socket = socket;
|
|
121
|
+
this.options = options;
|
|
122
|
+
this.namespace = options.namespace ?? "default";
|
|
123
|
+
this.heartbeatMs = options.heartbeat ?? 3e4;
|
|
124
|
+
this.maxPayload = options.maxPayload;
|
|
125
|
+
this.eventSchemasIn = options.inEvents.shape;
|
|
126
|
+
this.eventSchemasOut = options.outEvents.shape;
|
|
127
|
+
let resolveClosePromise;
|
|
128
|
+
this.closePromise = new Promise((resolve) => {
|
|
129
|
+
resolveClosePromise = resolve;
|
|
130
|
+
});
|
|
131
|
+
this.resolveClosePromise = resolveClosePromise;
|
|
132
|
+
this.options.registry.register(this, options.active ?? true);
|
|
133
|
+
this.socket.on("message", this.handleMessage);
|
|
134
|
+
this.socket.on("close", this.handleClose);
|
|
135
|
+
this.socket.on("error", this.handleError);
|
|
136
|
+
this.socket.on("pong", this.handlePong);
|
|
137
|
+
this.startHeartbeat();
|
|
138
|
+
}
|
|
139
|
+
get closed() {
|
|
140
|
+
return this.closedInternal;
|
|
141
|
+
}
|
|
142
|
+
onClose(callback) {
|
|
143
|
+
this.closeCallbacks.push(callback);
|
|
144
|
+
}
|
|
145
|
+
onMessage(event, handler) {
|
|
146
|
+
const eventKey = String(event);
|
|
147
|
+
const handlers = this.messageHandlers.get(eventKey) ?? [];
|
|
148
|
+
handlers.push(handler);
|
|
149
|
+
this.messageHandlers.set(eventKey, handlers);
|
|
150
|
+
this.flushPendingMessages(eventKey);
|
|
151
|
+
}
|
|
152
|
+
publish(event, data) {
|
|
153
|
+
this.publishValidated(String(event), data);
|
|
154
|
+
}
|
|
155
|
+
publishUntyped(event, data) {
|
|
156
|
+
this.publishValidated(event, data);
|
|
157
|
+
}
|
|
158
|
+
waitForClose() {
|
|
159
|
+
return this.closePromise;
|
|
160
|
+
}
|
|
161
|
+
join(roomId) {
|
|
162
|
+
this.options.registry.join(this.id, roomId);
|
|
163
|
+
}
|
|
164
|
+
leave(roomId) {
|
|
165
|
+
this.options.registry.leave(this.id, roomId);
|
|
166
|
+
}
|
|
167
|
+
setUserId(userId) {
|
|
168
|
+
this.options.registry.setUserId(this.id, userId);
|
|
169
|
+
}
|
|
170
|
+
clearUserId() {
|
|
171
|
+
this.options.registry.clearUserId(this.id);
|
|
172
|
+
}
|
|
173
|
+
close(code, reason) {
|
|
174
|
+
if (this.closedInternal || this.closeStarted || this.socket.readyState === WS_CLOSED) {
|
|
175
|
+
return;
|
|
176
|
+
}
|
|
177
|
+
this.closeStarted = true;
|
|
178
|
+
try {
|
|
179
|
+
this.closeTransport(code, reason);
|
|
180
|
+
} finally {
|
|
181
|
+
this.markClosed();
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
handleMessage = (raw) => {
|
|
185
|
+
this.enqueueMessageTask(async () => {
|
|
186
|
+
const text = normalizeMessage(raw);
|
|
187
|
+
if (this.maxPayload !== undefined && Buffer.byteLength(text) > this.maxPayload) {
|
|
188
|
+
this.close(WS_CLOSE_CODE_MESSAGE_TOO_BIG, "Message too large");
|
|
189
|
+
return;
|
|
190
|
+
}
|
|
191
|
+
const parsedEnvelope = safeParseEnvelope(text);
|
|
192
|
+
if (!parsedEnvelope) {
|
|
193
|
+
this.close(WS_CLOSE_CODE_INVALID_FRAME_PAYLOAD_DATA, "Invalid message payload");
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
this.options.registry.touch(this.id);
|
|
197
|
+
await this.dispatchEnvelope(parsedEnvelope);
|
|
198
|
+
});
|
|
199
|
+
};
|
|
200
|
+
handleClose = () => {
|
|
201
|
+
this.markClosed();
|
|
202
|
+
};
|
|
203
|
+
handleError = () => {
|
|
204
|
+
this.close(WS_CLOSE_CODE_INTERNAL_ERROR, "WebSocket transport error");
|
|
205
|
+
};
|
|
206
|
+
handlePong = () => {
|
|
207
|
+
this.awaitingPong = false;
|
|
208
|
+
this.options.registry.touch(this.id);
|
|
209
|
+
};
|
|
210
|
+
async dispatchEnvelope(envelope) {
|
|
211
|
+
const handlers = this.messageHandlers.get(envelope.event);
|
|
212
|
+
const schema = this.eventSchemasIn[envelope.event];
|
|
213
|
+
if (!schema) {
|
|
214
|
+
this.close(WS_CLOSE_CODE_POLICY_VIOLATION, "Unknown event");
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
const parsed = schema.safeParse(envelope.data);
|
|
218
|
+
if (!parsed.success) {
|
|
219
|
+
this.close(WS_CLOSE_CODE_INVALID_FRAME_PAYLOAD_DATA, "Invalid event data");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
if (!handlers || handlers.length === 0) {
|
|
223
|
+
if (this.pendingMessages.length >= MAX_PENDING_MESSAGES) {
|
|
224
|
+
this.pendingMessages.shift();
|
|
225
|
+
}
|
|
226
|
+
this.pendingMessages.push(envelope);
|
|
227
|
+
return;
|
|
228
|
+
}
|
|
229
|
+
for (const handler of handlers) {
|
|
230
|
+
await handler(parsed.data);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
flushPendingMessages(event) {
|
|
234
|
+
const remaining = [];
|
|
235
|
+
const toFlush = [];
|
|
236
|
+
for (const message of this.pendingMessages) {
|
|
237
|
+
if (message.event !== event) {
|
|
238
|
+
remaining.push(message);
|
|
239
|
+
continue;
|
|
240
|
+
}
|
|
241
|
+
toFlush.push(message);
|
|
242
|
+
}
|
|
243
|
+
this.pendingMessages.length = 0;
|
|
244
|
+
this.pendingMessages.push(...remaining);
|
|
245
|
+
for (const message of toFlush) {
|
|
246
|
+
this.enqueueMessageTask(async () => {
|
|
247
|
+
await this.dispatchEnvelope(message);
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
publishValidated(event, data) {
|
|
252
|
+
const schema = this.eventSchemasOut[event];
|
|
253
|
+
if (!schema) {
|
|
254
|
+
throw new Error(`Unknown websocket event: ${event}`);
|
|
255
|
+
}
|
|
256
|
+
const parsed = schema.safeParse(data);
|
|
257
|
+
if (!parsed.success) {
|
|
258
|
+
throw new Error(`Invalid websocket event payload: ${event}`);
|
|
259
|
+
}
|
|
260
|
+
if (this.closedInternal || this.socket.readyState !== WS_OPEN) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
this.enqueueOutboundMessage(JSON.stringify({
|
|
264
|
+
event,
|
|
265
|
+
data: parsed.data
|
|
266
|
+
}));
|
|
267
|
+
}
|
|
268
|
+
markClosed() {
|
|
269
|
+
if (this.closedInternal) {
|
|
270
|
+
return;
|
|
271
|
+
}
|
|
272
|
+
this.closedInternal = true;
|
|
273
|
+
this.closeStarted = false;
|
|
274
|
+
this.stopHeartbeat();
|
|
275
|
+
this.socket.off("message", this.handleMessage);
|
|
276
|
+
this.socket.off("close", this.handleClose);
|
|
277
|
+
this.socket.off("error", this.handleError);
|
|
278
|
+
this.socket.off("pong", this.handlePong);
|
|
279
|
+
this.awaitingPong = false;
|
|
280
|
+
this.pendingMessages.length = 0;
|
|
281
|
+
this.pendingOutboundMessages.length = 0;
|
|
282
|
+
this.options.registry.unregister(this.id);
|
|
283
|
+
for (const callback of this.closeCallbacks.splice(0)) {
|
|
284
|
+
try {
|
|
285
|
+
const result = callback();
|
|
286
|
+
if (isPromiseLike(result)) {
|
|
287
|
+
void result.catch(() => {});
|
|
288
|
+
}
|
|
289
|
+
} catch {}
|
|
290
|
+
}
|
|
291
|
+
this.resolveClosePromise();
|
|
292
|
+
}
|
|
293
|
+
startHeartbeat() {
|
|
294
|
+
if (this.heartbeatMs <= 0) {
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
this.heartbeatTimer = setInterval(() => {
|
|
298
|
+
if (this.closedInternal || this.socket.readyState !== WS_OPEN) {
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
if (this.awaitingPong) {
|
|
302
|
+
this.close(WS_CLOSE_CODE_GOING_AWAY, "Heartbeat timeout");
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
this.awaitingPong = true;
|
|
306
|
+
this.socket.ping();
|
|
307
|
+
}, this.heartbeatMs);
|
|
308
|
+
}
|
|
309
|
+
stopHeartbeat() {
|
|
310
|
+
if (!this.heartbeatTimer) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
clearInterval(this.heartbeatTimer);
|
|
314
|
+
this.heartbeatTimer = null;
|
|
315
|
+
}
|
|
316
|
+
closeTransport(code, reason) {
|
|
317
|
+
try {
|
|
318
|
+
if (this.socket.readyState === WS_OPEN || this.socket.readyState === WS_CONNECTING) {
|
|
319
|
+
this.socket.close(code, truncateCloseReason(reason));
|
|
320
|
+
return;
|
|
321
|
+
}
|
|
322
|
+
this.socket.terminate();
|
|
323
|
+
} catch {
|
|
324
|
+
try {
|
|
325
|
+
this.socket.terminate();
|
|
326
|
+
} catch {}
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
enqueueMessageTask(task) {
|
|
330
|
+
this.messageQueue = this.messageQueue.then(async () => {
|
|
331
|
+
if (this.closedInternal) {
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
await task();
|
|
335
|
+
}).catch(() => {
|
|
336
|
+
this.close(WS_CLOSE_CODE_INTERNAL_ERROR, "Message handling failed");
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
enqueueOutboundMessage(payload) {
|
|
340
|
+
if (this.pendingOutboundMessages.length >= MAX_PENDING_OUTBOUND_MESSAGES) {
|
|
341
|
+
this.close(WS_CLOSE_CODE_TRY_AGAIN_LATER, "WebSocket backpressure overflow");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
this.pendingOutboundMessages.push(payload);
|
|
345
|
+
this.scheduleOutboundFlush();
|
|
346
|
+
}
|
|
347
|
+
scheduleOutboundFlush(delayMs = 0) {
|
|
348
|
+
if (this.outboundFlushScheduled || this.closedInternal) {
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
this.outboundFlushScheduled = true;
|
|
352
|
+
const flush = () => {
|
|
353
|
+
this.outboundFlushScheduled = false;
|
|
354
|
+
this.flushOutboundMessages();
|
|
355
|
+
};
|
|
356
|
+
if (delayMs > 0) {
|
|
357
|
+
setTimeout(flush, delayMs);
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
setImmediate(flush);
|
|
361
|
+
}
|
|
362
|
+
flushOutboundMessages() {
|
|
363
|
+
if (this.closedInternal || this.socket.readyState !== WS_OPEN) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
if (this.socket.bufferedAmount > MAX_SOCKET_BUFFERED_AMOUNT) {
|
|
367
|
+
this.scheduleOutboundFlush(OUTBOUND_RETRY_DELAY_MS);
|
|
368
|
+
return;
|
|
369
|
+
}
|
|
370
|
+
let sent = 0;
|
|
371
|
+
while (sent < OUTBOUND_BATCH_SIZE && this.pendingOutboundMessages.length > 0 && this.socket.readyState === WS_OPEN) {
|
|
372
|
+
const payload = this.pendingOutboundMessages.shift();
|
|
373
|
+
if (!payload) {
|
|
374
|
+
break;
|
|
375
|
+
}
|
|
376
|
+
try {
|
|
377
|
+
this.socket.send(payload);
|
|
378
|
+
} catch {
|
|
379
|
+
this.close(WS_CLOSE_CODE_INTERNAL_ERROR, "Outbound publish failed");
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
sent += 1;
|
|
383
|
+
if (this.socket.bufferedAmount > MAX_SOCKET_BUFFERED_AMOUNT) {
|
|
384
|
+
break;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
if (this.pendingOutboundMessages.length > 0) {
|
|
388
|
+
this.scheduleOutboundFlush(this.socket.bufferedAmount > MAX_SOCKET_BUFFERED_AMOUNT ? OUTBOUND_RETRY_DELAY_MS : 0);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
}));
|
|
393
|
+
|
|
394
|
+
//#endregion
|
|
395
|
+
init_ws();
|
|
396
|
+
export { WebSocketRuntime, createWebSocketRuntime, init_ws };
|
|
397
|
+
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid3MuanMiLCJuYW1lcyI6WyJ6IiwicmVnaXN0cnlPcHRpb25zOiBXZWJTb2NrZXRSZWdpc3RyeU9wdGlvbnMiLCJzb2NrZXQ6IFdlYlNvY2tldCIsIm9wdGlvbnM6IFdlYlNvY2tldENvbm5lY3Rpb25PcHRpb25zPFRPdXRTY2hlbWEsIFRJblNjaGVtYT4iLCJyZXNvbHZlQ2xvc2VQcm9taXNlITogKCkgPT4gdm9pZCIsInJlbWFpbmluZzogUGFyc2VkRW52ZWxvcGVbXSIsInRvRmx1c2g6IFBhcnNlZEVudmVsb3BlW10iXSwic291cmNlcyI6WyIuLi8uLi9zcmMvc3RyZWFtL3dzLnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHJhbmRvbVVVSUQgfSBmcm9tIFwibm9kZTpjcnlwdG9cIjtcblxuaW1wb3J0IHsgdHlwZSBXZWJTb2NrZXQgfSBmcm9tIFwid3NcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmltcG9ydCB7IHR5cGUgV2ViU29ja2V0QXVkaWVuY2UgfSBmcm9tIFwiLi93cy1hdWRpZW5jZVwiO1xuaW1wb3J0IHsgdHlwZSBXZWJTb2NrZXRDbHVzdGVyQnVzIH0gZnJvbSBcIi4vd3MtY2x1c3Rlci1idXNcIjtcbmltcG9ydCB7IHR5cGUgV2ViU29ja2V0UHJlc2VuY2VTdG9yZSB9IGZyb20gXCIuL3dzLXByZXNlbmNlLXN0b3JlXCI7XG5pbXBvcnQge1xuICB0eXBlIE1hbmFnZWRXZWJTb2NrZXRDb25uZWN0aW9uLFxuICBXZWJTb2NrZXRSZWdpc3RyeSxcbiAgdHlwZSBXZWJTb2NrZXRSZWdpc3RyeU9wdGlvbnMsXG4gIHR5cGUgV2ViU29ja2V0Um9vbUlkLFxuICB0eXBlIFdlYlNvY2tldFVzZXJJZCxcbn0gZnJvbSBcIi4vd3MtcmVnaXN0cnlcIjtcblxuLy8gdHJhbnNwb3J0LWxldmVsIOyDgeyImOyZgCBxdWV1ZSB0aHJlc2hvbGTrpbwg7ZWcIO2MjOydvOyXkCDrqqjslYQgbGlmZWN5Y2xlL2JhY2twcmVzc3VyZSDsoJXssYXsnYQg7KSR7JWZ7ZmU7ZWoXG5jb25zdCBXU19DT05ORUNUSU5HID0gMDtcbmNvbnN0IFdTX09QRU4gPSAxO1xuY29uc3QgV1NfQ0xPU0VEID0gMztcbi8vIFJGQyA2NDU1IGNsb3NlIGNvZGVzIHVzZWQgYnkgU29uYW11J3MgV2ViU29ja2V0IHJ1bnRpbWUuXG5jb25zdCBXU19DTE9TRV9DT0RFX0dPSU5HX0FXQVkgPSAxMDAxO1xuY29uc3QgV1NfQ0xPU0VfQ09ERV9JTlZBTElEX0ZSQU1FX1BBWUxPQURfREFUQSA9IDEwMDc7XG5jb25zdCBXU19DTE9TRV9DT0RFX1BPTElDWV9WSU9MQVRJT04gPSAxMDA4O1xuY29uc3QgV1NfQ0xPU0VfQ09ERV9NRVNTQUdFX1RPT19CSUcgPSAxMDA5O1xuY29uc3QgV1NfQ0xPU0VfQ09ERV9JTlRFUk5BTF9FUlJPUiA9IDEwMTE7XG5jb25zdCBXU19DTE9TRV9DT0RFX1RSWV9BR0FJTl9MQVRFUiA9IDEwMTM7XG5jb25zdCBNQVhfUEVORElOR19NRVNTQUdFUyA9IDEwMDtcbmNvbnN0IE1BWF9QRU5ESU5HX09VVEJPVU5EX01FU1NBR0VTID0gMV8wMDA7XG5jb25zdCBNQVhfU09DS0VUX0JVRkZFUkVEX0FNT1VOVCA9IDFfMDQ4XzU3NjtcbmNvbnN0IE9VVEJPVU5EX0JBVENIX1NJWkUgPSA1MDtcbmNvbnN0IE9VVEJPVU5EX1JFVFJZX0RFTEFZX01TID0gNTtcblxuLy8gZW52ZWxvcGXsnYQgYHtldmVudCwgZGF0YX1gIO2Yle2DnOuhnCDqs6DsoJXtlbQgc2VydmVyIGhhbmRsZXLsmYAgZ2VuZXJhdGVkIGNsaWVudOqwgCDqsJnsnYAgZnJhbWluZyBjb250cmFjdOulvCDsk7Dqsowg7ZWoXG5jb25zdCBXZWJTb2NrZXRFbnZlbG9wZVNjaGVtYSA9IHoub2JqZWN0KHtcbiAgZXZlbnQ6IHouc3RyaW5nKCksXG4gIGRhdGE6IHoudW5rbm93bigpLFxufSk7XG5cbnR5cGUgTWVzc2FnZUhhbmRsZXI8VD4gPSAoZGF0YTogVCkgPT4gdm9pZCB8IFByb21pc2U8dm9pZD47XG50eXBlIENsb3NlSGFuZGxlciA9ICgpID0+IHZvaWQgfCBQcm9taXNlPHZvaWQ+O1xuXG5leHBvcnQgdHlwZSBXZWJTb2NrZXRFdmVudE1hcCA9IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXG50eXBlIEluZmVyV2ViU29ja2V0RXZlbnRNYXA8VFNjaGVtYSBleHRlbmRzIHouWm9kUmF3U2hhcGU+ID0gei5pbmZlcjx6LlpvZE9iamVjdDxUU2NoZW1hPj47XG5cbmV4cG9ydCB0eXBlIFdlYlNvY2tldE91dEV2ZW50czxUT3V0IGV4dGVuZHMgV2ViU29ja2V0RXZlbnRNYXAgPSBXZWJTb2NrZXRFdmVudE1hcD4gPSBUT3V0O1xuXG5leHBvcnQgdHlwZSBXZWJTb2NrZXRJbkV2ZW50czxUSW4gZXh0ZW5kcyBXZWJTb2NrZXRFdmVudE1hcCA9IFdlYlNvY2tldEV2ZW50TWFwPiA9IFRJbjtcblxuZXhwb3J0IGludGVyZmFjZSBXZWJTb2NrZXRDb25uZWN0aW9uPFxuICBUT3V0IGV4dGVuZHMgV2ViU29ja2V0RXZlbnRNYXAgPSBXZWJTb2NrZXRFdmVudE1hcCxcbiAgVEluIGV4dGVuZHMgV2ViU29ja2V0RXZlbnRNYXAgPSBXZWJTb2NrZXRFdmVudE1hcCxcbj4gZXh0ZW5kcyBNYW5hZ2VkV2ViU29ja2V0Q29ubmVjdGlvbiB7XG4gIHRyYW5zcG9ydDogXCJ3c1wiO1xuICBvbkNsb3NlKGNhbGxiYWNrOiBDbG9zZUhhbmRsZXIpOiB2b2lkO1xuICBvbk1lc3NhZ2U8SyBleHRlbmRzIGtleW9mIFdlYlNvY2tldEluRXZlbnRzPFRJbj4+KFxuICAgIGV2ZW50OiBLLFxuICAgIGhhbmRsZXI6IE1lc3NhZ2VIYW5kbGVyPFdlYlNvY2tldEluRXZlbnRzPFRJbj5bS10+LFxuICApOiB2b2lkO1xuICBwdWJsaXNoPEsgZXh0ZW5kcyBrZXlvZiBXZWJTb2NrZXRPdXRFdmVudHM8VE91dD4+KFxuICAgIGV2ZW50OiBLLFxuICAgIGRhdGE6IFdlYlNvY2tldE91dEV2ZW50czxUT3V0PltLXSxcbiAgKTogdm9pZDtcbiAgd2FpdEZvckNsb3NlKCk6IFByb21pc2U8dm9pZD47XG4gIGpvaW4ocm9vbUlkOiBXZWJTb2NrZXRSb29tSWQpOiB2b2lkO1xuICBsZWF2ZShyb29tSWQ6IFdlYlNvY2tldFJvb21JZCk6IHZvaWQ7XG4gIHNldFVzZXJJZCh1c2VySWQ6IFdlYlNvY2tldFVzZXJJZCk6IHZvaWQ7XG4gIGNsZWFyVXNlcklkKCk6IHZvaWQ7XG59XG5cbmV4cG9ydCB0eXBlIEFueVdlYlNvY2tldENvbm5lY3Rpb24gPSBXZWJTb2NrZXRDb25uZWN0aW9uPFdlYlNvY2tldEV2ZW50TWFwLCBXZWJTb2NrZXRFdmVudE1hcD47XG5cbnR5cGUgUGFyc2VkRW52ZWxvcGUgPSB6LmluZmVyPHR5cGVvZiBXZWJTb2NrZXRFbnZlbG9wZVNjaGVtYT47XG5cbnR5cGUgV2ViU29ja2V0Q29ubmVjdGlvbk9wdGlvbnM8VE91dCBleHRlbmRzIHouWm9kUmF3U2hhcGUsIFRJbiBleHRlbmRzIHouWm9kUmF3U2hhcGU+ID0ge1xuICBuYW1lc3BhY2U/OiBzdHJpbmc7XG4gIGhlYXJ0YmVhdD86IG51bWJlcjtcbiAgbWF4UGF5bG9hZD86IG51bWJlcjtcbiAgYWN0aXZlPzogYm9vbGVhbjtcbiAgb3V0RXZlbnRzOiB6LlpvZE9iamVjdDxUT3V0PjtcbiAgaW5FdmVudHM6IHouWm9kT2JqZWN0PFRJbj47XG4gIHJlZ2lzdHJ5OiBXZWJTb2NrZXRSZWdpc3RyeTtcbn07XG5cbmV4cG9ydCB0eXBlIFdlYlNvY2tldFJ1bnRpbWVPcHRpb25zID0ge1xuICBub2RlSWQ/OiBzdHJpbmc7XG4gIHByZXNlbmNlU3RvcmU/OiBXZWJTb2NrZXRQcmVzZW5jZVN0b3JlO1xuICBjbHVzdGVyQnVzPzogV2ViU29ja2V0Q2x1c3RlckJ1cztcbn07XG5cbi8vIHJlZ2lzdHJ566W8IOyGjOycoO2VmOqzoCBjb25uZWN0aW9uIOyDneyEsS9zaHV0ZG93buydhCDri7Tri7ntlaguIFNvbmFtdSDslaDtlIzrpqzsvIDsnbTshZgg7IiY66qF7KO86riw7JmAIOqwmeydtCDsm4Dsp4HsnbTrj4TroZ0g7ISk6rOE7ZWoXG5leHBvcnQgY2xhc3MgV2ViU29ja2V0UnVudGltZSB7XG4gIHJlYWRvbmx5IHJlZ2lzdHJ5OiBXZWJTb2NrZXRSZWdpc3RyeTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBXZWJTb2NrZXRSdW50aW1lT3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3QgcmVnaXN0cnlPcHRpb25zOiBXZWJTb2NrZXRSZWdpc3RyeU9wdGlvbnMgPSB7XG4gICAgICBub2RlSWQ6IG9wdGlvbnMubm9kZUlkLFxuICAgICAgcHJlc2VuY2VTdG9yZTogb3B0aW9ucy5wcmVzZW5jZVN0b3JlLFxuICAgICAgY2x1c3RlckJ1czogb3B0aW9ucy5jbHVzdGVyQnVzLFxuICAgIH07XG4gICAgdGhpcy5yZWdpc3RyeSA9IG5ldyBXZWJTb2NrZXRSZWdpc3RyeShyZWdpc3RyeU9wdGlvbnMpO1xuICB9XG5cbiAgcmVnaXN0ZXJDb25uZWN0aW9uPFRPdXRTY2hlbWEgZXh0ZW5kcyB6LlpvZFJhd1NoYXBlLCBUSW5TY2hlbWEgZXh0ZW5kcyB6LlpvZFJhd1NoYXBlPihcbiAgICBzb2NrZXQ6IFdlYlNvY2tldCxcbiAgICBvcHRpb25zOiBPbWl0PFdlYlNvY2tldENvbm5lY3Rpb25PcHRpb25zPFRPdXRTY2hlbWEsIFRJblNjaGVtYT4sIFwicmVnaXN0cnlcIj4sXG4gICk6IFdlYlNvY2tldENvbm5lY3Rpb248SW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUT3V0U2NoZW1hPiwgSW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUSW5TY2hlbWE+PiB7XG4gICAgcmV0dXJuIG5ldyBXZWJTb2NrZXRDb25uZWN0aW9uSW1wbChzb2NrZXQsIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICByZWdpc3RyeTogdGhpcy5yZWdpc3RyeSxcbiAgICB9KTtcbiAgfVxuXG4gIGFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucmVnaXN0cnkuYWN0aXZhdGUoY29ubmVjdGlvbklkKTtcbiAgfVxuXG4gIGJyb2FkY2FzdChldmVudDogc3RyaW5nLCBkYXRhOiB1bmtub3duLCBuYW1lc3BhY2U/OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lzdHJ5LmJyb2FkY2FzdChldmVudCwgZGF0YSwgbmFtZXNwYWNlKTtcbiAgfVxuXG4gIHB1Ymxpc2hUb1Jvb20ocm9vbUlkOiBXZWJTb2NrZXRSb29tSWQsIGV2ZW50OiBzdHJpbmcsIGRhdGE6IHVua25vd24sIG5hbWVzcGFjZT86IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMucmVnaXN0cnkucHVibGlzaFRvUm9vbShyb29tSWQsIGV2ZW50LCBkYXRhLCBuYW1lc3BhY2UpO1xuICB9XG5cbiAgcHVibGlzaFRvVXNlcih1c2VySWQ6IFdlYlNvY2tldFVzZXJJZCwgZXZlbnQ6IHN0cmluZywgZGF0YTogdW5rbm93biwgbmFtZXNwYWNlPzogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5yZWdpc3RyeS5wdWJsaXNoVG9Vc2VyKHVzZXJJZCwgZXZlbnQsIGRhdGEsIG5hbWVzcGFjZSk7XG4gIH1cblxuICBwdWJsaXNoVG9BdWRpZW5jZShhdWRpZW5jZTogV2ViU29ja2V0QXVkaWVuY2UsIGV2ZW50OiBzdHJpbmcsIGRhdGE6IHVua25vd24pOiB2b2lkIHtcbiAgICB0aGlzLnJlZ2lzdHJ5LnB1Ymxpc2hUb0F1ZGllbmNlKGF1ZGllbmNlLCBldmVudCwgZGF0YSk7XG4gIH1cblxuICAvLyDtlITroZzshLjsiqQg7KKF66OMIOyLnCDsgrTslYTsnojripQg7Jew6rKw7J20IOuCqOyngCDslYrrj4TroZ0gcmVnaXN0cnnrpbwg7Iic7ZqM7ZW0IOydvOq0hCDsooXro4ztlahcbiAgYXN5bmMgc2h1dGRvd24oXG4gICAgY29kZTogbnVtYmVyID0gV1NfQ0xPU0VfQ09ERV9HT0lOR19BV0FZLFxuICAgIHJlYXNvbiA9IFwiU2VydmVyIHNodXR0aW5nIGRvd25cIixcbiAgKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5yZWdpc3RyeS5zaHV0ZG93bihjb2RlLCByZWFzb24pO1xuICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVXZWJTb2NrZXRSdW50aW1lKG9wdGlvbnM6IFdlYlNvY2tldFJ1bnRpbWVPcHRpb25zID0ge30pOiBXZWJTb2NrZXRSdW50aW1lIHtcbiAgcmV0dXJuIG5ldyBXZWJTb2NrZXRSdW50aW1lKG9wdGlvbnMpO1xufVxuXG5jbGFzcyBXZWJTb2NrZXRDb25uZWN0aW9uSW1wbDxcbiAgVE91dFNjaGVtYSBleHRlbmRzIHouWm9kUmF3U2hhcGUsXG4gIFRJblNjaGVtYSBleHRlbmRzIHouWm9kUmF3U2hhcGUsXG4+IGltcGxlbWVudHMgV2ViU29ja2V0Q29ubmVjdGlvbjxcbiAgSW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUT3V0U2NoZW1hPixcbiAgSW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUSW5TY2hlbWE+XG4+IHtcbiAgcmVhZG9ubHkgaWQgPSByYW5kb21VVUlEKCk7XG4gIHJlYWRvbmx5IHRyYW5zcG9ydCA9IFwid3NcIjtcbiAgcmVhZG9ubHkgbmFtZXNwYWNlOiBzdHJpbmc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjbG9zZUNhbGxiYWNrczogQ2xvc2VIYW5kbGVyW10gPSBbXTtcbiAgcHJpdmF0ZSByZWFkb25seSBtZXNzYWdlSGFuZGxlcnMgPSBuZXcgTWFwPHN0cmluZywgQXJyYXk8TWVzc2FnZUhhbmRsZXI8dW5rbm93bj4+PigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdNZXNzYWdlczogUGFyc2VkRW52ZWxvcGVbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdPdXRib3VuZE1lc3NhZ2VzOiBzdHJpbmdbXSA9IFtdO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsb3NlUHJvbWlzZTogUHJvbWlzZTx2b2lkPjtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlQ2xvc2VQcm9taXNlOiAoKSA9PiB2b2lkO1xuICBwcml2YXRlIHJlYWRvbmx5IGhlYXJ0YmVhdE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4UGF5bG9hZD86IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBldmVudFNjaGVtYXNJbjogUmVjb3JkPHN0cmluZywgei5ab2RUeXBlQW55PjtcbiAgcHJpdmF0ZSByZWFkb25seSBldmVudFNjaGVtYXNPdXQ6IFJlY29yZDxzdHJpbmcsIHouWm9kVHlwZUFueT47XG5cbiAgcHJpdmF0ZSBjbG9zZWRJbnRlcm5hbCA9IGZhbHNlO1xuICBwcml2YXRlIGNsb3NlU3RhcnRlZCA9IGZhbHNlO1xuICBwcml2YXRlIGF3YWl0aW5nUG9uZyA9IGZhbHNlO1xuICBwcml2YXRlIGhlYXJ0YmVhdFRpbWVyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBtZXNzYWdlUXVldWU6IFByb21pc2U8dm9pZD4gPSBQcm9taXNlLnJlc29sdmUoKTtcbiAgcHJpdmF0ZSBvdXRib3VuZEZsdXNoU2NoZWR1bGVkID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBzb2NrZXQ6IFdlYlNvY2tldCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IG9wdGlvbnM6IFdlYlNvY2tldENvbm5lY3Rpb25PcHRpb25zPFRPdXRTY2hlbWEsIFRJblNjaGVtYT4sXG4gICkge1xuICAgIHRoaXMubmFtZXNwYWNlID0gb3B0aW9ucy5uYW1lc3BhY2UgPz8gXCJkZWZhdWx0XCI7XG4gICAgdGhpcy5oZWFydGJlYXRNcyA9IG9wdGlvbnMuaGVhcnRiZWF0ID8/IDMwMDAwO1xuICAgIHRoaXMubWF4UGF5bG9hZCA9IG9wdGlvbnMubWF4UGF5bG9hZDtcbiAgICB0aGlzLmV2ZW50U2NoZW1hc0luID0gb3B0aW9ucy5pbkV2ZW50cy5zaGFwZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHouWm9kVHlwZUFueT47XG4gICAgdGhpcy5ldmVudFNjaGVtYXNPdXQgPSBvcHRpb25zLm91dEV2ZW50cy5zaGFwZSBhcyB1bmtub3duIGFzIFJlY29yZDxzdHJpbmcsIHouWm9kVHlwZUFueT47XG5cbiAgICBsZXQgcmVzb2x2ZUNsb3NlUHJvbWlzZSE6ICgpID0+IHZvaWQ7XG4gICAgdGhpcy5jbG9zZVByb21pc2UgPSBuZXcgUHJvbWlzZTx2b2lkPigocmVzb2x2ZSkgPT4ge1xuICAgICAgcmVzb2x2ZUNsb3NlUHJvbWlzZSA9IHJlc29sdmU7XG4gICAgfSk7XG4gICAgdGhpcy5yZXNvbHZlQ2xvc2VQcm9taXNlID0gcmVzb2x2ZUNsb3NlUHJvbWlzZTtcblxuICAgIHRoaXMub3B0aW9ucy5yZWdpc3RyeS5yZWdpc3Rlcih0aGlzLCBvcHRpb25zLmFjdGl2ZSA/PyB0cnVlKTtcbiAgICB0aGlzLnNvY2tldC5vbihcIm1lc3NhZ2VcIiwgdGhpcy5oYW5kbGVNZXNzYWdlKTtcbiAgICB0aGlzLnNvY2tldC5vbihcImNsb3NlXCIsIHRoaXMuaGFuZGxlQ2xvc2UpO1xuICAgIHRoaXMuc29ja2V0Lm9uKFwiZXJyb3JcIiwgdGhpcy5oYW5kbGVFcnJvcik7XG4gICAgdGhpcy5zb2NrZXQub24oXCJwb25nXCIsIHRoaXMuaGFuZGxlUG9uZyk7XG4gICAgdGhpcy5zdGFydEhlYXJ0YmVhdCgpO1xuICB9XG5cbiAgZ2V0IGNsb3NlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jbG9zZWRJbnRlcm5hbDtcbiAgfVxuXG4gIG9uQ2xvc2UoY2FsbGJhY2s6IENsb3NlSGFuZGxlcik6IHZvaWQge1xuICAgIHRoaXMuY2xvc2VDYWxsYmFja3MucHVzaChjYWxsYmFjayk7XG4gIH1cblxuICBvbk1lc3NhZ2U8SyBleHRlbmRzIGtleW9mIEluZmVyV2ViU29ja2V0RXZlbnRNYXA8VEluU2NoZW1hPj4oXG4gICAgZXZlbnQ6IEssXG4gICAgaGFuZGxlcjogTWVzc2FnZUhhbmRsZXI8SW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUSW5TY2hlbWE+W0tdPixcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgZXZlbnRLZXkgPSBTdHJpbmcoZXZlbnQpO1xuICAgIGNvbnN0IGhhbmRsZXJzID0gdGhpcy5tZXNzYWdlSGFuZGxlcnMuZ2V0KGV2ZW50S2V5KSA/PyBbXTtcbiAgICBoYW5kbGVycy5wdXNoKGhhbmRsZXIgYXMgTWVzc2FnZUhhbmRsZXI8dW5rbm93bj4pO1xuICAgIHRoaXMubWVzc2FnZUhhbmRsZXJzLnNldChldmVudEtleSwgaGFuZGxlcnMpO1xuICAgIHRoaXMuZmx1c2hQZW5kaW5nTWVzc2FnZXMoZXZlbnRLZXkpO1xuICB9XG5cbiAgcHVibGlzaDxLIGV4dGVuZHMga2V5b2YgSW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUT3V0U2NoZW1hPj4oXG4gICAgZXZlbnQ6IEssXG4gICAgZGF0YTogSW5mZXJXZWJTb2NrZXRFdmVudE1hcDxUT3V0U2NoZW1hPltLXSxcbiAgKTogdm9pZCB7XG4gICAgdGhpcy5wdWJsaXNoVmFsaWRhdGVkKFN0cmluZyhldmVudCksIGRhdGEpO1xuICB9XG5cbiAgcHVibGlzaFVudHlwZWQoZXZlbnQ6IHN0cmluZywgZGF0YTogdW5rbm93bik6IHZvaWQge1xuICAgIHRoaXMucHVibGlzaFZhbGlkYXRlZChldmVudCwgZGF0YSk7XG4gIH1cblxuICB3YWl0Rm9yQ2xvc2UoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgcmV0dXJuIHRoaXMuY2xvc2VQcm9taXNlO1xuICB9XG5cbiAgam9pbihyb29tSWQ6IFdlYlNvY2tldFJvb21JZCk6IHZvaWQge1xuICAgIHRoaXMub3B0aW9ucy5yZWdpc3RyeS5qb2luKHRoaXMuaWQsIHJvb21JZCk7XG4gIH1cblxuICBsZWF2ZShyb29tSWQ6IFdlYlNvY2tldFJvb21JZCk6IHZvaWQge1xuICAgIHRoaXMub3B0aW9ucy5yZWdpc3RyeS5sZWF2ZSh0aGlzLmlkLCByb29tSWQpO1xuICB9XG5cbiAgc2V0VXNlcklkKHVzZXJJZDogV2ViU29ja2V0VXNlcklkKTogdm9pZCB7XG4gICAgdGhpcy5vcHRpb25zLnJlZ2lzdHJ5LnNldFVzZXJJZCh0aGlzLmlkLCB1c2VySWQpO1xuICB9XG5cbiAgY2xlYXJVc2VySWQoKTogdm9pZCB7XG4gICAgdGhpcy5vcHRpb25zLnJlZ2lzdHJ5LmNsZWFyVXNlcklkKHRoaXMuaWQpO1xuICB9XG5cbiAgLy8gdHJhbnNwb3J0IOyiheujjCDrj4TspJEg7JiI7Jm46rCAIOuCmOuPhCBtYXJrQ2xvc2Vk6rCAIOuwmOuTnOyLnCDsi6TtlonrkJjrj4TroZ0gdHJ5L2ZpbmFsbHnroZwg6rCQ7IyIXG4gIGNsb3NlKGNvZGU/OiBudW1iZXIsIHJlYXNvbj86IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICh0aGlzLmNsb3NlZEludGVybmFsIHx8IHRoaXMuY2xvc2VTdGFydGVkIHx8IHRoaXMuc29ja2V0LnJlYWR5U3RhdGUgPT09IFdTX0NMT1NFRCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2VTdGFydGVkID0gdHJ1ZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5jbG9zZVRyYW5zcG9ydChjb2RlLCByZWFzb24pO1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLm1hcmtDbG9zZWQoKTtcbiAgICB9XG4gIH1cblxuICAvLyDsnbjrsJTsmrTrk5wg66mU7Iuc7KeA66W8IOyInOywqCDsspjrpqwg7YGQ7JeQIOyYrOumvC4gcGF5bG9hZCBzaXplIOKGkiBlbnZlbG9wZSDtjIzsi7Eg7Iic7Jy866GcIHRyYW5zcG9ydCDroIjrsqgg6rKA7Kad7J2EIOyasOyEoCDsiJjtlontlahcbiAgcHJpdmF0ZSByZWFkb25seSBoYW5kbGVNZXNzYWdlID0gKHJhdzogdW5rbm93bikgPT4ge1xuICAgIHRoaXMuZW5xdWV1ZU1lc3NhZ2VUYXNrKGFzeW5jICgpID0+IHtcbiAgICAgIGNvbnN0IHRleHQgPSBub3JtYWxpemVNZXNzYWdlKHJhdyk7XG4gICAgICBpZiAodGhpcy5tYXhQYXlsb2FkICE9PSB1bmRlZmluZWQgJiYgQnVmZmVyLmJ5dGVMZW5ndGgodGV4dCkgPiB0aGlzLm1heFBheWxvYWQpIHtcbiAgICAgICAgdGhpcy5jbG9zZShXU19DTE9TRV9DT0RFX01FU1NBR0VfVE9PX0JJRywgXCJNZXNzYWdlIHRvbyBsYXJnZVwiKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBwYXJzZWRFbnZlbG9wZSA9IHNhZmVQYXJzZUVudmVsb3BlKHRleHQpO1xuICAgICAgaWYgKCFwYXJzZWRFbnZlbG9wZSkge1xuICAgICAgICB0aGlzLmNsb3NlKFdTX0NMT1NFX0NPREVfSU5WQUxJRF9GUkFNRV9QQVlMT0FEX0RBVEEsIFwiSW52YWxpZCBtZXNzYWdlIHBheWxvYWRcIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5vcHRpb25zLnJlZ2lzdHJ5LnRvdWNoKHRoaXMuaWQpO1xuICAgICAgYXdhaXQgdGhpcy5kaXNwYXRjaEVudmVsb3BlKHBhcnNlZEVudmVsb3BlKTtcbiAgICB9KTtcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGhhbmRsZUNsb3NlID0gKCkgPT4ge1xuICAgIHRoaXMubWFya0Nsb3NlZCgpO1xuICB9O1xuXG4gIC8vIOyGjOy8k+ydtCB0cmFuc3BvcnQgZXJyb3LrpbwgZW1pdO2VmOuptCDsponsi5wgMTAxMSBjbG9zZeuhnCDsiJjroLTsi5zsvJwg7IOB7YOcIOuIhOudveydhCDrp4nsnYxcbiAgcHJpdmF0ZSByZWFkb25seSBoYW5kbGVFcnJvciA9ICgpID0+IHtcbiAgICB0aGlzLmNsb3NlKFdTX0NMT1NFX0NPREVfSU5URVJOQUxfRVJST1IsIFwiV2ViU29ja2V0IHRyYW5zcG9ydCBlcnJvclwiKTtcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IGhhbmRsZVBvbmcgPSAoKSA9PiB7XG4gICAgdGhpcy5hd2FpdGluZ1BvbmcgPSBmYWxzZTtcbiAgICB0aGlzLm9wdGlvbnMucmVnaXN0cnkudG91Y2godGhpcy5pZCk7XG4gIH07XG5cbiAgLy8gZXZlbnQg7KG07J6sIOyXrOu2gCDihpIgc2NoZW1hIOqygOymnSDihpIgaGFuZGxlciDsi6Ttlokg7Iic7Jy866GcIOu2hOq4sO2VqFxuICAvLyBoYW5kbGVy6rCAIOyVhOyngSDrk7HroZ3rkJjsp4Ag7JWK7J2AIOy0iOq4sCDrqZTsi5zsp4DripQg67KE7Y287JeQIOuztOq0gO2WiOuLpOqwgCBvbk1lc3NhZ2Ug65Ox66GdIOyLnCBmbHVzaO2VqFxuICAvLyBoYW5kbGVy64qUIGBhd2FpdGDsnLzroZwg7Iic7LCoIOyLpO2Wie2VtCDtlZwgY29ubmVjdGlvbiDslYjsnZgg66mU7Iuc7KeAIOyInOyEnOulvCDrs7TsnqXtlahcbiAgcHJpdmF0ZSBhc3luYyBkaXNwYXRjaEVudmVsb3BlKGVudmVsb3BlOiBQYXJzZWRFbnZlbG9wZSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGhhbmRsZXJzID0gdGhpcy5tZXNzYWdlSGFuZGxlcnMuZ2V0KGVudmVsb3BlLmV2ZW50KTtcbiAgICBjb25zdCBzY2hlbWEgPSB0aGlzLmV2ZW50U2NoZW1hc0luW2VudmVsb3BlLmV2ZW50XTtcblxuICAgIGlmICghc2NoZW1hKSB7XG4gICAgICB0aGlzLmNsb3NlKFdTX0NMT1NFX0NPREVfUE9MSUNZX1ZJT0xBVElPTiwgXCJVbmtub3duIGV2ZW50XCIpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IHNjaGVtYS5zYWZlUGFyc2UoZW52ZWxvcGUuZGF0YSk7XG4gICAgaWYgKCFwYXJzZWQuc3VjY2Vzcykge1xuICAgICAgdGhpcy5jbG9zZShXU19DTE9TRV9DT0RFX0lOVkFMSURfRlJBTUVfUEFZTE9BRF9EQVRBLCBcIkludmFsaWQgZXZlbnQgZGF0YVwiKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBpZiAoIWhhbmRsZXJzIHx8IGhhbmRsZXJzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgaWYgKHRoaXMucGVuZGluZ01lc3NhZ2VzLmxlbmd0aCA+PSBNQVhfUEVORElOR19NRVNTQUdFUykge1xuICAgICAgICB0aGlzLnBlbmRpbmdNZXNzYWdlcy5zaGlmdCgpO1xuICAgICAgfVxuICAgICAgdGhpcy5wZW5kaW5nTWVzc2FnZXMucHVzaChlbnZlbG9wZSk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBoYW5kbGVyIG9mIGhhbmRsZXJzKSB7XG4gICAgICBhd2FpdCBoYW5kbGVyKHBhcnNlZC5kYXRhKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZsdXNoUGVuZGluZ01lc3NhZ2VzKGV2ZW50OiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCByZW1haW5pbmc6IFBhcnNlZEVudmVsb3BlW10gPSBbXTtcbiAgICBjb25zdCB0b0ZsdXNoOiBQYXJzZWRFbnZlbG9wZVtdID0gW107XG5cbiAgICBmb3IgKGNvbnN0IG1lc3NhZ2Ugb2YgdGhpcy5wZW5kaW5nTWVzc2FnZXMpIHtcbiAgICAgIGlmIChtZXNzYWdlLmV2ZW50ICE9PSBldmVudCkge1xuICAgICAgICByZW1haW5pbmcucHVzaChtZXNzYWdlKTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIHRvRmx1c2gucHVzaChtZXNzYWdlKTtcbiAgICB9XG5cbiAgICB0aGlzLnBlbmRpbmdNZXNzYWdlcy5sZW5ndGggPSAwO1xuICAgIHRoaXMucGVuZGluZ01lc3NhZ2VzLnB1c2goLi4ucmVtYWluaW5nKTtcblxuICAgIGZvciAoY29uc3QgbWVzc2FnZSBvZiB0b0ZsdXNoKSB7XG4gICAgICB0aGlzLmVucXVldWVNZXNzYWdlVGFzayhhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuZGlzcGF0Y2hFbnZlbG9wZShtZXNzYWdlKTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcHVibGlzaFZhbGlkYXRlZChldmVudDogc3RyaW5nLCBkYXRhOiB1bmtub3duKTogdm9pZCB7XG4gICAgY29uc3Qgc2NoZW1hID0gdGhpcy5ldmVudFNjaGVtYXNPdXRbZXZlbnRdO1xuICAgIGlmICghc2NoZW1hKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFVua25vd24gd2Vic29ja2V0IGV2ZW50OiAke2V2ZW50fWApO1xuICAgIH1cblxuICAgIGNvbnN0IHBhcnNlZCA9IHNjaGVtYS5zYWZlUGFyc2UoZGF0YSk7XG4gICAgaWYgKCFwYXJzZWQuc3VjY2Vzcykge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIHdlYnNvY2tldCBldmVudCBwYXlsb2FkOiAke2V2ZW50fWApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLmNsb3NlZEludGVybmFsIHx8IHRoaXMuc29ja2V0LnJlYWR5U3RhdGUgIT09IFdTX09QRU4pIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLmVucXVldWVPdXRib3VuZE1lc3NhZ2UoXG4gICAgICBKU09OLnN0cmluZ2lmeSh7XG4gICAgICAgIGV2ZW50LFxuICAgICAgICBkYXRhOiBwYXJzZWQuZGF0YSxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICAvLyBsaXN0ZW5lciDtlbTsoJwgLyBoZWFydGJlYXQg7KSR64uoIC8gcGVuZGluZyBxdWV1ZSDruYTsm4AgLyByZWdpc3RyeSB1bnJlZ2lzdGVyIC8gb25DbG9zZSDsi6TtlokgLyB3YWl0Rm9yQ2xvc2UgcmVzb2x2ZSDsnYQg7ZWcIOqzs+yXkCDrqqjslYQg7JuQ7J6Q7KCB7Jy866GcIOyymOumrO2VqFxuICAvLyBhc3luYyBvbkNsb3Nl6rCAIHJlamVjdO2VtOuPhCB1bmhhbmRsZWQgcmVqZWN0aW9u7Jy866GcIOyDiOyngCDslYrrj4TroZ0gY2F0Y2jroZwg6rKp66as7ZWoXG4gIHByaXZhdGUgbWFya0Nsb3NlZCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5jbG9zZWRJbnRlcm5hbCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuY2xvc2VkSW50ZXJuYWwgPSB0cnVlO1xuICAgIHRoaXMuY2xvc2VTdGFydGVkID0gZmFsc2U7XG4gICAgdGhpcy5zdG9wSGVhcnRiZWF0KCk7XG4gICAgdGhpcy5zb2NrZXQub2ZmKFwibWVzc2FnZVwiLCB0aGlzLmhhbmRsZU1lc3NhZ2UpO1xuICAgIHRoaXMuc29ja2V0Lm9mZihcImNsb3NlXCIsIHRoaXMuaGFuZGxlQ2xvc2UpO1xuICAgIHRoaXMuc29ja2V0Lm9mZihcImVycm9yXCIsIHRoaXMuaGFuZGxlRXJyb3IpO1xuICAgIHRoaXMuc29ja2V0Lm9mZihcInBvbmdcIiwgdGhpcy5oYW5kbGVQb25nKTtcbiAgICB0aGlzLmF3YWl0aW5nUG9uZyA9IGZhbHNlO1xuICAgIHRoaXMucGVuZGluZ01lc3NhZ2VzLmxlbmd0aCA9IDA7XG4gICAgdGhpcy5wZW5kaW5nT3V0Ym91bmRNZXNzYWdlcy5sZW5ndGggPSAwO1xuICAgIHRoaXMub3B0aW9ucy5yZWdpc3RyeS51bnJlZ2lzdGVyKHRoaXMuaWQpO1xuICAgIGZvciAoY29uc3QgY2FsbGJhY2sgb2YgdGhpcy5jbG9zZUNhbGxiYWNrcy5zcGxpY2UoMCkpIHtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGNhbGxiYWNrKCk7XG4gICAgICAgIGlmIChpc1Byb21pc2VMaWtlKHJlc3VsdCkpIHtcbiAgICAgICAgICB2b2lkIHJlc3VsdC5jYXRjaCgoKSA9PiB7XG4gICAgICAgICAgICAvLyBhc3luYyBjbG9zZSBjYWxsYmFja3MgbXVzdCBub3QgZXNjYXBlIGFzIHVuaGFuZGxlZCByZWplY3Rpb25zXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyBjbG9zZSBjYWxsYmFja3MgbXVzdCBub3QgYmxvY2sgdHJhbnNwb3J0IGNsZWFudXBcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZXNvbHZlQ2xvc2VQcm9taXNlKCk7XG4gIH1cblxuICAvLyBwb25n7J20IOyYpOyngCDslYrsnYAg7IOB7YOc7JeQ7IScIOuLpOydjCB0aWNr7J20IOyYpOuptCB0aW1lb3V0IGNsb3Nl66GcIOyymOumrO2VtCB6b21iaWUgY29ubmVjdGlvbuydhCDsoJXrpqztlahcbiAgcHJpdmF0ZSBzdGFydEhlYXJ0YmVhdCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5oZWFydGJlYXRNcyA8PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmNsb3NlZEludGVybmFsIHx8IHRoaXMuc29ja2V0LnJlYWR5U3RhdGUgIT09IFdTX09QRU4pIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICBpZiAodGhpcy5hd2FpdGluZ1BvbmcpIHtcbiAgICAgICAgdGhpcy5jbG9zZShXU19DTE9TRV9DT0RFX0dPSU5HX0FXQVksIFwiSGVhcnRiZWF0IHRpbWVvdXRcIik7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hd2FpdGluZ1BvbmcgPSB0cnVlO1xuICAgICAgdGhpcy5zb2NrZXQucGluZygpO1xuICAgIH0sIHRoaXMuaGVhcnRiZWF0TXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wSGVhcnRiZWF0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5oZWFydGJlYXRUaW1lcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNsZWFySW50ZXJ2YWwodGhpcy5oZWFydGJlYXRUaW1lcik7XG4gICAgdGhpcy5oZWFydGJlYXRUaW1lciA9IG51bGw7XG4gIH1cblxuICAvLyBjbG9zZeqwgCDsi6TtjKjtlbTrj4QgdGVybWluYXRlIO2PtOuwseq5jOyngCDsi5zrj4TtlZjqs6AsIOuBneuCtCDsi6TtjKjtlZjrqbQgbWFya0Nsb3NlZOyXkCDsg4Htg5wg7KCV66as66W8IOychOyehO2VqFxuICBwcml2YXRlIGNsb3NlVHJhbnNwb3J0KGNvZGU/OiBudW1iZXIsIHJlYXNvbj86IHN0cmluZyk6IHZvaWQge1xuICAgIHRyeSB7XG4gICAgICBpZiAodGhpcy5zb2NrZXQucmVhZHlTdGF0ZSA9PT0gV1NfT1BFTiB8fCB0aGlzLnNvY2tldC5yZWFkeVN0YXRlID09PSBXU19DT05ORUNUSU5HKSB7XG4gICAgICAgIHRoaXMuc29ja2V0LmNsb3NlKGNvZGUsIHRydW5jYXRlQ2xvc2VSZWFzb24ocmVhc29uKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgdGhpcy5zb2NrZXQudGVybWluYXRlKCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnNvY2tldC50ZXJtaW5hdGUoKTtcbiAgICAgIH0gY2F0Y2gge1xuICAgICAgICAvLyB0cmFuc3BvcnQgaXMgYWxyZWFkeSBicm9rZW47IHN0YXRlIGNsZWFudXAgaXMgaGFuZGxlZCBieSBtYXJrQ2xvc2VkKClcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyDsnbjrsJTsmrTrk5wgaGFuZGxlcuulvCBwcm9taXNlIGNoYWlu7Jy866GcIHNlcmlhbGl6ZSDtlZjqs6AsIGhhbmRsZXIg7JiI7Jm464qUIGNvbm5lY3Rpb24tbG9jYWwgMTAxMSBjbG9zZeuhnCDstpXshoztlahcbiAgcHJpdmF0ZSBlbnF1ZXVlTWVzc2FnZVRhc2sodGFzazogKCkgPT4gUHJvbWlzZTx2b2lkPik6IHZvaWQge1xuICAgIHRoaXMubWVzc2FnZVF1ZXVlID0gdGhpcy5tZXNzYWdlUXVldWVcbiAgICAgIC50aGVuKGFzeW5jICgpID0+IHtcbiAgICAgICAgaWYgKHRoaXMuY2xvc2VkSW50ZXJuYWwpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBhd2FpdCB0YXNrKCk7XG4gICAgICB9KVxuICAgICAgLmNhdGNoKCgpID0+IHtcbiAgICAgICAgdGhpcy5jbG9zZShXU19DTE9TRV9DT0RFX0lOVEVSTkFMX0VSUk9SLCBcIk1lc3NhZ2UgaGFuZGxpbmcgZmFpbGVkXCIpO1xuICAgICAgfSk7XG4gIH1cblxuICAvLyBxdWV1ZeqwgCDtlZzqs4Tsl5Ag64+E64us7ZWY66m0IDEwMTPsnLzroZwg64ur7JWEIOuKkOumsCDshozruYTsnpDqsIAg66mU66qo66as66W8IOuBneyXhuydtCDsnqHslYTrqLnsp4Ag66q77ZWY6rKMIO2VqFxuICBwcml2YXRlIGVucXVldWVPdXRib3VuZE1lc3NhZ2UocGF5bG9hZDogc3RyaW5nKTogdm9pZCB7XG4gICAgaWYgKHRoaXMucGVuZGluZ091dGJvdW5kTWVzc2FnZXMubGVuZ3RoID49IE1BWF9QRU5ESU5HX09VVEJPVU5EX01FU1NBR0VTKSB7XG4gICAgICB0aGlzLmNsb3NlKFdTX0NMT1NFX0NPREVfVFJZX0FHQUlOX0xBVEVSLCBcIldlYlNvY2tldCBiYWNrcHJlc3N1cmUgb3ZlcmZsb3dcIik7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nT3V0Ym91bmRNZXNzYWdlcy5wdXNoKHBheWxvYWQpO1xuICAgIHRoaXMuc2NoZWR1bGVPdXRib3VuZEZsdXNoKCk7XG4gIH1cblxuICBwcml2YXRlIHNjaGVkdWxlT3V0Ym91bmRGbHVzaChkZWxheU1zOiBudW1iZXIgPSAwKTogdm9pZCB7XG4gICAgaWYgKHRoaXMub3V0Ym91bmRGbHVzaFNjaGVkdWxlZCB8fCB0aGlzLmNsb3NlZEludGVybmFsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgdGhpcy5vdXRib3VuZEZsdXNoU2NoZWR1bGVkID0gdHJ1ZTtcbiAgICBjb25zdCBmbHVzaCA9ICgpID0+IHtcbiAgICAgIHRoaXMub3V0Ym91bmRGbHVzaFNjaGVkdWxlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5mbHVzaE91dGJvdW5kTWVzc2FnZXMoKTtcbiAgICB9O1xuXG4gICAgaWYgKGRlbGF5TXMgPiAwKSB7XG4gICAgICBzZXRUaW1lb3V0KGZsdXNoLCBkZWxheU1zKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBzZXRJbW1lZGlhdGUoZmx1c2gpO1xuICB9XG5cbiAgLy8gYnVmZmVyZWRBbW91bnTqsIAg7J6E6rOE7LmY66W8IOuEmOycvOuptCBmbHVzaOulvCDrr7jrpIQgc29ja2V0IOuCtOu2gCDtgZDqsIAg7YSw7KeA7KeAIOyViuuPhOuhnSBiYWNrcHJlc3N1cmXrpbwg7KG07KSR7ZWoXG4gIC8vIO2VnCDrsojsl5Ag67Cw7LmYIOuLqOychOuhnOunjCBzZW5k7ZW0IOuPmeq4sCDro6jtlITqsIAg7J2067Kk7Yq4IOujqO2UhOulvCDsnqXsi5zqsIQg7KCQ7Jyg7ZWY7KeAIOyViuqyjCDtlahcbiAgcHJpdmF0ZSBmbHVzaE91dGJvdW5kTWVzc2FnZXMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuY2xvc2VkSW50ZXJuYWwgfHwgdGhpcy5zb2NrZXQucmVhZHlTdGF0ZSAhPT0gV1NfT1BFTikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGlmICh0aGlzLnNvY2tldC5idWZmZXJlZEFtb3VudCA+IE1BWF9TT0NLRVRfQlVGRkVSRURfQU1PVU5UKSB7XG4gICAgICB0aGlzLnNjaGVkdWxlT3V0Ym91bmRGbHVzaChPVVRCT1VORF9SRVRSWV9ERUxBWV9NUyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbGV0IHNlbnQgPSAwO1xuICAgIHdoaWxlIChcbiAgICAgIHNlbnQgPCBPVVRCT1VORF9CQVRDSF9TSVpFICYmXG4gICAgICB0aGlzLnBlbmRpbmdPdXRib3VuZE1lc3NhZ2VzLmxlbmd0aCA+IDAgJiZcbiAgICAgIHRoaXMuc29ja2V0LnJlYWR5U3RhdGUgPT09IFdTX09QRU5cbiAgICApIHtcbiAgICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLnBlbmRpbmdPdXRib3VuZE1lc3NhZ2VzLnNoaWZ0KCk7XG4gICAgICBpZiAoIXBheWxvYWQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG5cbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuc29ja2V0LnNlbmQocGF5bG9hZCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgdGhpcy5jbG9zZShXU19DTE9TRV9DT0RFX0lOVEVSTkFMX0VSUk9SLCBcIk91dGJvdW5kIHB1Ymxpc2ggZmFpbGVkXCIpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG5cbiAgICAgIHNlbnQgKz0gMTtcbiAgICAgIGlmICh0aGlzLnNvY2tldC5idWZmZXJlZEFtb3VudCA+IE1BWF9TT0NLRVRfQlVGRkVSRURfQU1PVU5UKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0aGlzLnBlbmRpbmdPdXRib3VuZE1lc3NhZ2VzLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVPdXRib3VuZEZsdXNoKFxuICAgICAgICB0aGlzLnNvY2tldC5idWZmZXJlZEFtb3VudCA+IE1BWF9TT0NLRVRfQlVGRkVSRURfQU1PVU5UID8gT1VUQk9VTkRfUkVUUllfREVMQVlfTVMgOiAwLFxuICAgICAgKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gbm9ybWFsaXplTWVzc2FnZShyYXc6IHVua25vd24pOiBzdHJpbmcge1xuICBpZiAodHlwZW9mIHJhdyA9PT0gXCJzdHJpbmdcIikge1xuICAgIHJldHVybiByYXc7XG4gIH1cblxuICBpZiAocmF3IGluc3RhbmNlb2YgQnVmZmVyKSB7XG4gICAgcmV0dXJuIHJhdy50b1N0cmluZyhcInV0Zi04XCIpO1xuICB9XG5cbiAgaWYgKHJhdyBpbnN0YW5jZW9mIEFycmF5QnVmZmVyKSB7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKHJhdykudG9TdHJpbmcoXCJ1dGYtOFwiKTtcbiAgfVxuXG4gIGlmIChBcnJheS5pc0FycmF5KHJhdykpIHtcbiAgICByZXR1cm4gQnVmZmVyLmNvbmNhdChyYXcuZmlsdGVyKChjaHVuayk6IGNodW5rIGlzIEJ1ZmZlciA9PiBjaHVuayBpbnN0YW5jZW9mIEJ1ZmZlcikpLnRvU3RyaW5nKFxuICAgICAgXCJ1dGYtOFwiLFxuICAgICk7XG4gIH1cblxuICByZXR1cm4gSlNPTi5zdHJpbmdpZnkocmF3KTtcbn1cblxuZnVuY3Rpb24gc2FmZVBhcnNlRW52ZWxvcGUocmF3OiBzdHJpbmcpOiBQYXJzZWRFbnZlbG9wZSB8IG51bGwge1xuICB0cnkge1xuICAgIGNvbnN0IHBhcnNlZCA9IEpTT04ucGFyc2UocmF3KSBhcyB1bmtub3duO1xuICAgIGNvbnN0IHZhbGlkYXRlZCA9IFdlYlNvY2tldEVudmVsb3BlU2NoZW1hLnNhZmVQYXJzZShwYXJzZWQpO1xuICAgIHJldHVybiB2YWxpZGF0ZWQuc3VjY2VzcyA/IHZhbGlkYXRlZC5kYXRhIDogbnVsbDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbn1cblxuLy8gUkZDIDY0NTXqsIAgY2xvc2UgZnJhbWUgcmVhc29u7J2EIDEyMyBieXRl66GcIOygnO2VnO2VmOuvgOuhnCDstIjqs7zrtoTsnYAg7J6Y6528IOyghOyGoSDsi6TtjKjrpbwg67Cp7KeA7ZWoXG5mdW5jdGlvbiB0cnVuY2F0ZUNsb3NlUmVhc29uKHJlYXNvbj86IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gIGlmICghcmVhc29uKSB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBCdWZmZXIuYnl0ZUxlbmd0aChyZWFzb24sIFwidXRmLThcIikgPD0gMTIzXG4gICAgPyByZWFzb25cbiAgICA6IEJ1ZmZlci5mcm9tKHJlYXNvbikuc3ViYXJyYXkoMCwgMTIzKS50b1N0cmluZyhcInV0Zi04XCIpO1xufVxuXG5mdW5jdGlvbiBpc1Byb21pc2VMaWtlKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUHJvbWlzZTx2b2lkPiB7XG4gIHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIgJiYgdmFsdWUgIT09IG51bGwgJiYgXCJ0aGVuXCIgaW4gdmFsdWUgJiYgXCJjYXRjaFwiIGluIHZhbHVlO1xufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7QUErSUEsU0FBZ0IsdUJBQXVCLFVBQW1DLEVBQUUsRUFBb0I7QUFDOUYsUUFBTyxJQUFJLGlCQUFpQixRQUFROztBQWladEMsU0FBUyxpQkFBaUIsS0FBc0I7QUFDOUMsS0FBSSxPQUFPLFFBQVEsVUFBVTtB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
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"api-parser.d.ts","sourceRoot":"","sources":["../../src/syncer/api-parser.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"api-parser.d.ts","sourceRoot":"","sources":["../../src/syncer/api-parser.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAIrD,OAAO,EAAE,KAAK,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAexD;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAmHrF"}
|