@workflow/world-local 5.0.0-beta.10 → 5.0.0-beta.11
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/config.d.ts +23 -5
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +19 -14
- package/dist/fs.d.ts +113 -2
- package/dist/fs.d.ts.map +1 -1
- package/dist/fs.js +321 -28
- package/dist/index.d.ts +16 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +97 -6
- package/dist/init.d.ts +91 -0
- package/dist/init.d.ts.map +1 -0
- package/dist/init.js +268 -0
- package/dist/instrumentObject.d.ts +8 -0
- package/dist/instrumentObject.d.ts.map +1 -0
- package/dist/instrumentObject.js +66 -0
- package/dist/queue.d.ts +8 -1
- package/dist/queue.d.ts.map +1 -1
- package/dist/queue.js +195 -54
- package/dist/storage/events-storage.d.ts +7 -0
- package/dist/storage/events-storage.d.ts.map +1 -0
- package/dist/storage/events-storage.js +898 -0
- package/dist/storage/filters.d.ts +22 -0
- package/dist/storage/filters.d.ts.map +1 -0
- package/dist/storage/filters.js +33 -0
- package/dist/storage/helpers.d.ts +18 -0
- package/dist/storage/helpers.d.ts.map +1 -0
- package/dist/storage/helpers.js +44 -0
- package/dist/storage/hooks-storage.d.ts +12 -0
- package/dist/storage/hooks-storage.d.ts.map +1 -0
- package/dist/storage/hooks-storage.js +93 -0
- package/dist/storage/index.d.ts +21 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +30 -0
- package/dist/storage/legacy.d.ts +13 -0
- package/dist/storage/legacy.d.ts.map +1 -0
- package/dist/storage/legacy.js +78 -0
- package/dist/storage/runs-storage.d.ts +33 -0
- package/dist/storage/runs-storage.d.ts.map +1 -0
- package/dist/storage/runs-storage.js +130 -0
- package/dist/storage/steps-storage.d.ts +7 -0
- package/dist/storage/steps-storage.d.ts.map +1 -0
- package/dist/storage/steps-storage.js +52 -0
- package/dist/storage.d.ts +9 -2
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +9 -456
- package/dist/streamer.d.ts +4 -2
- package/dist/streamer.d.ts.map +1 -1
- package/dist/streamer.js +467 -107
- package/dist/telemetry.d.ts +28 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +71 -0
- package/dist/test-helpers.d.ts +54 -0
- package/dist/test-helpers.d.ts.map +1 -0
- package/dist/test-helpers.js +118 -0
- package/dist/util.js +1 -1
- package/package.json +12 -11
- package/dist/config.js.map +0 -1
- package/dist/fs.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/queue.js.map +0 -1
- package/dist/storage.js.map +0 -1
- package/dist/streamer.js.map +0 -1
- package/dist/util.js.map +0 -1
package/dist/queue.d.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { type Queue } from '@workflow/world';
|
|
2
2
|
import type { Config } from './config.js';
|
|
3
|
-
export
|
|
3
|
+
export type DirectHandler = (req: Request) => Promise<Response>;
|
|
4
|
+
export type LocalQueue = Queue & {
|
|
5
|
+
/** Close the HTTP agent and release resources. */
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
/** Register a direct in-process handler for a queue prefix, bypassing HTTP. */
|
|
8
|
+
registerHandler(prefix: '__wkf_step_' | '__wkf_workflow_', handler: DirectHandler): void;
|
|
9
|
+
};
|
|
10
|
+
export declare function createQueue(config: Partial<Config>): LocalQueue;
|
|
4
11
|
//# sourceMappingURL=queue.d.ts.map
|
package/dist/queue.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,KAAK,EAAkB,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"queue.d.ts","sourceRoot":"","sources":["../src/queue.ts"],"names":[],"mappings":"AAEA,OAAO,EAAa,KAAK,KAAK,EAAkB,MAAM,iBAAiB,CAAC;AAKxE,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAiD1C,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC;AAEhE,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG;IAC/B,kDAAkD;IAClD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,+EAA+E;IAC/E,eAAe,CACb,MAAM,EAAE,aAAa,GAAG,iBAAiB,EACzC,OAAO,EAAE,aAAa,GACrB,IAAI,CAAC;CACT,CAAC;AAuCF,wBAAgB,WAAW,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,GAAG,UAAU,CAoQ/D"}
|
package/dist/queue.js
CHANGED
|
@@ -1,26 +1,96 @@
|
|
|
1
1
|
import { setTimeout } from 'node:timers/promises';
|
|
2
|
-
import { JsonTransport } from '@vercel/queue';
|
|
3
2
|
import { MessageId, ValidQueueName } from '@workflow/world';
|
|
3
|
+
import { Sema } from 'async-sema';
|
|
4
4
|
import { monotonicFactory } from 'ulid';
|
|
5
5
|
import { Agent } from 'undici';
|
|
6
|
-
import z from 'zod';
|
|
6
|
+
import { z } from 'zod/v4';
|
|
7
7
|
import { resolveBaseUrl } from './config.js';
|
|
8
|
+
import { jsonReplacer, jsonReviver } from './fs.js';
|
|
9
|
+
import { getPackageInfo } from './init.js';
|
|
10
|
+
/**
|
|
11
|
+
* JSON transport that preserves Uint8Array values using the same
|
|
12
|
+
* replacer/reviver that world-local uses for filesystem storage.
|
|
13
|
+
* Uint8Array → { __type: 'Uint8Array', data: '<base64>' } in JSON.
|
|
14
|
+
*/
|
|
15
|
+
class TypedJsonTransport {
|
|
16
|
+
contentType = 'application/json';
|
|
17
|
+
serialize(value) {
|
|
18
|
+
return Buffer.from(JSON.stringify(value, jsonReplacer));
|
|
19
|
+
}
|
|
20
|
+
async deserialize(stream) {
|
|
21
|
+
const chunks = [];
|
|
22
|
+
const reader = stream.getReader();
|
|
23
|
+
while (true) {
|
|
24
|
+
const { done, value } = await reader.read();
|
|
25
|
+
if (done)
|
|
26
|
+
break;
|
|
27
|
+
if (value)
|
|
28
|
+
chunks.push(value);
|
|
29
|
+
}
|
|
30
|
+
const text = Buffer.concat(chunks).toString();
|
|
31
|
+
return JSON.parse(text, jsonReviver);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
8
34
|
// For local queue, there is no technical limit on the message visibility lifespan,
|
|
9
35
|
// but the environment variable can be used for testing purposes to set a max visibility limit.
|
|
10
36
|
const LOCAL_QUEUE_MAX_VISIBILITY = parseInt(process.env.WORKFLOW_LOCAL_QUEUE_MAX_VISIBILITY ?? '0', 10) ||
|
|
11
37
|
Infinity;
|
|
12
|
-
//
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
38
|
+
// Maximum safe delay for setTimeout in Node.js (2^31 - 1 milliseconds ≈ 24.85 days)
|
|
39
|
+
// Larger values cause "TimeoutOverflowWarning: X does not fit into a 32-bit signed integer"
|
|
40
|
+
// When the clamped timeout fires, the handler will recalculate remaining time from
|
|
41
|
+
// persistent state and return another timeoutSeconds if needed.
|
|
42
|
+
const MAX_SAFE_TIMEOUT_MS = 2147483647;
|
|
43
|
+
// The local workers share the same Node.js process and event loop,
|
|
44
|
+
// so we need to limit concurrency to avoid overwhelming the system.
|
|
45
|
+
const DEFAULT_CONCURRENCY_LIMIT = 1000;
|
|
46
|
+
const WORKFLOW_LOCAL_QUEUE_CONCURRENCY = parseInt(process.env.WORKFLOW_LOCAL_QUEUE_CONCURRENCY ?? '0', 10) ||
|
|
47
|
+
DEFAULT_CONCURRENCY_LIMIT;
|
|
48
|
+
const DETACHED_ARRAYBUFFER_ERROR = 'Cannot perform ArrayBuffer.prototype.slice on a detached ArrayBuffer';
|
|
49
|
+
const PROXY_HANDLER_DOCS_URL = 'https://workflow-sdk.dev/docs/getting-started/next#configure-proxy-handler';
|
|
50
|
+
function isDetachedArrayBufferQueueError(error) {
|
|
51
|
+
let current = error;
|
|
52
|
+
const visited = new Set();
|
|
53
|
+
while (current && typeof current === 'object' && !visited.has(current)) {
|
|
54
|
+
visited.add(current);
|
|
55
|
+
if ('message' in current &&
|
|
56
|
+
typeof current.message === 'string' &&
|
|
57
|
+
current.message.includes(DETACHED_ARRAYBUFFER_ERROR)) {
|
|
58
|
+
return true;
|
|
59
|
+
}
|
|
60
|
+
current = 'cause' in current ? current.cause : undefined;
|
|
61
|
+
}
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
function getQueueRoute(queueName) {
|
|
65
|
+
if (queueName.startsWith('__wkf_step_')) {
|
|
66
|
+
return { pathname: 'step', prefix: '__wkf_step_' };
|
|
67
|
+
}
|
|
68
|
+
if (queueName.startsWith('__wkf_workflow_')) {
|
|
69
|
+
return { pathname: 'flow', prefix: '__wkf_workflow_' };
|
|
70
|
+
}
|
|
71
|
+
throw new Error('Unknown queue name prefix');
|
|
72
|
+
}
|
|
16
73
|
export function createQueue(config) {
|
|
17
|
-
|
|
74
|
+
// Create a custom agent optimized for high-concurrency local workflows:
|
|
75
|
+
// - headersTimeout: 0 allows long-running steps
|
|
76
|
+
// - connections: 1000 allows many parallel connections to the same host
|
|
77
|
+
// - pipelining: 1 (default) for HTTP/1.1 compatibility
|
|
78
|
+
// - keepAliveTimeout: 30s keeps connections warm for rapid step execution
|
|
79
|
+
const httpAgent = new Agent({
|
|
80
|
+
headersTimeout: 0,
|
|
81
|
+
connections: 1000,
|
|
82
|
+
keepAliveTimeout: 30_000,
|
|
83
|
+
});
|
|
84
|
+
const transport = new TypedJsonTransport();
|
|
18
85
|
const generateId = monotonicFactory();
|
|
86
|
+
const semaphore = new Sema(WORKFLOW_LOCAL_QUEUE_CONCURRENCY);
|
|
19
87
|
/**
|
|
20
88
|
* holds inflight messages by idempotency key to ensure
|
|
21
89
|
* that we don't queue the same message multiple times
|
|
22
90
|
*/
|
|
23
91
|
const inflightMessages = new Map();
|
|
92
|
+
/** Direct in-process handlers by queue prefix, bypassing HTTP when set. */
|
|
93
|
+
const directHandlers = new Map();
|
|
24
94
|
const queue = async (queueName, message, opts) => {
|
|
25
95
|
const cleanup = [];
|
|
26
96
|
if (opts?.idempotencyKey) {
|
|
@@ -30,17 +100,13 @@ export function createQueue(config) {
|
|
|
30
100
|
}
|
|
31
101
|
}
|
|
32
102
|
const body = transport.serialize(message);
|
|
33
|
-
|
|
34
|
-
if (queueName.startsWith('__wkf_step_')) {
|
|
35
|
-
pathname = `step`;
|
|
36
|
-
}
|
|
37
|
-
else if (queueName.startsWith('__wkf_workflow_')) {
|
|
38
|
-
pathname = `flow`;
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
throw new Error('Unknown queue name prefix');
|
|
42
|
-
}
|
|
103
|
+
const { pathname, prefix } = getQueueRoute(queueName);
|
|
43
104
|
const messageId = MessageId.parse(`msg_${generateId()}`);
|
|
105
|
+
// Extract identifiers from the message for structured logging.
|
|
106
|
+
// Workflow messages have `runId`, step messages have `workflowRunId` + `stepId`.
|
|
107
|
+
const msg = message;
|
|
108
|
+
const runId = (msg.runId ?? msg.workflowRunId ?? undefined);
|
|
109
|
+
const stepId = (msg.stepId ?? undefined);
|
|
44
110
|
if (opts?.idempotencyKey) {
|
|
45
111
|
const key = opts.idempotencyKey;
|
|
46
112
|
inflightMessages.set(key, messageId);
|
|
@@ -49,46 +115,110 @@ export function createQueue(config) {
|
|
|
49
115
|
});
|
|
50
116
|
}
|
|
51
117
|
(async () => {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
118
|
+
const token = semaphore.tryAcquire();
|
|
119
|
+
if (!token) {
|
|
120
|
+
console.warn(`[world-local]: concurrency limit (${WORKFLOW_LOCAL_QUEUE_CONCURRENCY}) reached, waiting for queue to free up`);
|
|
121
|
+
await semaphore.acquire();
|
|
122
|
+
}
|
|
123
|
+
// Safety limit to prevent infinite loops in the local queue.
|
|
124
|
+
// The actual max delivery enforcement happens in the workflow/step handlers
|
|
125
|
+
// (at MAX_QUEUE_DELIVERIES = 48), so this just needs to be comfortably higher.
|
|
126
|
+
const MAX_LOCAL_SAFETY_LIMIT = 256;
|
|
127
|
+
try {
|
|
128
|
+
for (let attempt = 0; attempt < MAX_LOCAL_SAFETY_LIMIT; attempt++) {
|
|
129
|
+
const headers = {
|
|
130
|
+
...opts?.headers,
|
|
62
131
|
'content-type': 'application/json',
|
|
63
132
|
'x-vqs-queue-name': queueName,
|
|
64
133
|
'x-vqs-message-id': messageId,
|
|
65
134
|
'x-vqs-message-attempt': String(attempt + 1),
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
135
|
+
};
|
|
136
|
+
const directHandler = directHandlers.get(prefix);
|
|
137
|
+
let response;
|
|
138
|
+
if (directHandler) {
|
|
139
|
+
const req = new Request(`http://localhost/.well-known/workflow/v1/${pathname}`, {
|
|
140
|
+
method: 'POST',
|
|
141
|
+
headers,
|
|
142
|
+
body,
|
|
143
|
+
});
|
|
144
|
+
response = await directHandler(req);
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const baseUrl = await resolveBaseUrl(config);
|
|
148
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- undici v7 dispatcher types don't match @types/node's RequestInit
|
|
149
|
+
response = await fetch(`${baseUrl}/.well-known/workflow/v1/${pathname}`, {
|
|
150
|
+
method: 'POST',
|
|
151
|
+
duplex: 'half',
|
|
152
|
+
dispatcher: httpAgent,
|
|
153
|
+
headers,
|
|
154
|
+
body,
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
const text = await response.text();
|
|
158
|
+
if (response.ok) {
|
|
159
|
+
try {
|
|
160
|
+
const timeoutSeconds = Number(JSON.parse(text).timeoutSeconds);
|
|
161
|
+
if (Number.isFinite(timeoutSeconds) && timeoutSeconds >= 0) {
|
|
162
|
+
// Clamp to MAX_SAFE_TIMEOUT_MS to avoid Node.js setTimeout overflow warning.
|
|
163
|
+
// When this fires early, the handler recalculates remaining time from
|
|
164
|
+
// persistent state and returns another timeoutSeconds if needed.
|
|
165
|
+
if (timeoutSeconds > 0) {
|
|
166
|
+
const timeoutMs = Math.min(timeoutSeconds * 1000, MAX_SAFE_TIMEOUT_MS);
|
|
167
|
+
await setTimeout(timeoutMs);
|
|
168
|
+
}
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
catch { }
|
|
173
|
+
return;
|
|
79
174
|
}
|
|
80
|
-
|
|
175
|
+
console.error(`[world-local] Queue message failed (attempt ${attempt + 1}, HTTP ${response.status})`, {
|
|
176
|
+
queueName,
|
|
177
|
+
messageId,
|
|
178
|
+
...(runId && { runId }),
|
|
179
|
+
...(stepId && { stepId }),
|
|
180
|
+
handlerError: text,
|
|
181
|
+
});
|
|
182
|
+
// 5s linear backoff to approximate VQS retry timing in local dev.
|
|
183
|
+
// VQS uses 5s linear for attempts 1–32, then exponential, but for
|
|
184
|
+
// local dev linear 5s is sufficient — the handler enforces the real
|
|
185
|
+
// cap at MAX_QUEUE_DELIVERIES (48) which keeps total time under ~4min.
|
|
186
|
+
await setTimeout(5000);
|
|
81
187
|
}
|
|
82
|
-
console.error(`[
|
|
188
|
+
console.error(`[world-local] Queue message exhausted safety limit (${MAX_LOCAL_SAFETY_LIMIT} attempts)`, {
|
|
83
189
|
queueName,
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
body: body.toString(),
|
|
190
|
+
messageId,
|
|
191
|
+
...(runId && { runId }),
|
|
192
|
+
...(stepId && { stepId }),
|
|
88
193
|
});
|
|
89
194
|
}
|
|
90
|
-
|
|
91
|
-
|
|
195
|
+
finally {
|
|
196
|
+
semaphore.release();
|
|
197
|
+
}
|
|
198
|
+
})()
|
|
199
|
+
.catch((err) => {
|
|
200
|
+
// Silently ignore client disconnect errors (e.g., browser refresh during streaming)
|
|
201
|
+
// These are expected and should not cause unhandled rejection warnings
|
|
202
|
+
const isAbortError = err?.name === 'AbortError' || err?.name === 'ResponseAborted';
|
|
203
|
+
if (!isAbortError) {
|
|
204
|
+
if (isDetachedArrayBufferQueueError(err)) {
|
|
205
|
+
console.error(`[local world] Queue operation failed: detected "${DETACHED_ARRAYBUFFER_ERROR}". ` +
|
|
206
|
+
"This usually means a Next.js proxy/middleware consumed Workflow's internal " +
|
|
207
|
+
'request before the executor could read it. Exclude `/.well-known/workflow/*` ' +
|
|
208
|
+
`from your matcher. See ${PROXY_HANDLER_DOCS_URL}`, {
|
|
209
|
+
queueName,
|
|
210
|
+
messageId,
|
|
211
|
+
...(runId && { runId }),
|
|
212
|
+
...(stepId && { stepId }),
|
|
213
|
+
originalError: err,
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
console.error('[local world] Queue operation failed:', err);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
})
|
|
221
|
+
.finally(() => {
|
|
92
222
|
for (const fn of cleanup) {
|
|
93
223
|
fn();
|
|
94
224
|
}
|
|
@@ -116,15 +246,15 @@ export function createQueue(config) {
|
|
|
116
246
|
if (!queueName.startsWith(prefix)) {
|
|
117
247
|
return Response.json({ error: 'Unhandled queue' }, { status: 400 });
|
|
118
248
|
}
|
|
119
|
-
const body = await new
|
|
249
|
+
const body = await new TypedJsonTransport().deserialize(req.body);
|
|
120
250
|
try {
|
|
121
251
|
const result = await handler(body, { attempt, queueName, messageId });
|
|
122
252
|
let timeoutSeconds = null;
|
|
123
253
|
if (typeof result?.timeoutSeconds === 'number') {
|
|
124
254
|
timeoutSeconds = Math.min(result.timeoutSeconds, LOCAL_QUEUE_MAX_VISIBILITY);
|
|
125
255
|
}
|
|
126
|
-
if (timeoutSeconds) {
|
|
127
|
-
return Response.json({ timeoutSeconds }
|
|
256
|
+
if (timeoutSeconds != null) {
|
|
257
|
+
return Response.json({ timeoutSeconds });
|
|
128
258
|
}
|
|
129
259
|
return Response.json({ ok: true });
|
|
130
260
|
}
|
|
@@ -134,8 +264,19 @@ export function createQueue(config) {
|
|
|
134
264
|
};
|
|
135
265
|
};
|
|
136
266
|
const getDeploymentId = async () => {
|
|
137
|
-
|
|
267
|
+
const packageInfo = await getPackageInfo();
|
|
268
|
+
return `dpl_local@${packageInfo.version}`;
|
|
269
|
+
};
|
|
270
|
+
return {
|
|
271
|
+
queue,
|
|
272
|
+
createQueueHandler,
|
|
273
|
+
getDeploymentId,
|
|
274
|
+
registerHandler(prefix, handler) {
|
|
275
|
+
directHandlers.set(prefix, handler);
|
|
276
|
+
},
|
|
277
|
+
async close() {
|
|
278
|
+
await httpAgent.close();
|
|
279
|
+
},
|
|
138
280
|
};
|
|
139
|
-
return { queue, createQueueHandler, getDeploymentId };
|
|
140
281
|
}
|
|
141
|
-
//# sourceMappingURL=queue.js.map
|
|
282
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicXVldWUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcXVldWUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWxELE9BQU8sRUFBRSxTQUFTLEVBQWMsY0FBYyxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDeEUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLFlBQVksQ0FBQztBQUNsQyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDeEMsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUMvQixPQUFPLEVBQUUsQ0FBQyxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRTNCLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSxhQUFhLENBQUM7QUFDN0MsT0FBTyxFQUFFLFlBQVksRUFBRSxXQUFXLEVBQUUsTUFBTSxTQUFTLENBQUM7QUFDcEQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUUzQzs7OztHQUlHO0FBQ0gsTUFBTSxrQkFBa0I7SUFDYixXQUFXLEdBQUcsa0JBQWtCLENBQUM7SUFFMUMsU0FBUyxDQUFDLEtBQWM7UUFDdEIsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUVELEtBQUssQ0FBQyxXQUFXLENBQUMsTUFBa0M7UUFDbEQsTUFBTSxNQUFNLEdBQWlCLEVBQUUsQ0FBQztRQUNoQyxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDbEMsT0FBTyxJQUFJLEVBQUUsQ0FBQztZQUNaLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLEdBQUcsTUFBTSxNQUFNLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDNUMsSUFBSSxJQUFJO2dCQUFFLE1BQU07WUFD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QUFJLENBQUMsRUFBRSxjQUFjLEVBQUUsQ0FBQyxDQUFDO2dCQUMzQyxDQUFDO2dCQUVELE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7WUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO2dCQUNmLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQztZQUN2RCxDQUFDO1FBQ0gsQ0FBQyxDQUFDO0lBQ0osQ0FBQyxDQUFDO0lBRUYsTUFBTSxlQUFlLEdBQTZCLEtBQUssSUFBSSxFQUFFO1FBQzNELE1BQU0sV0FBVyxHQUFHLE1BQU0sY0FBYyxFQUFFLENBQUM7UUFDM0MsT0FBTyxhQUFhLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztJQUM1QyxDQUFDLENBQUM7SUFFRixPQUFPO1FBQ0wsS0FBSztRQUNMLGtCQUFrQjtRQUNsQixlQUFlO1FBQ2YsZUFBZSxDQUNiLE1BQXlDLEVBQ3pDLE9BQXNCO1lBRXRCLGNBQWMsQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RDLENBQUM7UUFDRCxLQUFLLENBQUMsS0FBSztZQUNULE1BQU0sU0FBUyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzFCLENBQUM7S0FDRixDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHNldFRpbWVvdXQgfSBmcm9tICdub2RlOnRpbWVycy9wcm9taXNlcyc7XG5pbXBvcnQgdHlwZSB7IFRyYW5zcG9ydCB9IGZyb20gJ0B2ZXJjZWwvcXVldWUnO1xuaW1wb3J0IHsgTWVzc2FnZUlkLCB0eXBlIFF1ZXVlLCBWYWxpZFF1ZXVlTmFtZSB9IGZyb20gJ0B3b3JrZmxvdy93b3JsZCc7XG5pbXBvcnQgeyBTZW1hIH0gZnJvbSAnYXN5bmMtc2VtYSc7XG5pbXBvcnQgeyBtb25vdG9uaWNGYWN0b3J5IH0gZnJvbSAndWxpZCc7XG5pbXBvcnQgeyBBZ2VudCB9IGZyb20gJ3VuZGljaSc7XG5pbXBvcnQgeyB6IH0gZnJvbSAnem9kL3Y0JztcbmltcG9ydCB0eXBlIHsgQ29uZmlnIH0gZnJvbSAnLi9jb25maWcuanMnO1xuaW1wb3J0IHsgcmVzb2x2ZUJhc2VVcmwgfSBmcm9tICcuL2NvbmZpZy5qcyc7XG5pbXBvcnQgeyBqc29uUmVwbGFjZXIsIGpzb25SZXZpdmVyIH0gZnJvbSAnLi9mcy5qcyc7XG5pbXBvcnQgeyBnZXRQYWNrYWdlSW5mbyB9IGZyb20gJy4vaW5pdC5qcyc7XG5cbi8qKlxuICogSlNPTiB0cmFuc3BvcnQgdGhhdCBwcmVzZXJ2ZXMgVWludDhBcnJheSB2YWx1ZXMgdXNpbmcgdGhlIHNhbWVcbiAqIHJlcGxhY2VyL3Jldml2ZXIgdGhhdCB3b3JsZC1sb2NhbCB1c2VzIGZvciBmaWxlc3lzdGVtIHN0b3JhZ2UuXG4gKiBVaW50OEFycmF5IOKGkiB7IF9fdHlwZTogJ1VpbnQ4QXJyYXknLCBkYXRhOiAnPGJhc2U2ND4nIH0gaW4gSlNPTi5cbiAqL1xuY2xhc3MgVHlwZWRKc29uVHJhbnNwb3J0IGltcGxlbWVudHMgVHJhbnNwb3J0PHVua25vd24+IHtcbiAgcmVhZG9ubHkgY29udGVudFR5cGUgPSAnYXBwbGljYXRpb24vanNvbic7XG5cbiAgc2VyaWFsaXplKHZhbHVlOiB1bmtub3duKTogQnVmZmVyIHtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oSlNPTi5zdHJpbmdpZnkodmFsdWUsIGpzb25SZXBsYWNlcikpO1xuICB9XG5cbiAgYXN5bmMgZGVzZXJpYWxpemUoc3RyZWFtOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5Pik6IFByb21pc2U8dW5rbm93bj4ge1xuICAgIGNvbnN0IGNodW5rczogVWludDhBcnJheVtdID0gW107XG4gICAgY29uc3QgcmVhZGVyID0gc3RyZWFtLmdldFJlYWRlcigpO1xuICAgIHdoaWxlICh0cnVlKSB7XG4gICAgICBjb25zdCB7IGRvbmUsIHZhbHVlIH0gPSBhd2FpdCByZWFkZXIucmVhZCgpO1xuICAgICAgaWYgKGRvbmUpIGJyZWFrO1xuICAgICAgaWYgKHZhbHVlKSBjaHVua3MucHVzaCh2YWx1ZSk7XG4gICAgfVxuICAgIGNvbnN0IHRleHQgPSBCdWZmZXIuY29uY2F0KGNodW5rcykudG9TdHJpbmcoKTtcbiAgICByZXR1cm4gSlNPTi5wYXJzZSh0ZXh0LCBqc29uUmV2aXZlcik7XG4gIH1cbn1cblxuLy8gRm9yIGxvY2FsIHF1ZXVlLCB0aGVyZSBpcyBubyB0ZWNobmljYWwgbGltaXQgb24gdGhlIG1lc3NhZ2UgdmlzaWJpbGl0eSBsaWZlc3Bhbixcbi8vIGJ1dCB0aGUgZW52aXJvbm1lbnQgdmFyaWFibGUgY2FuIGJlIHVzZWQgZm9yIHRlc3RpbmcgcHVycG9zZXMgdG8gc2V0IGEgbWF4IHZpc2liaWxpdHkgbGltaXQuXG5jb25zdCBMT0NBTF9RVUVVRV9NQVhfVklTSUJJTElUWSA9XG4gIHBhcnNlSW50KHByb2Nlc3MuZW52LldPUktGTE9XX0xPQ0FMX1FVRVVFX01BWF9WSVNJQklMSVRZID8/ICcwJywgMTApIHx8XG4gIEluZmluaXR5O1xuXG4vLyBNYXhpbXVtIHNhZmUgZGVsYXkgZm9yIHNldFRpbWVvdXQgaW4gTm9kZS5qcyAoMl4zMSAtIDEgbWlsbGlzZWNvbmRzIOKJiCAyNC44NSBkYXlzKVxuLy8gTGFyZ2VyIHZhbHVlcyBjYXVzZSBcIlRpbWVvdXRPdmVyZmxvd1dhcm5pbmc6IFggZG9lcyBub3QgZml0IGludG8gYSAzMi1iaXQgc2lnbmVkIGludGVnZXJcIlxuLy8gV2hlbiB0aGUgY2xhbXBlZCB0aW1lb3V0IGZpcmVzLCB0aGUgaGFuZGxlciB3aWxsIHJlY2FsY3VsYXRlIHJlbWFpbmluZyB0aW1lIGZyb21cbi8vIHBlcnNpc3RlbnQgc3RhdGUgYW5kIHJldHVybiBhbm90aGVyIHRpbWVvdXRTZWNvbmRzIGlmIG5lZWRlZC5cbmNvbnN0IE1BWF9TQUZFX1RJTUVPVVRfTVMgPSAyMTQ3NDgzNjQ3O1xuXG4vLyBUaGUgbG9jYWwgd29ya2VycyBzaGFyZSB0aGUgc2FtZSBOb2RlLmpzIHByb2Nlc3MgYW5kIGV2ZW50IGxvb3AsXG4vLyBzbyB3ZSBuZWVkIHRvIGxpbWl0IGNvbmN1cnJlbmN5IHRvIGF2b2lkIG92ZXJ3aGVsbWluZyB0aGUgc3lzdGVtLlxuY29uc3QgREVGQVVMVF9DT05DVVJSRU5DWV9MSU1JVCA9IDEwMDA7XG5jb25zdCBXT1JLRkxPV19MT0NBTF9RVUVVRV9DT05DVVJSRU5DWSA9XG4gIHBhcnNlSW50KHByb2Nlc3MuZW52LldPUktGTE9XX0xPQ0FMX1FVRVVFX0NPTkNVUlJFTkNZID8/ICcwJywgMTApIHx8XG4gIERFRkFVTFRfQ09OQ1VSUkVOQ1lfTElNSVQ7XG5cbmV4cG9ydCB0eXBlIERpcmVjdEhhbmRsZXIgPSAocmVxOiBSZXF1ZXN0KSA9PiBQcm9taXNlPFJlc3BvbnNlPjtcblxuZXhwb3J0IHR5cGUgTG9jYWxRdWV1ZSA9IFF1ZXVlICYge1xuICAvKiogQ2xvc2UgdGhlIEhUVFAgYWdlbnQgYW5kIHJlbGVhc2UgcmVzb3VyY2VzLiAqL1xuICBjbG9zZSgpOiBQcm9taXNlPHZvaWQ+O1xuICAvKiogUmVnaXN0ZXIgYSBkaXJlY3QgaW4tcHJvY2VzcyBoYW5kbGVyIGZvciBhIHF1ZXVlIHByZWZpeCwgYnlwYXNzaW5nIEhUVFAuICovXG4gIHJlZ2lzdGVySGFuZGxlcihcbiAgICBwcmVmaXg6ICdfX3drZl9zdGVwXycgfCAnX193a2Zfd29ya2Zsb3dfJyxcbiAgICBoYW5kbGVyOiBEaXJlY3RIYW5kbGVyXG4gICk6IHZvaWQ7XG59O1xuXG5jb25zdCBERVRBQ0hFRF9BUlJBWUJVRkZFUl9FUlJPUiA9XG4gICdDYW5ub3QgcGVyZm9ybSBBcnJheUJ1ZmZlci5wcm90b3R5cGUuc2xpY2Ugb24gYSBkZXRhY2hlZCBBcnJheUJ1ZmZlcic7XG5jb25zdCBQUk9YWV9IQU5ETEVSX0RPQ1NfVVJMID1cbiAgJ2h0dHBzOi8vd29ya2Zsb3ctc2RrLmRldi9kb2NzL2dldHRpbmctc3RhcnRlZC9uZXh0I2NvbmZpZ3VyZS1wcm94eS1oYW5kbGVyJztcblxuZnVuY3Rpb24gaXNEZXRhY2hlZEFycmF5QnVmZmVyUXVldWVFcnJvcihlcnJvcjogdW5rbm93bik6IGJvb2xlYW4ge1xuICBsZXQgY3VycmVudCA9IGVycm9yO1xuICBjb25zdCB2aXNpdGVkID0gbmV3IFNldDx1bmtub3duPigpO1xuXG4gIHdoaWxlIChjdXJyZW50ICYmIHR5cGVvZiBjdXJyZW50ID09PSAnb2JqZWN0JyAmJiAhdmlzaXRlZC5oYXMoY3VycmVudCkpIHtcbiAgICB2aXNpdGVkLmFkZChjdXJyZW50KTtcbiAgICBpZiAoXG4gICAgICAnbWVzc2FnZScgaW4gY3VycmVudCAmJlxuICAgICAgdHlwZW9mIGN1cnJlbnQubWVzc2FnZSA9PT0gJ3N0cmluZycgJiZcbiAgICAgIGN1cnJlbnQubWVzc2FnZS5pbmNsdWRlcyhERVRBQ0hFRF9BUlJBWUJVRkZFUl9FUlJPUilcbiAgICApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjdXJyZW50ID0gJ2NhdXNlJyBpbiBjdXJyZW50ID8gY3VycmVudC5jYXVzZSA6IHVuZGVmaW5lZDtcbiAgfVxuXG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZ2V0UXVldWVSb3V0ZShxdWV1ZU5hbWU6IFZhbGlkUXVldWVOYW1lKToge1xuICBwYXRobmFtZTogJ2Zsb3cnIHwgJ3N0ZXAnO1xuICBwcmVmaXg6ICdfX3drZl9zdGVwXycgfCAnX193a2Zfd29ya2Zsb3dfJztcbn0ge1xuICBpZiAocXVldWVOYW1lLnN0YXJ0c1dpdGgoJ19fd2tmX3N0ZXBfJykpIHtcbiAgICByZXR1cm4geyBwYXRobmFtZTogJ3N0ZXAnLCBwcmVmaXg6ICdfX3drZl9zdGVwXycgfTtcbiAgfVxuICBpZiAocXVldWVOYW1lLnN0YXJ0c1dpdGgoJ19fd2tmX3dvcmtmbG93XycpKSB7XG4gICAgcmV0dXJuIHsgcGF0aG5hbWU6ICdmbG93JywgcHJlZml4OiAnX193a2Zfd29ya2Zsb3dfJyB9O1xuICB9XG4gIHRocm93IG5ldyBFcnJvcignVW5rbm93biBxdWV1ZSBuYW1lIHByZWZpeCcpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlUXVldWUoY29uZmlnOiBQYXJ0aWFsPENvbmZpZz4pOiBMb2NhbFF1ZXVlIHtcbiAgLy8gQ3JlYXRlIGEgY3VzdG9tIGFnZW50IG9wdGltaXplZCBmb3IgaGlnaC1jb25jdXJyZW5jeSBsb2NhbCB3b3JrZmxvd3M6XG4gIC8vIC0gaGVhZGVyc1RpbWVvdXQ6IDAgYWxsb3dzIGxvbmctcnVubmluZyBzdGVwc1xuICAvLyAtIGNvbm5lY3Rpb25zOiAxMDAwIGFsbG93cyBtYW55IHBhcmFsbGVsIGNvbm5lY3Rpb25zIHRvIHRoZSBzYW1lIGhvc3RcbiAgLy8gLSBwaXBlbGluaW5nOiAxIChkZWZhdWx0KSBmb3IgSFRUUC8xLjEgY29tcGF0aWJpbGl0eVxuICAvLyAtIGtlZXBBbGl2ZVRpbWVvdXQ6IDMwcyBrZWVwcyBjb25uZWN0aW9ucyB3YXJtIGZvciByYXBpZCBzdGVwIGV4ZWN1dGlvblxuICBjb25zdCBodHRwQWdlbnQgPSBuZXcgQWdlbnQoe1xuICAgIGhlYWRlcnNUaW1lb3V0OiAwLFxuICAgIGNvbm5lY3Rpb25zOiAxMDAwLFxuICAgIGtlZXBBbGl2ZVRpbWVvdXQ6IDMwXzAwMCxcbiAgfSk7XG4gIGNvbnN0IHRyYW5zcG9ydCA9IG5ldyBUeXBlZEpzb25UcmFuc3BvcnQoKTtcbiAgY29uc3QgZ2VuZXJhdGVJZCA9IG1vbm90b25pY0ZhY3RvcnkoKTtcbiAgY29uc3Qgc2VtYXBob3JlID0gbmV3IFNlbWEoV09SS0ZMT1dfTE9DQUxfUVVFVUVfQ09OQ1VSUkVOQ1kpO1xuXG4gIC8qKlxuICAgKiBob2xkcyBpbmZsaWdodCBtZXNzYWdlcyBieSBpZGVtcG90ZW5jeSBrZXkgdG8gZW5zdXJlXG4gICAqIHRoYXQgd2UgZG9uJ3QgcXVldWUgdGhlIHNhbWUgbWVzc2FnZSBtdWx0aXBsZSB0aW1lc1xuICAgKi9cbiAgY29uc3QgaW5mbGlnaHRNZXNzYWdlcyA9IG5ldyBNYXA8c3RyaW5nLCBNZXNzYWdlSWQ+KCk7XG4gIC8qKiBEaXJlY3QgaW4tcHJvY2VzcyBoYW5kbGVycyBieSBxdWV1ZSBwcmVmaXgsIGJ5cGFzc2luZyBIVFRQIHdoZW4gc2V0LiAqL1xuICBjb25zdCBkaXJlY3RIYW5kbGVycyA9IG5ldyBNYXA8c3RyaW5nLCBEaXJlY3RIYW5kbGVyPigpO1xuXG4gIGNvbnN0IHF1ZXVlOiBRdWV1ZVsncXVldWUnXSA9IGFzeW5jIChxdWV1ZU5hbWUsIG1lc3NhZ2UsIG9wdHMpID0+IHtcbiAgICBjb25zdCBjbGVhbnVwID0gW10gYXMgKCgpID0+IHZvaWQpW107XG5cbiAgICBpZiAob3B0cz8uaWRlbXBvdGVuY3lLZXkpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nID0gaW5mbGlnaHRNZXNzYWdlcy5nZXQob3B0cy5pZGVtcG90ZW5jeUtleSk7XG4gICAgICBpZiAoZXhpc3RpbmcpIHtcbiAgICAgICAgcmV0dXJuIHsgbWVzc2FnZUlkOiBleGlzdGluZyB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IGJvZHkgPSB0cmFuc3BvcnQuc2VyaWFsaXplKG1lc3NhZ2UpO1xuICAgIGNvbnN0IHsgcGF0aG5hbWUsIHByZWZpeCB9ID0gZ2V0UXVldWVSb3V0ZShxdWV1ZU5hbWUpO1xuICAgIGNvbnN0IG1lc3NhZ2VJZCA9IE1lc3NhZ2VJZC5wYXJzZShgbXNnXyR7Z2VuZXJhdGVJZCgpfWApO1xuXG4gICAgLy8gRXh0cmFjdCBpZGVudGlmaWVycyBmcm9tIHRoZSBtZXNzYWdlIGZvciBzdHJ1Y3R1cmVkIGxvZ2dpbmcuXG4gICAgLy8gV29ya2Zsb3cgbWVzc2FnZXMgaGF2ZSBgcnVuSWRgLCBzdGVwIG1lc3NhZ2VzIGhhdmUgYHdvcmtmbG93UnVuSWRgICsgYHN0ZXBJZGAuXG4gICAgY29uc3QgbXNnID0gbWVzc2FnZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPjtcbiAgICBjb25zdCBydW5JZCA9IChtc2cucnVuSWQgPz8gbXNnLndvcmtmbG93UnVuSWQgPz8gdW5kZWZpbmVkKSBhc1xuICAgICAgfCBzdHJpbmdcbiAgICAgIHwgdW5kZWZpbmVkO1xuICAgIGNvbnN0IHN0ZXBJZCA9IChtc2cuc3RlcElkID8/IHVuZGVmaW5lZCkgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKG9wdHM/LmlkZW1wb3RlbmN5S2V5KSB7XG4gICAgICBjb25zdCBrZXkgPSBvcHRzLmlkZW1wb3RlbmN5S2V5O1xuICAgICAgaW5mbGlnaHRNZXNzYWdlcy5zZXQoa2V5LCBtZXNzYWdlSWQpO1xuICAgICAgY2xlYW51cC5wdXNoKCgpID0+IHtcbiAgICAgICAgaW5mbGlnaHRNZXNzYWdlcy5kZWxldGUoa2V5KTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIChhc3luYyAoKSA9PiB7XG4gICAgICBjb25zdCB0b2tlbiA9IHNlbWFwaG9yZS50cnlBY3F1aXJlKCk7XG4gICAgICBpZiAoIXRva2VuKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICBgW3dvcmxkLWxvY2FsXTogY29uY3VycmVuY3kgbGltaXQgKCR7V09SS0ZMT1dfTE9DQUxfUVVFVUVfQ09OQ1VSUkVOQ1l9KSByZWFjaGVkLCB3YWl0aW5nIGZvciBxdWV1ZSB0byBmcmVlIHVwYFxuICAgICAgICApO1xuICAgICAgICBhd2FpdCBzZW1hcGhvcmUuYWNxdWlyZSgpO1xuICAgICAgfVxuICAgICAgLy8gU2FmZXR5IGxpbWl0IHRvIHByZXZlbnQgaW5maW5pdGUgbG9vcHMgaW4gdGhlIGxvY2FsIHF1ZXVlLlxuICAgICAgLy8gVGhlIGFjdHVhbCBtYXggZGVsaXZlcnkgZW5mb3JjZW1lbnQgaGFwcGVucyBpbiB0aGUgd29ya2Zsb3cvc3RlcCBoYW5kbGVyc1xuICAgICAgLy8gKGF0IE1BWF9RVUVVRV9ERUxJVkVSSUVTID0gNDgpLCBzbyB0aGlzIGp1c3QgbmVlZHMgdG8gYmUgY29tZm9ydGFibHkgaGlnaGVyLlxuICAgICAgY29uc3QgTUFYX0xPQ0FMX1NBRkVUWV9MSU1JVCA9IDI1NjtcbiAgICAgIHRyeSB7XG4gICAgICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgTUFYX0xPQ0FMX1NBRkVUWV9MSU1JVDsgYXR0ZW1wdCsrKSB7XG4gICAgICAgICAgY29uc3QgaGVhZGVyczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHtcbiAgICAgICAgICAgIC4uLm9wdHM/LmhlYWRlcnMsXG4gICAgICAgICAgICAnY29udGVudC10eXBlJzogJ2FwcGxpY2F0aW9uL2pzb24nLFxuICAgICAgICAgICAgJ3gtdnFzLXF1ZXVlLW5hbWUnOiBxdWV1ZU5hbWUsXG4gICAgICAgICAgICAneC12cXMtbWVzc2FnZS1pZCc6IG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICd4LXZxcy1tZXNzYWdlLWF0dGVtcHQnOiBTdHJpbmcoYXR0ZW1wdCArIDEpLFxuICAgICAgICAgIH07XG4gICAgICAgICAgY29uc3QgZGlyZWN0SGFuZGxlciA9IGRpcmVjdEhhbmRsZXJzLmdldChwcmVmaXgpO1xuICAgICAgICAgIGxldCByZXNwb25zZTogUmVzcG9uc2U7XG5cbiAgICAgICAgICBpZiAoZGlyZWN0SGFuZGxlcikge1xuICAgICAgICAgICAgY29uc3QgcmVxID0gbmV3IFJlcXVlc3QoXG4gICAgICAgICAgICAgIGBodHRwOi8vbG9jYWxob3N0Ly53ZWxsLWtub3duL3dvcmtmbG93L3YxLyR7cGF0aG5hbWV9YCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGhlYWRlcnMsXG4gICAgICAgICAgICAgICAgYm9keSxcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgZGlyZWN0SGFuZGxlcihyZXEpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBiYXNlVXJsID0gYXdhaXQgcmVzb2x2ZUJhc2VVcmwoY29uZmlnKTtcbiAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tZXhwbGljaXQtYW55IC0tIHVuZGljaSB2NyBkaXNwYXRjaGVyIHR5cGVzIGRvbid0IG1hdGNoIEB0eXBlcy9ub2RlJ3MgUmVxdWVzdEluaXRcbiAgICAgICAgICAgIHJlc3BvbnNlID0gYXdhaXQgZmV0Y2goXG4gICAgICAgICAgICAgIGAke2Jhc2VVcmx9Ly53ZWxsLWtub3duL3dvcmtmbG93L3YxLyR7cGF0aG5hbWV9YCxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIG1ldGhvZDogJ1BPU1QnLFxuICAgICAgICAgICAgICAgIGR1cGxleDogJ2hhbGYnLFxuICAgICAgICAgICAgICAgIGRpc3BhdGNoZXI6IGh0dHBBZ2VudCxcbiAgICAgICAgICAgICAgICBoZWFkZXJzLFxuICAgICAgICAgICAgICAgIGJvZHksXG4gICAgICAgICAgICAgIH0gYXMgYW55XG4gICAgICAgICAgICApO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHRleHQgPSBhd2FpdCByZXNwb25zZS50ZXh0KCk7XG5cbiAgICAgICAgICBpZiAocmVzcG9uc2Uub2spIHtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgIGNvbnN0IHRpbWVvdXRTZWNvbmRzID0gTnVtYmVyKEpTT04ucGFyc2UodGV4dCkudGltZW91dFNlY29uZHMpO1xuICAgICAgICAgICAgICBpZiAoTnVtYmVyLmlzRmluaXRlKHRpbWVvdXRTZWNvbmRzKSAmJiB0aW1lb3V0U2Vjb25kcyA+PSAwKSB7XG4gICAgICAgICAgICAgICAgLy8gQ2xhbXAgdG8gTUFYX1NBRkVfVElNRU9VVF9NUyB0byBhdm9pZCBOb2RlLmpzIHNldFRpbWVvdXQgb3ZlcmZsb3cgd2FybmluZy5cbiAgICAgICAgICAgICAgICAvLyBXaGVuIHRoaXMgZmlyZXMgZWFybHksIHRoZSBoYW5kbGVyIHJlY2FsY3VsYXRlcyByZW1haW5pbmcgdGltZSBmcm9tXG4gICAgICAgICAgICAgICAgLy8gcGVyc2lzdGVudCBzdGF0ZSBhbmQgcmV0dXJucyBhbm90aGVyIHRpbWVvdXRTZWNvbmRzIGlmIG5lZWRlZC5cbiAgICAgICAgICAgICAgICBpZiAodGltZW91dFNlY29uZHMgPiAwKSB7XG4gICAgICAgICAgICAgICAgICBjb25zdCB0aW1lb3V0TXMgPSBNYXRoLm1pbihcbiAgICAgICAgICAgICAgICAgICAgdGltZW91dFNlY29uZHMgKiAxMDAwLFxuICAgICAgICAgICAgICAgICAgICBNQVhfU0FGRV9USU1FT1VUX01TXG4gICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgYXdhaXQgc2V0VGltZW91dCh0aW1lb3V0TXMpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSBjYXRjaCB7fVxuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgICBgW3dvcmxkLWxvY2FsXSBRdWV1ZSBtZXNzYWdlIGZhaWxlZCAoYXR0ZW1wdCAke2F0dGVtcHQgKyAxfSwgSFRUUCAke3Jlc3BvbnNlLnN0YXR1c30pYCxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgcXVldWVOYW1lLFxuICAgICAgICAgICAgICBtZXNzYWdlSWQsXG4gICAgICAgICAgICAgIC4uLihydW5JZCAmJiB7IHJ1bklkIH0pLFxuICAgICAgICAgICAgICAuLi4oc3RlcElkICYmIHsgc3RlcElkIH0pLFxuICAgICAgICAgICAgICBoYW5kbGVyRXJyb3I6IHRleHQsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIDVzIGxpbmVhciBiYWNrb2ZmIHRvIGFwcHJveGltYXRlIFZRUyByZXRyeSB0aW1pbmcgaW4gbG9jYWwgZGV2LlxuICAgICAgICAgIC8vIFZRUyB1c2VzIDVzIGxpbmVhciBmb3IgYXR0ZW1wdHMgMeKAkzMyLCB0aGVuIGV4cG9uZW50aWFsLCBidXQgZm9yXG4gICAgICAgICAgLy8gbG9jYWwgZGV2IGxpbmVhciA1cyBpcyBzdWZmaWNpZW50IOKAlCB0aGUgaGFuZGxlciBlbmZvcmNlcyB0aGUgcmVhbFxuICAgICAgICAgIC8vIGNhcCBhdCBNQVhfUVVFVUVfREVMSVZFUklFUyAoNDgpIHdoaWNoIGtlZXBzIHRvdGFsIHRpbWUgdW5kZXIgfjRtaW4uXG4gICAgICAgICAgYXdhaXQgc2V0VGltZW91dCg1MDAwKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgYFt3b3JsZC1sb2NhbF0gUXVldWUgbWVzc2FnZSBleGhhdXN0ZWQgc2FmZXR5IGxpbWl0ICgke01BWF9MT0NBTF9TQUZFVFlfTElNSVR9IGF0dGVtcHRzKWAsXG4gICAgICAgICAge1xuICAgICAgICAgICAgcXVldWVOYW1lLFxuICAgICAgICAgICAgbWVzc2FnZUlkLFxuICAgICAgICAgICAgLi4uKHJ1bklkICYmIHsgcnVuSWQgfSksXG4gICAgICAgICAgICAuLi4oc3RlcElkICYmIHsgc3RlcElkIH0pLFxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICAgIH0gZmluYWxseSB7XG4gICAgICAgIHNlbWFwaG9yZS5yZWxlYXNlKCk7XG4gICAgICB9XG4gICAgfSkoKVxuICAgICAgLmNhdGNoKChlcnIpID0+IHtcbiAgICAgICAgLy8gU2lsZW50bHkgaWdub3JlIGNsaWVudCBkaXNjb25uZWN0IGVycm9ycyAoZS5nLiwgYnJvd3NlciByZWZyZXNoIGR1cmluZyBzdHJlYW1pbmcpXG4gICAgICAgIC8vIFRoZXNlIGFyZSBleHBlY3RlZCBhbmQgc2hvdWxkIG5vdCBjYXVzZSB1bmhhbmRsZWQgcmVqZWN0aW9uIHdhcm5pbmdzXG4gICAgICAgIGNvbnN0IGlzQWJvcnRFcnJvciA9XG4gICAgICAgICAgZXJyPy5uYW1lID09PSAnQWJvcnRFcnJvcicgfHwgZXJyPy5uYW1lID09PSAnUmVzcG9uc2VBYm9ydGVkJztcbiAgICAgICAgaWYgKCFpc0Fib3J0RXJyb3IpIHtcbiAgICAgICAgICBpZiAoaXNEZXRhY2hlZEFycmF5QnVmZmVyUXVldWVFcnJvcihlcnIpKSB7XG4gICAgICAgICAgICBjb25zb2xlLmVycm9yKFxuICAgICAgICAgICAgICBgW2xvY2FsIHdvcmxkXSBRdWV1ZSBvcGVyYXRpb24gZmFpbGVkOiBkZXRlY3RlZCBcIiR7REVUQUNIRURfQVJSQVlCVUZGRVJfRVJST1J9XCIuIGAgK1xuICAgICAgICAgICAgICAgIFwiVGhpcyB1c3VhbGx5IG1lYW5zIGEgTmV4dC5qcyBwcm94eS9taWRkbGV3YXJlIGNvbnN1bWVkIFdvcmtmbG93J3MgaW50ZXJuYWwgXCIgK1xuICAgICAgICAgICAgICAgICdyZXF1ZXN0IGJlZm9yZSB0aGUgZXhlY3V0b3IgY291bGQgcmVhZCBpdC4gRXhjbHVkZSBgLy53ZWxsLWtub3duL3dvcmtmbG93LypgICcgK1xuICAgICAgICAgICAgICAgIGBmcm9tIHlvdXIgbWF0Y2hlci4gU2VlICR7UFJPWFlfSEFORExFUl9ET0NTX1VSTH1gLFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgcXVldWVOYW1lLFxuICAgICAgICAgICAgICAgIG1lc3NhZ2VJZCxcbiAgICAgICAgICAgICAgICAuLi4ocnVuSWQgJiYgeyBydW5JZCB9KSxcbiAgICAgICAgICAgICAgICAuLi4oc3RlcElkICYmIHsgc3RlcElkIH0pLFxuICAgICAgICAgICAgICAgIG9yaWdpbmFsRXJyb3I6IGVycixcbiAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgKTtcbiAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc29sZS5lcnJvcignW2xvY2FsIHdvcmxkXSBRdWV1ZSBvcGVyYXRpb24gZmFpbGVkOicsIGVycik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9KVxuICAgICAgLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IGZuIG9mIGNsZWFudXApIHtcbiAgICAgICAgICBmbigpO1xuICAgICAgICB9XG4gICAgICB9KTtcblxuICAgIHJldHVybiB7IG1lc3NhZ2VJZCB9O1xuICB9O1xuXG4gIGNvbnN0IEhlYWRlclBhcnNlciA9IHoub2JqZWN0KHtcbiAgICAneC12cXMtcXVldWUtbmFtZSc6IFZhbGlkUXVldWVOYW1lLFxuICAgICd4LXZxcy1tZXNzYWdlLWlkJzogTWVzc2FnZUlkLFxuICAgICd4LXZxcy1tZXNzYWdlLWF0dGVtcHQnOiB6LmNvZXJjZS5udW1iZXIoKSxcbiAgfSk7XG5cbiAgY29uc3QgY3JlYXRlUXVldWVIYW5kbGVyOiBRdWV1ZVsnY3JlYXRlUXVldWVIYW5kbGVyJ10gPSAocHJlZml4LCBoYW5kbGVyKSA9PiB7XG4gICAgcmV0dXJuIGFzeW5jIChyZXEpID0+IHtcbiAgICAgIGNvbnN0IGhlYWRlcnMgPSBIZWFkZXJQYXJzZXIuc2FmZVBhcnNlKE9iamVjdC5mcm9tRW50cmllcyhyZXEuaGVhZGVycykpO1xuXG4gICAgICBpZiAoIWhlYWRlcnMuc3VjY2VzcyB8fCAhcmVxLmJvZHkpIHtcbiAgICAgICAgcmV0dXJuIFJlc3BvbnNlLmpzb24oXG4gICAgICAgICAge1xuICAgICAgICAgICAgZXJyb3I6ICFyZXEuYm9keVxuICAgICAgICAgICAgICA/ICdNaXNzaW5nIHJlcXVlc3QgYm9keSdcbiAgICAgICAgICAgICAgOiAnTWlzc2luZyByZXF1aXJlZCBoZWFkZXJzJyxcbiAgICAgICAgICB9LFxuICAgICAgICAgIHsgc3RhdHVzOiA0MDAgfVxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBxdWV1ZU5hbWUgPSBoZWFkZXJzLmRhdGFbJ3gtdnFzLXF1ZXVlLW5hbWUnXTtcbiAgICAgIGNvbnN0IG1lc3NhZ2VJZCA9IGhlYWRlcnMuZGF0YVsneC12cXMtbWVzc2FnZS1pZCddO1xuICAgICAgY29uc3QgYXR0ZW1wdCA9IGhlYWRlcnMuZGF0YVsneC12cXMtbWVzc2FnZS1hdHRlbXB0J107XG5cbiAgICAgIGlmICghcXVldWVOYW1lLnN0YXJ0c1dpdGgocHJlZml4KSkge1xuICAgICAgICByZXR1cm4gUmVzcG9uc2UuanNvbih7IGVycm9yOiAnVW5oYW5kbGVkIHF1ZXVlJyB9LCB7IHN0YXR1czogNDAwIH0pO1xuICAgICAgfVxuXG4gICAgICBjb25zdCBib2R5ID0gYXdhaXQgbmV3IFR5cGVkSnNvblRyYW5zcG9ydCgpLmRlc2VyaWFsaXplKHJlcS5ib2R5KTtcbiAgICAgIHRyeSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGhhbmRsZXIoYm9keSwgeyBhdHRlbXB0LCBxdWV1ZU5hbWUsIG1lc3NhZ2VJZCB9KTtcblxuICAgICAgICBsZXQgdGltZW91dFNlY29uZHM6IG51bWJlciB8IG51bGwgPSBudWxsO1xuICAgICAgICBpZiAodHlwZW9mIHJlc3VsdD8udGltZW91dFNlY29uZHMgPT09ICdudW1iZXInKSB7XG4gICAgICAgICAgdGltZW91dFNlY29uZHMgPSBNYXRoLm1pbihcbiAgICAgICAgICAgIHJlc3VsdC50aW1lb3V0U2Vjb25kcyxcbiAgICAgICAgICAgIExPQ0FMX1FVRVVFX01BWF9WSVNJQklMSVRZXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aW1lb3V0U2Vjb25kcyAhPSBudWxsKSB7XG4gICAgICAgICAgcmV0dXJuIFJlc3BvbnNlLmpzb24oeyB0aW1lb3V0U2Vjb25kcyB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBSZXNwb25zZS5qc29uKHsgb2s6IHRydWUgfSk7XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICByZXR1cm4gUmVzcG9uc2UuanNvbihTdHJpbmcoZXJyb3IpLCB7IHN0YXR1czogNTAwIH0pO1xuICAgICAgfVxuICAgIH07XG4gIH07XG5cbiAgY29uc3QgZ2V0RGVwbG95bWVudElkOiBRdWV1ZVsnZ2V0RGVwbG95bWVudElkJ10gPSBhc3luYyAoKSA9PiB7XG4gICAgY29uc3QgcGFja2FnZUluZm8gPSBhd2FpdCBnZXRQYWNrYWdlSW5mbygpO1xuICAgIHJldHVybiBgZHBsX2xvY2FsQCR7cGFja2FnZUluZm8udmVyc2lvbn1gO1xuICB9O1xuXG4gIHJldHVybiB7XG4gICAgcXVldWUsXG4gICAgY3JlYXRlUXVldWVIYW5kbGVyLFxuICAgIGdldERlcGxveW1lbnRJZCxcbiAgICByZWdpc3RlckhhbmRsZXIoXG4gICAgICBwcmVmaXg6ICdfX3drZl9zdGVwXycgfCAnX193a2Zfd29ya2Zsb3dfJyxcbiAgICAgIGhhbmRsZXI6IERpcmVjdEhhbmRsZXJcbiAgICApIHtcbiAgICAgIGRpcmVjdEhhbmRsZXJzLnNldChwcmVmaXgsIGhhbmRsZXIpO1xuICAgIH0sXG4gICAgYXN5bmMgY2xvc2UoKSB7XG4gICAgICBhd2FpdCBodHRwQWdlbnQuY2xvc2UoKTtcbiAgICB9LFxuICB9O1xufVxuIl19
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Storage } from '@workflow/world';
|
|
2
|
+
/**
|
|
3
|
+
* Creates the events storage implementation using the filesystem.
|
|
4
|
+
* Implements the Storage['events'] interface with create, list, and listByCorrelationId operations.
|
|
5
|
+
*/
|
|
6
|
+
export declare function createEventsStorage(basedir: string, tag?: string): Storage['events'];
|
|
7
|
+
//# sourceMappingURL=events-storage.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events-storage.d.ts","sourceRoot":"","sources":["../../src/storage/events-storage.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAMV,OAAO,EAGR,MAAM,iBAAiB,CAAC;AA8IzB;;;GAGG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,GAAG,CAAC,EAAE,MAAM,GACX,OAAO,CAAC,QAAQ,CAAC,CAukCnB"}
|