@workflow/core 5.0.0-beta.17 → 5.0.0-beta.19
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/capabilities.d.ts +3 -0
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +12 -1
- package/dist/runtime/resume-hook.d.ts.map +1 -1
- package/dist/runtime/resume-hook.js +8 -3
- package/dist/runtime/start.d.ts +11 -1
- package/dist/runtime/start.d.ts.map +1 -1
- package/dist/runtime/start.js +49 -8
- package/dist/runtime/step-executor.d.ts +6 -0
- package/dist/runtime/step-executor.d.ts.map +1 -1
- package/dist/runtime/step-executor.js +11 -8
- package/dist/runtime/step-handler.d.ts.map +1 -1
- package/dist/runtime/step-handler.js +16 -9
- package/dist/runtime/suspension-handler.d.ts.map +1 -1
- package/dist/runtime/suspension-handler.js +8 -5
- package/dist/runtime.d.ts.map +1 -1
- package/dist/runtime.js +9 -5
- package/dist/serialization/client.d.ts.map +1 -1
- package/dist/serialization/client.js +6 -3
- package/dist/serialization/codec.d.ts +16 -0
- package/dist/serialization/codec.d.ts.map +1 -1
- package/dist/serialization/codec.js +1 -1
- package/dist/serialization/compression.d.ts +104 -0
- package/dist/serialization/compression.d.ts.map +1 -0
- package/dist/serialization/compression.js +260 -0
- package/dist/serialization/index.d.ts +7 -6
- package/dist/serialization/index.d.ts.map +1 -1
- package/dist/serialization/index.js +9 -7
- package/dist/serialization/step.d.ts.map +1 -1
- package/dist/serialization/step.js +6 -3
- package/dist/serialization/types.d.ts +4 -0
- package/dist/serialization/types.d.ts.map +1 -1
- package/dist/serialization/types.js +5 -1
- package/dist/serialization-format.d.ts +15 -0
- package/dist/serialization-format.d.ts.map +1 -1
- package/dist/serialization-format.js +133 -9
- package/dist/serialization.d.ts +8 -7
- package/dist/serialization.d.ts.map +1 -1
- package/dist/serialization.js +106 -20
- package/dist/telemetry/semantic-conventions.d.ts +24 -0
- package/dist/telemetry/semantic-conventions.d.ts.map +1 -1
- package/dist/telemetry/semantic-conventions.js +19 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +2 -2
- package/dist/workflow.d.ts.map +1 -1
- package/dist/workflow.js +7 -2
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/serialization/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/serialization/client.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,iBAAiB,CAAC;AAKzB;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,OAAO,EACd,aAAa,CAAC,EAAE,SAAS,EACzB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,CAmB/B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,GAAG,OAAO,EAC1B,aAAa,CAAC,EAAE,SAAS,EACzB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAsBlB"}
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { SerializationError } from '@workflow/errors';
|
|
8
8
|
import { devalueCodec } from './codec-devalue.js';
|
|
9
|
+
import { compress, decompress } from './compression.js';
|
|
9
10
|
import { decrypt as decryptData, encrypt as encryptData, } from './encryption.js';
|
|
10
11
|
import { formatSerializationError, rethrowIfRuntimeError } from './errors.js';
|
|
11
12
|
import { decodeFormatPrefix, encodeWithFormatPrefix } from './format.js';
|
|
@@ -17,7 +18,9 @@ export async function serialize(value, encryptionKey, options) {
|
|
|
17
18
|
try {
|
|
18
19
|
const payload = devalueCodec.serialize(value, 'client', options);
|
|
19
20
|
const prefixed = encodeWithFormatPrefix(SerializationFormat.DEVALUE_V1, payload);
|
|
20
|
-
|
|
21
|
+
// Compress before encrypting — encrypted bytes don't compress.
|
|
22
|
+
const compressed = await compress(prefixed, options?.compression === true, options?.compressionStats);
|
|
23
|
+
return encryptData(compressed, encryptionKey);
|
|
21
24
|
}
|
|
22
25
|
catch (error) {
|
|
23
26
|
rethrowIfRuntimeError(error);
|
|
@@ -29,7 +32,7 @@ export async function serialize(value, encryptionKey, options) {
|
|
|
29
32
|
* Deserialize a value for the client environment (e.g. workflow return value).
|
|
30
33
|
*/
|
|
31
34
|
export async function deserialize(data, encryptionKey, options) {
|
|
32
|
-
const decrypted = await decryptData(data, encryptionKey);
|
|
35
|
+
const decrypted = await decompress(await decryptData(data, encryptionKey), options?.compressionStats);
|
|
33
36
|
if (!(decrypted instanceof Uint8Array)) {
|
|
34
37
|
if (devalueCodec.deserializeLegacy) {
|
|
35
38
|
return devalueCodec.deserializeLegacy(decrypted, 'client', options);
|
|
@@ -42,4 +45,4 @@ export async function deserialize(data, encryptionKey, options) {
|
|
|
42
45
|
}
|
|
43
46
|
throw new Error(`Unsupported serialization format: ${format}`);
|
|
44
47
|
}
|
|
45
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
48
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xpZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL3NlcmlhbGl6YXRpb24vY2xpZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7OztHQUtHO0FBRUgsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDeEQsT0FBTyxFQUVMLE9BQU8sSUFBSSxXQUFXLEVBQ3RCLE9BQU8sSUFBSSxXQUFXLEdBQ3ZCLE1BQU0saUJBQWlCLENBQUM7QUFDekIsT0FBTyxFQUFFLHdCQUF3QixFQUFFLHFCQUFxQixFQUFFLE1BQU0sYUFBYSxDQUFDO0FBQzlFLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxzQkFBc0IsRUFBRSxNQUFNLGFBQWEsQ0FBQztBQUN6RSxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFakQ7O0dBRUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFNBQVMsQ0FDN0IsS0FBYyxFQUNkLGFBQXlCLEVBQ3pCLE9BQXNCO0lBRXRCLElBQUksQ0FBQztRQUNILE1BQU0sT0FBTyxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUNqRSxNQUFNLFFBQVEsR0FBRyxzQkFBc0IsQ0FDckMsbUJBQW1CLENBQUMsVUFBVSxFQUM5QixPQUFPLENBQ00sQ0FBQztRQUNoQiwrREFBK0Q7UUFDL0QsTUFBTSxVQUFVLEdBQUcsTUFBTSxRQUFRLENBQy9CLFFBQVEsRUFDUixPQUFPLEVBQUUsV0FBVyxLQUFLLElBQUksRUFDN0IsT0FBTyxFQUFFLGdCQUFnQixDQUMxQixDQUFDO1FBQ0YsT0FBTyxXQUFXLENBQUMsVUFBVSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1FBQ2YscUJBQXFCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDN0IsTUFBTSxFQUFFLE9BQU8sRUFBRSxJQUFJLEVBQUUsR0FBRyx3QkFBd0IsQ0FBQyxjQUFjLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDMUUsTUFBTSxJQUFJLGtCQUFrQixDQUFDLE9BQU8sRUFBRSxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztJQUNoRSxDQUFDO0FBQ0gsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQy9CLElBQTBCLEVBQzFCLGFBQXlCLEVBQ3pCLE9BQXNCO0lBRXRCLE1BQU0sU0FBUyxHQUFHLE1BQU0sVUFBVSxDQUNoQyxNQUFNLFdBQVcsQ0FBQyxJQUFJLEVBQUUsYUFBYSxDQUFDLEVBQ3RDLE9BQU8sRUFBRSxnQkFBZ0IsQ0FDMUIsQ0FBQztJQUVGLElBQUksQ0FBQyxDQUFDLFNBQVMsWUFBWSxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQ3ZDLElBQUksWUFBWSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDbkMsT0FBTyxZQUFZLENBQUMsaUJBQWlCLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN0RSxDQUFDO1FBQ0QsTUFBTSxJQUFJLEtBQUssQ0FDYiwyREFBMkQsQ0FDNUQsQ0FBQztJQUNKLENBQUM7SUFFRCxNQUFNLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLGtCQUFrQixDQUFDLFNBQVMsQ0FBQyxDQUFDO0lBRTFELElBQUksTUFBTSxLQUFLLG1CQUFtQixDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQzlDLE9BQU8sWUFBWSxDQUFDLFdBQVcsQ0FBQyxPQUFPLEVBQUUsUUFBUSxFQUFFLE9BQU8sQ0FBQyxDQUFDO0lBQzlELENBQUM7SUFFRCxNQUFNLElBQUksS0FBSyxDQUFDLHFDQUFxQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO0FBQ2pFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIENsaWVudCAoZXh0ZXJuYWwpIG1vZGUgc2VyaWFsaXphdGlvbi5cbiAqXG4gKiBVc2VkIHdoZW4gc3RhcnRpbmcgd29ya2Zsb3dzIGZyb20gdGhlIGNsaWVudCBzaWRlIChzZXJpYWxpemluZyB3b3JrZmxvd1xuICogYXJndW1lbnRzKSBhbmQgd2hlbiByZWNlaXZpbmcgd29ya2Zsb3cgcmV0dXJuIHZhbHVlcy4gU3VwcG9ydHMgZW5jcnlwdGlvbi5cbiAqL1xuXG5pbXBvcnQgeyBTZXJpYWxpemF0aW9uRXJyb3IgfSBmcm9tICdAd29ya2Zsb3cvZXJyb3JzJztcbmltcG9ydCB0eXBlIHsgQ29kZWNPcHRpb25zIH0gZnJvbSAnLi9jb2RlYy5qcyc7XG5pbXBvcnQgeyBkZXZhbHVlQ29kZWMgfSBmcm9tICcuL2NvZGVjLWRldmFsdWUuanMnO1xuaW1wb3J0IHsgY29tcHJlc3MsIGRlY29tcHJlc3MgfSBmcm9tICcuL2NvbXByZXNzaW9uLmpzJztcbmltcG9ydCB7XG4gIHR5cGUgQ3J5cHRvS2V5LFxuICBkZWNyeXB0IGFzIGRlY3J5cHREYXRhLFxuICBlbmNyeXB0IGFzIGVuY3J5cHREYXRhLFxufSBmcm9tICcuL2VuY3J5cHRpb24uanMnO1xuaW1wb3J0IHsgZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yLCByZXRocm93SWZSdW50aW1lRXJyb3IgfSBmcm9tICcuL2Vycm9ycy5qcyc7XG5pbXBvcnQgeyBkZWNvZGVGb3JtYXRQcmVmaXgsIGVuY29kZVdpdGhGb3JtYXRQcmVmaXggfSBmcm9tICcuL2Zvcm1hdC5qcyc7XG5pbXBvcnQgeyBTZXJpYWxpemF0aW9uRm9ybWF0IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKlxuICogU2VyaWFsaXplIGEgdmFsdWUgZnJvbSB0aGUgY2xpZW50IGVudmlyb25tZW50IChlLmcuIHdvcmtmbG93IGFyZ3VtZW50cykuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXJpYWxpemUoXG4gIHZhbHVlOiB1bmtub3duLFxuICBlbmNyeXB0aW9uS2V5PzogQ3J5cHRvS2V5LFxuICBvcHRpb25zPzogQ29kZWNPcHRpb25zXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIHRyeSB7XG4gICAgY29uc3QgcGF5bG9hZCA9IGRldmFsdWVDb2RlYy5zZXJpYWxpemUodmFsdWUsICdjbGllbnQnLCBvcHRpb25zKTtcbiAgICBjb25zdCBwcmVmaXhlZCA9IGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoXG4gICAgICBTZXJpYWxpemF0aW9uRm9ybWF0LkRFVkFMVUVfVjEsXG4gICAgICBwYXlsb2FkXG4gICAgKSBhcyBVaW50OEFycmF5O1xuICAgIC8vIENvbXByZXNzIGJlZm9yZSBlbmNyeXB0aW5nIOKAlCBlbmNyeXB0ZWQgYnl0ZXMgZG9uJ3QgY29tcHJlc3MuXG4gICAgY29uc3QgY29tcHJlc3NlZCA9IGF3YWl0IGNvbXByZXNzKFxuICAgICAgcHJlZml4ZWQsXG4gICAgICBvcHRpb25zPy5jb21wcmVzc2lvbiA9PT0gdHJ1ZSxcbiAgICAgIG9wdGlvbnM/LmNvbXByZXNzaW9uU3RhdHNcbiAgICApO1xuICAgIHJldHVybiBlbmNyeXB0RGF0YShjb21wcmVzc2VkLCBlbmNyeXB0aW9uS2V5KTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICByZXRocm93SWZSdW50aW1lRXJyb3IoZXJyb3IpO1xuICAgIGNvbnN0IHsgbWVzc2FnZSwgaGludCB9ID0gZm9ybWF0U2VyaWFsaXphdGlvbkVycm9yKCdjbGllbnQgdmFsdWUnLCBlcnJvcik7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihtZXNzYWdlLCB7IGhpbnQsIGNhdXNlOiBlcnJvciB9KTtcbiAgfVxufVxuXG4vKipcbiAqIERlc2VyaWFsaXplIGEgdmFsdWUgZm9yIHRoZSBjbGllbnQgZW52aXJvbm1lbnQgKGUuZy4gd29ya2Zsb3cgcmV0dXJuIHZhbHVlKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlc2VyaWFsaXplKFxuICBkYXRhOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgZW5jcnlwdGlvbktleT86IENyeXB0b0tleSxcbiAgb3B0aW9ucz86IENvZGVjT3B0aW9uc1xuKTogUHJvbWlzZTx1bmtub3duPiB7XG4gIGNvbnN0IGRlY3J5cHRlZCA9IGF3YWl0IGRlY29tcHJlc3MoXG4gICAgYXdhaXQgZGVjcnlwdERhdGEoZGF0YSwgZW5jcnlwdGlvbktleSksXG4gICAgb3B0aW9ucz8uY29tcHJlc3Npb25TdGF0c1xuICApO1xuXG4gIGlmICghKGRlY3J5cHRlZCBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpKSB7XG4gICAgaWYgKGRldmFsdWVDb2RlYy5kZXNlcmlhbGl6ZUxlZ2FjeSkge1xuICAgICAgcmV0dXJuIGRldmFsdWVDb2RlYy5kZXNlcmlhbGl6ZUxlZ2FjeShkZWNyeXB0ZWQsICdjbGllbnQnLCBvcHRpb25zKTtcbiAgICB9XG4gICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgJ0Nhbm5vdCBkZXNlcmlhbGl6ZSBub24tYmluYXJ5IGRhdGEgd2l0aG91dCBsZWdhY3kgc3VwcG9ydCdcbiAgICApO1xuICB9XG5cbiAgY29uc3QgeyBmb3JtYXQsIHBheWxvYWQgfSA9IGRlY29kZUZvcm1hdFByZWZpeChkZWNyeXB0ZWQpO1xuXG4gIGlmIChmb3JtYXQgPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuREVWQUxVRV9WMSkge1xuICAgIHJldHVybiBkZXZhbHVlQ29kZWMuZGVzZXJpYWxpemUocGF5bG9hZCwgJ2NsaWVudCcsIG9wdGlvbnMpO1xuICB9XG5cbiAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBzZXJpYWxpemF0aW9uIGZvcm1hdDogJHtmb3JtYXR9YCk7XG59XG4iXX0=
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* - **json**: Would only support standard JSON types (primitives, arrays,
|
|
14
14
|
* plain objects). No Date, Map, Set, typed arrays, etc.
|
|
15
15
|
*/
|
|
16
|
+
import type { CompressionStats } from './compression.js';
|
|
16
17
|
import type { FormatPrefix } from './types.js';
|
|
17
18
|
/**
|
|
18
19
|
* The serialization mode determines which types are supported and how
|
|
@@ -49,6 +50,21 @@ export interface CodecOptions {
|
|
|
49
50
|
* or other mode-specific type revivers.
|
|
50
51
|
*/
|
|
51
52
|
extraRevivers?: Record<string, (value: any) => any>;
|
|
53
|
+
/**
|
|
54
|
+
* Whether to gzip-compress the serialized payload (write side only;
|
|
55
|
+
* reads always handle both compressed and uncompressed data). Must
|
|
56
|
+
* only be enabled when the target run supports compressed payloads:
|
|
57
|
+
* run specVersion >= SPEC_VERSION_SUPPORTS_COMPRESSION, and for
|
|
58
|
+
* cross-deployment writes the target deployment's capabilities (see
|
|
59
|
+
* `getRunCapabilities` in capabilities.ts). Defaults to `false`.
|
|
60
|
+
*/
|
|
61
|
+
compression?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* Optional telemetry sink populated by the compression layer with what
|
|
64
|
+
* it did to the payload (whether it compressed, logical vs stored size).
|
|
65
|
+
* Used by the dehydrate/hydrate wrappers to emit OTel span attributes.
|
|
66
|
+
*/
|
|
67
|
+
compressionStats?: CompressionStats;
|
|
52
68
|
}
|
|
53
69
|
export interface Codec {
|
|
54
70
|
/** The 4-character format prefix identifier (e.g. "devl", "cbor", "json") */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/serialization/codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE7B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;IAEpD;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"codec.d.ts","sourceRoot":"","sources":["../../src/serialization/codec.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C;;;;;;;;;;GAUG;AACH,MAAM,MAAM,iBAAiB,GAAG,UAAU,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE/D;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B;;;;OAIG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAE7B;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;IAEpD;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,CAAC,CAAC;IAEpD;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;IAEtB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC;AAED,MAAM,WAAW,KAAK;IACpB,6EAA6E;IAC7E,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAC;IAEpC;;;;;;;;;OASG;IACH,SAAS,CACP,KAAK,EAAE,OAAO,EACd,IAAI,EAAE,iBAAiB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,UAAU,CAAC;IAEd;;;;;;;;;OASG;IACH,WAAW,CACT,IAAI,EAAE,UAAU,EAChB,IAAI,EAAE,iBAAiB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC;IAEX;;;;;;;;;OASG;IACH,iBAAiB,CAAC,CAChB,IAAI,EAAE,OAAO,EACb,IAAI,EAAE,iBAAiB,EACvB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC;CACZ"}
|
|
@@ -14,4 +14,4 @@
|
|
|
14
14
|
* plain objects). No Date, Map, Set, typed arrays, etc.
|
|
15
15
|
*/
|
|
16
16
|
export {};
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
17
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29kZWMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VyaWFsaXphdGlvbi9jb2RlYy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7R0FjRyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29kZWMgaW50ZXJmYWNlIGZvciBzZXJpYWxpemF0aW9uIGZvcm1hdHMuXG4gKlxuICogQSBjb2RlYyBoYW5kbGVzIHRoZSBjb3JlIHNlcmlhbGl6ZS9kZXNlcmlhbGl6ZSBsb2dpYyBmb3IgYSBzcGVjaWZpY1xuICogd2lyZSBmb3JtYXQgKGRldmFsdWUsIENCT1IsIEpTT04sIGV0Yy4pLiBFYWNoIGNvZGVjIGlzIHJlc3BvbnNpYmxlXG4gKiBmb3IgaGFuZGxpbmcgYWxsIHN1cHBvcnRlZCBkYXRhIHR5cGVzIGludGVybmFsbHkg4oCUIHRoZSBjYWxsZXIgb25seVxuICogc3BlY2lmaWVzIHdoaWNoIHNlcmlhbGl6YXRpb24gbW9kZSB0byB1c2UuXG4gKlxuICogLSAqKmRldmFsdWUqKjogVXNlcyBjdXN0b20gcmVkdWNlcnMvcmV2aXZlcnMgZm9yIERhdGUsIEVycm9yLCBNYXAsIFNldCxcbiAqICAgdHlwZWQgYXJyYXlzLCBjbGFzcyBpbnN0YW5jZXMsIGV0Yy5cbiAqIC0gKipjYm9yKio6IFdvdWxkIGhhbmRsZSBEYXRlLCB0eXBlZCBhcnJheXMsIE1hcCwgU2V0IG5hdGl2ZWx5IHZpYSB0aGVcbiAqICAgQ0JPUiB0eXBlIHN5c3RlbS4gQ2xhc3MgaW5zdGFuY2VzIHdvdWxkIHN0aWxsIG5lZWQgY3VzdG9tIGhhbmRsaW5nLlxuICogLSAqKmpzb24qKjogV291bGQgb25seSBzdXBwb3J0IHN0YW5kYXJkIEpTT04gdHlwZXMgKHByaW1pdGl2ZXMsIGFycmF5cyxcbiAqICAgcGxhaW4gb2JqZWN0cykuIE5vIERhdGUsIE1hcCwgU2V0LCB0eXBlZCBhcnJheXMsIGV0Yy5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IENvbXByZXNzaW9uU3RhdHMgfSBmcm9tICcuL2NvbXByZXNzaW9uLmpzJztcbmltcG9ydCB0eXBlIHsgRm9ybWF0UHJlZml4IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5cbi8qKlxuICogVGhlIHNlcmlhbGl6YXRpb24gbW9kZSBkZXRlcm1pbmVzIHdoaWNoIHR5cGVzIGFyZSBzdXBwb3J0ZWQgYW5kIGhvd1xuICogdGhleSdyZSBoYW5kbGVkLiBEaWZmZXJlbnQgbW9kZXMgY29tcG9zZSBkaWZmZXJlbnQgc2V0cyBvZiB0eXBlIGhhbmRsZXJzLlxuICpcbiAqIC0gYHdvcmtmbG93YDogUnVucyBpbnNpZGUgdGhlIHdvcmtmbG93IFZNLiBJbmNsdWRlcyBjbGFzcyBzZXJpYWxpemF0aW9uLFxuICogICBzdGVwIGZ1bmN0aW9uIHNlcmlhbGl6YXRpb24uIE5vIHN0cmVhbSBoYW5kbGluZy5cbiAqIC0gYHN0ZXBgOiBSdW5zIGluIHRoZSBzdGVwIGhhbmRsZXIgKE5vZGUuanMpLiBJbmNsdWRlcyBjbGFzcyBzZXJpYWxpemF0aW9uLlxuICogICBObyBzdGVwIGZ1bmN0aW9uIHNlcmlhbGl6YXRpb24uIFN0cmVhbSBoYW5kbGluZyBhdCBjYWxsIHNpdGVzLlxuICogLSBgY2xpZW50YDogUnVucyBvbiB0aGUgY2xpZW50IHNpZGUuIEluY2x1ZGVzIGNsYXNzIHNlcmlhbGl6YXRpb24uXG4gKiAgIE5vIHN0ZXAgZnVuY3Rpb24gc2VyaWFsaXphdGlvbi4gU3RyZWFtIGhhbmRsaW5nIGF0IGNhbGwgc2l0ZXMuXG4gKi9cbmV4cG9ydCB0eXBlIFNlcmlhbGl6YXRpb25Nb2RlID0gJ3dvcmtmbG93JyB8ICdzdGVwJyB8ICdjbGllbnQnO1xuXG4vKipcbiAqIE9wdGlvbnMgcGFzc2VkIHRvIGNvZGVjIHNlcmlhbGl6ZS9kZXNlcmlhbGl6ZSB0byBzdXBwb3J0IFZNLWNvbnRleHRcbiAqIHNlcmlhbGl6YXRpb24gYW5kIG1vZGUtc3BlY2lmaWMgdHlwZSBoYW5kbGluZy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb2RlY09wdGlvbnMge1xuICAvKipcbiAgICogVGhlIGdsb2JhbCBvYmplY3QgdG8gdXNlIGZvciBgaW5zdGFuY2VvZmAgY2hlY2tzIGFuZCBjb25zdHJ1Y3RvcnMuXG4gICAqIERlZmF1bHRzIHRvIGBnbG9iYWxUaGlzYC4gTXVzdCBiZSBzZXQgdG8gdGhlIFZNJ3MgZ2xvYmFsIHdoZW5cbiAgICogc2VyaWFsaXppbmcvZGVzZXJpYWxpemluZyBkYXRhIHRoYXQgY3Jvc3NlcyBWTSBib3VuZGFyaWVzLlxuICAgKi9cbiAgZ2xvYmFsPzogUmVjb3JkPHN0cmluZywgYW55PjtcblxuICAvKipcbiAgICogQWRkaXRpb25hbCByZWR1Y2VycyB0byBtZXJnZSBpbnRvIHRoZSBtb2RlJ3MgZGVmYXVsdCByZWR1Y2Vycy5cbiAgICogVXNlZCBieSBkZWh5ZHJhdGUvaHlkcmF0ZSBmdW5jdGlvbnMgdGhhdCBuZWVkIHN0cmVhbSBoYW5kbGluZ1xuICAgKiBvciBvdGhlciBtb2RlLXNwZWNpZmljIHR5cGUgcmVkdWNlcnMuXG4gICAqL1xuICBleHRyYVJlZHVjZXJzPzogUmVjb3JkPHN0cmluZywgKHZhbHVlOiBhbnkpID0+IGFueT47XG5cbiAgLyoqXG4gICAqIEFkZGl0aW9uYWwgcmV2aXZlcnMgdG8gbWVyZ2UgaW50byB0aGUgbW9kZSdzIGRlZmF1bHQgcmV2aXZlcnMuXG4gICAqIFVzZWQgYnkgZGVoeWRyYXRlL2h5ZHJhdGUgZnVuY3Rpb25zIHRoYXQgbmVlZCBzdHJlYW0gaGFuZGxpbmdcbiAgICogb3Igb3RoZXIgbW9kZS1zcGVjaWZpYyB0eXBlIHJldml2ZXJzLlxuICAgKi9cbiAgZXh0cmFSZXZpdmVycz86IFJlY29yZDxzdHJpbmcsICh2YWx1ZTogYW55KSA9PiBhbnk+O1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGd6aXAtY29tcHJlc3MgdGhlIHNlcmlhbGl6ZWQgcGF5bG9hZCAod3JpdGUgc2lkZSBvbmx5O1xuICAgKiByZWFkcyBhbHdheXMgaGFuZGxlIGJvdGggY29tcHJlc3NlZCBhbmQgdW5jb21wcmVzc2VkIGRhdGEpLiBNdXN0XG4gICAqIG9ubHkgYmUgZW5hYmxlZCB3aGVuIHRoZSB0YXJnZXQgcnVuIHN1cHBvcnRzIGNvbXByZXNzZWQgcGF5bG9hZHM6XG4gICAqIHJ1biBzcGVjVmVyc2lvbiA+PSBTUEVDX1ZFUlNJT05fU1VQUE9SVFNfQ09NUFJFU1NJT04sIGFuZCBmb3JcbiAgICogY3Jvc3MtZGVwbG95bWVudCB3cml0ZXMgdGhlIHRhcmdldCBkZXBsb3ltZW50J3MgY2FwYWJpbGl0aWVzIChzZWVcbiAgICogYGdldFJ1bkNhcGFiaWxpdGllc2AgaW4gY2FwYWJpbGl0aWVzLnRzKS4gRGVmYXVsdHMgdG8gYGZhbHNlYC5cbiAgICovXG4gIGNvbXByZXNzaW9uPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogT3B0aW9uYWwgdGVsZW1ldHJ5IHNpbmsgcG9wdWxhdGVkIGJ5IHRoZSBjb21wcmVzc2lvbiBsYXllciB3aXRoIHdoYXRcbiAgICogaXQgZGlkIHRvIHRoZSBwYXlsb2FkICh3aGV0aGVyIGl0IGNvbXByZXNzZWQsIGxvZ2ljYWwgdnMgc3RvcmVkIHNpemUpLlxuICAgKiBVc2VkIGJ5IHRoZSBkZWh5ZHJhdGUvaHlkcmF0ZSB3cmFwcGVycyB0byBlbWl0IE9UZWwgc3BhbiBhdHRyaWJ1dGVzLlxuICAgKi9cbiAgY29tcHJlc3Npb25TdGF0cz86IENvbXByZXNzaW9uU3RhdHM7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ29kZWMge1xuICAvKiogVGhlIDQtY2hhcmFjdGVyIGZvcm1hdCBwcmVmaXggaWRlbnRpZmllciAoZS5nLiBcImRldmxcIiwgXCJjYm9yXCIsIFwianNvblwiKSAqL1xuICByZWFkb25seSBmb3JtYXRQcmVmaXg6IEZvcm1hdFByZWZpeDtcblxuICAvKipcbiAgICogU2VyaWFsaXplIGEgdmFsdWUgdG8gYnl0ZXMuXG4gICAqXG4gICAqIFRoZSBjb2RlYyBoYW5kbGVzIGFsbCBzdXBwb3J0ZWQgdHlwZXMgaW50ZXJuYWxseSBiYXNlZCBvbiB0aGUgbW9kZS5cbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIC0gVGhlIHZhbHVlIHRvIHNlcmlhbGl6ZVxuICAgKiBAcGFyYW0gbW9kZSAtIFRoZSBzZXJpYWxpemF0aW9uIG1vZGVcbiAgICogQHBhcmFtIG9wdGlvbnMgLSBPcHRpb25hbCBnbG9iYWwsIGV4dHJhIHJlZHVjZXJzL3Jldml2ZXJzXG4gICAqIEByZXR1cm5zIFRoZSBzZXJpYWxpemVkIHBheWxvYWQgKHdpdGhvdXQgZm9ybWF0IHByZWZpeClcbiAgICovXG4gIHNlcmlhbGl6ZShcbiAgICB2YWx1ZTogdW5rbm93bixcbiAgICBtb2RlOiBTZXJpYWxpemF0aW9uTW9kZSxcbiAgICBvcHRpb25zPzogQ29kZWNPcHRpb25zXG4gICk6IFVpbnQ4QXJyYXk7XG5cbiAgLyoqXG4gICAqIERlc2VyaWFsaXplIGJ5dGVzIGJhY2sgdG8gYSB2YWx1ZS5cbiAgICpcbiAgICogVGhlIGNvZGVjIGhhbmRsZXMgYWxsIHN1cHBvcnRlZCB0eXBlcyBpbnRlcm5hbGx5IGJhc2VkIG9uIHRoZSBtb2RlLlxuICAgKlxuICAgKiBAcGFyYW0gZGF0YSAtIFRoZSBzZXJpYWxpemVkIHBheWxvYWQgKHdpdGhvdXQgZm9ybWF0IHByZWZpeClcbiAgICogQHBhcmFtIG1vZGUgLSBUaGUgc2VyaWFsaXphdGlvbiBtb2RlXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwgZ2xvYmFsLCBleHRyYSByZXZpdmVyc1xuICAgKiBAcmV0dXJucyBUaGUgZGVzZXJpYWxpemVkIHZhbHVlXG4gICAqL1xuICBkZXNlcmlhbGl6ZShcbiAgICBkYXRhOiBVaW50OEFycmF5LFxuICAgIG1vZGU6IFNlcmlhbGl6YXRpb25Nb2RlLFxuICAgIG9wdGlvbnM/OiBDb2RlY09wdGlvbnNcbiAgKTogdW5rbm93bjtcblxuICAvKipcbiAgICogRGVzZXJpYWxpemUgbGVnYWN5IChwcmUtZm9ybWF0LXByZWZpeCkgZGF0YS5cbiAgICogVXNlZCBmb3IgYmFja3dhcmRzIGNvbXBhdGliaWxpdHkgd2l0aCBzcGVjVmVyc2lvbiAxIHJ1bnMgdGhhdCBzdG9yZWRcbiAgICogZGF0YSBhcyBwbGFpbiBKU09OIGFycmF5cyBpbnN0ZWFkIG9mIGJpbmFyeS5cbiAgICpcbiAgICogQHBhcmFtIGRhdGEgLSBUaGUgbGVnYWN5IGRhdGFcbiAgICogQHBhcmFtIG1vZGUgLSBUaGUgc2VyaWFsaXphdGlvbiBtb2RlXG4gICAqIEBwYXJhbSBvcHRpb25zIC0gT3B0aW9uYWwgZ2xvYmFsLCBleHRyYSByZXZpdmVyc1xuICAgKiBAcmV0dXJucyBUaGUgZGVzZXJpYWxpemVkIHZhbHVlXG4gICAqL1xuICBkZXNlcmlhbGl6ZUxlZ2FjeT8oXG4gICAgZGF0YTogdW5rbm93bixcbiAgICBtb2RlOiBTZXJpYWxpemF0aW9uTW9kZSxcbiAgICBvcHRpb25zPzogQ29kZWNPcHRpb25zXG4gICk6IHVua25vd247XG59XG4iXX0=
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable compression layer for serialized data.
|
|
3
|
+
*
|
|
4
|
+
* Wraps/unwraps serialized payloads with a compression codec, using the
|
|
5
|
+
* format prefix system to mark compressed data (e.g. 'zstd' or 'gzip'
|
|
6
|
+
* wrapping the inner format: 'zstd' + zstd('devl' + payload)).
|
|
7
|
+
*
|
|
8
|
+
* Codec selection (write side): zstd is preferred — it is markedly faster
|
|
9
|
+
* than gzip at a comparable-or-better ratio (see scripts/README.md), and
|
|
10
|
+
* compression runs at every step boundary so the write CPU is a per-step
|
|
11
|
+
* tax. zstd requires `node:zlib` >= 22.15 (Web `CompressionStream` has no
|
|
12
|
+
* zstd), so on a runtime without it we fall back to gzip via the portable
|
|
13
|
+
* `CompressionStream`. `WORKFLOW_COMPRESSION_CODEC=gzip` forces the
|
|
14
|
+
* portable codec.
|
|
15
|
+
*
|
|
16
|
+
* Read side: dispatch on the format prefix, so both 'zstd' and 'gzip'
|
|
17
|
+
* payloads are always decodable regardless of which codec wrote them.
|
|
18
|
+
* (The browser o11y read path decodes zstd via a registered WASM decoder —
|
|
19
|
+
* see `serialization-format.ts`; this module's `decompress` is the Node
|
|
20
|
+
* runtime/replay path and uses `node:zlib`.)
|
|
21
|
+
*
|
|
22
|
+
* Layering order with encryption: compression is applied BEFORE
|
|
23
|
+
* encryption (encr(zstd(devl))) — encrypted bytes are high-entropy and
|
|
24
|
+
* do not compress, so the reverse order would be a no-op.
|
|
25
|
+
*
|
|
26
|
+
* Compression is conditional:
|
|
27
|
+
* - Payloads smaller than {@link COMPRESSION_MIN_BYTES} are passed
|
|
28
|
+
* through unchanged (codec overhead isn't worth it).
|
|
29
|
+
* - If the compressed result isn't meaningfully smaller than the
|
|
30
|
+
* original (see {@link COMPRESSION_MIN_SAVINGS_RATIO}), the original
|
|
31
|
+
* is kept. This protects already-compressed binary payloads (images,
|
|
32
|
+
* archives, etc.) from wasted CPU and size inflation.
|
|
33
|
+
*/
|
|
34
|
+
/**
|
|
35
|
+
* Payloads below this size are never compressed. The 4-byte format
|
|
36
|
+
* prefix + codec header/trailer overhead means small payloads gain
|
|
37
|
+
* nothing, and tiny ones would grow.
|
|
38
|
+
*/
|
|
39
|
+
export declare const COMPRESSION_MIN_BYTES = 1024;
|
|
40
|
+
/**
|
|
41
|
+
* Compression must shave off at least this fraction of the payload
|
|
42
|
+
* size to be kept; otherwise the uncompressed original is stored.
|
|
43
|
+
* Guards against incompressible (already-compressed / high-entropy)
|
|
44
|
+
* data paying a permanent decompression tax for a negligible win.
|
|
45
|
+
*/
|
|
46
|
+
export declare const COMPRESSION_MIN_SAVINGS_RATIO = 0.05;
|
|
47
|
+
/** Which codec compressed a payload (or `none` when stored uncompressed). */
|
|
48
|
+
export type CompressionCodec = 'zstd' | 'gzip' | 'none';
|
|
49
|
+
/**
|
|
50
|
+
* Telemetry sink describing what the compression layer did to a payload.
|
|
51
|
+
* Populated by {@link compress} (write) and {@link decompress} (read) when
|
|
52
|
+
* a `stats` object is passed. Sizes are measured at the compression
|
|
53
|
+
* boundary — i.e. before encryption is layered on the write side and after
|
|
54
|
+
* decryption on the read side — so they reflect compression's effect, not
|
|
55
|
+
* the at-rest size (which also includes the `encr` envelope and, on some
|
|
56
|
+
* backends, base64 expansion).
|
|
57
|
+
*
|
|
58
|
+
* Field meanings are identical for both directions:
|
|
59
|
+
* - `uncompressedBytes`: the logical (devalue-prefixed) payload size.
|
|
60
|
+
* - `storedBytes`: the size handed to / read from storage (compressed when
|
|
61
|
+
* a codec applied, otherwise equal to `uncompressedBytes`).
|
|
62
|
+
* - `codec`: which codec applied (`none` when stored uncompressed).
|
|
63
|
+
*/
|
|
64
|
+
export interface CompressionStats {
|
|
65
|
+
/** True once the compression layer ran (i.e. saw binary data). */
|
|
66
|
+
recorded?: boolean;
|
|
67
|
+
/** Whether a codec was applied (write) or present (read). */
|
|
68
|
+
compressed?: boolean;
|
|
69
|
+
/** Which codec applied / was present. */
|
|
70
|
+
codec?: CompressionCodec;
|
|
71
|
+
/** Logical, uncompressed payload size in bytes. */
|
|
72
|
+
uncompressedBytes?: number;
|
|
73
|
+
/** Stored (post-compression) payload size in bytes. */
|
|
74
|
+
storedBytes?: number;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Compress a format-prefixed payload if compression is enabled for the
|
|
78
|
+
* target run and the payload is worth compressing.
|
|
79
|
+
*
|
|
80
|
+
* @param data - The format-prefixed serialized data (e.g. 'devl' + bytes)
|
|
81
|
+
* @param enabled - Whether the target run supports compressed payloads
|
|
82
|
+
* (run specVersion >= SPEC_VERSION_SUPPORTS_COMPRESSION, and for
|
|
83
|
+
* cross-deployment writes, the target deployment's capabilities —
|
|
84
|
+
* see `getRunCapabilities` in capabilities.ts). zstd and gzip read
|
|
85
|
+
* support co-ship, so a single boolean is sufficient.
|
|
86
|
+
* @param stats - Optional telemetry sink; populated when `data` is binary.
|
|
87
|
+
* @returns The compressed data with a codec prefix, or the original data
|
|
88
|
+
* when compression is disabled, unavailable, or not worthwhile.
|
|
89
|
+
*/
|
|
90
|
+
export declare function compress(data: Uint8Array | unknown, enabled: boolean, stats?: CompressionStats): Promise<Uint8Array | unknown>;
|
|
91
|
+
/**
|
|
92
|
+
* Decompress a format-prefixed payload if it's compressed.
|
|
93
|
+
* Dispatches on the prefix ('zstd' or 'gzip') and inflates the inner
|
|
94
|
+
* payload (which carries its own format prefix, e.g. 'devl').
|
|
95
|
+
*
|
|
96
|
+
* Non-compressed data (including non-binary legacy data) is returned
|
|
97
|
+
* unchanged, so this is safe to apply unconditionally on read paths.
|
|
98
|
+
*/
|
|
99
|
+
export declare function decompress(data: Uint8Array | unknown, stats?: CompressionStats): Promise<Uint8Array | unknown>;
|
|
100
|
+
/**
|
|
101
|
+
* Check if data is compressed (has a 'zstd' or 'gzip' format prefix).
|
|
102
|
+
*/
|
|
103
|
+
export declare function isCompressed(data: Uint8Array | unknown): boolean;
|
|
104
|
+
//# sourceMappingURL=compression.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"compression.d.ts","sourceRoot":"","sources":["../../src/serialization/compression.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AASH;;;;GAIG;AACH,eAAO,MAAM,qBAAqB,OAAO,CAAC;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B,OAAO,CAAC;AAKlD,6EAA6E;AAC7E,MAAM,MAAM,gBAAgB,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,CAAC;AA4IxD;;;;;;;;;;;;;;GAcG;AACH,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6DAA6D;IAC7D,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,yCAAyC;IACzC,KAAK,CAAC,EAAE,gBAAgB,CAAC;IACzB,mDAAmD;IACnD,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,uDAAuD;IACvD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA6BD;;;;;;;;;;;;;GAaG;AACH,wBAAsB,QAAQ,CAC5B,IAAI,EAAE,UAAU,GAAG,OAAO,EAC1B,OAAO,EAAE,OAAO,EAChB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,CA4B/B;AAED;;;;;;;GAOG;AACH,wBAAsB,UAAU,CAC9B,IAAI,EAAE,UAAU,GAAG,OAAO,EAC1B,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,CA2B/B;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,GAAG,OAAO,CAKhE"}
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Composable compression layer for serialized data.
|
|
3
|
+
*
|
|
4
|
+
* Wraps/unwraps serialized payloads with a compression codec, using the
|
|
5
|
+
* format prefix system to mark compressed data (e.g. 'zstd' or 'gzip'
|
|
6
|
+
* wrapping the inner format: 'zstd' + zstd('devl' + payload)).
|
|
7
|
+
*
|
|
8
|
+
* Codec selection (write side): zstd is preferred — it is markedly faster
|
|
9
|
+
* than gzip at a comparable-or-better ratio (see scripts/README.md), and
|
|
10
|
+
* compression runs at every step boundary so the write CPU is a per-step
|
|
11
|
+
* tax. zstd requires `node:zlib` >= 22.15 (Web `CompressionStream` has no
|
|
12
|
+
* zstd), so on a runtime without it we fall back to gzip via the portable
|
|
13
|
+
* `CompressionStream`. `WORKFLOW_COMPRESSION_CODEC=gzip` forces the
|
|
14
|
+
* portable codec.
|
|
15
|
+
*
|
|
16
|
+
* Read side: dispatch on the format prefix, so both 'zstd' and 'gzip'
|
|
17
|
+
* payloads are always decodable regardless of which codec wrote them.
|
|
18
|
+
* (The browser o11y read path decodes zstd via a registered WASM decoder —
|
|
19
|
+
* see `serialization-format.ts`; this module's `decompress` is the Node
|
|
20
|
+
* runtime/replay path and uses `node:zlib`.)
|
|
21
|
+
*
|
|
22
|
+
* Layering order with encryption: compression is applied BEFORE
|
|
23
|
+
* encryption (encr(zstd(devl))) — encrypted bytes are high-entropy and
|
|
24
|
+
* do not compress, so the reverse order would be a no-op.
|
|
25
|
+
*
|
|
26
|
+
* Compression is conditional:
|
|
27
|
+
* - Payloads smaller than {@link COMPRESSION_MIN_BYTES} are passed
|
|
28
|
+
* through unchanged (codec overhead isn't worth it).
|
|
29
|
+
* - If the compressed result isn't meaningfully smaller than the
|
|
30
|
+
* original (see {@link COMPRESSION_MIN_SAVINGS_RATIO}), the original
|
|
31
|
+
* is kept. This protects already-compressed binary payloads (images,
|
|
32
|
+
* archives, etc.) from wasted CPU and size inflation.
|
|
33
|
+
*/
|
|
34
|
+
import { decodeFormatPrefix, encodeWithFormatPrefix, peekFormatPrefix, } from './format.js';
|
|
35
|
+
import { SerializationFormat } from './types.js';
|
|
36
|
+
/**
|
|
37
|
+
* Payloads below this size are never compressed. The 4-byte format
|
|
38
|
+
* prefix + codec header/trailer overhead means small payloads gain
|
|
39
|
+
* nothing, and tiny ones would grow.
|
|
40
|
+
*/
|
|
41
|
+
export const COMPRESSION_MIN_BYTES = 1024;
|
|
42
|
+
/**
|
|
43
|
+
* Compression must shave off at least this fraction of the payload
|
|
44
|
+
* size to be kept; otherwise the uncompressed original is stored.
|
|
45
|
+
* Guards against incompressible (already-compressed / high-entropy)
|
|
46
|
+
* data paying a permanent decompression tax for a negligible win.
|
|
47
|
+
*/
|
|
48
|
+
export const COMPRESSION_MIN_SAVINGS_RATIO = 0.05;
|
|
49
|
+
/** Default zstd compression level — the sweet spot of speed vs ratio. */
|
|
50
|
+
const ZSTD_LEVEL = 3;
|
|
51
|
+
/**
|
|
52
|
+
* Escape hatch: set WORKFLOW_DISABLE_COMPRESSION=1 to disable
|
|
53
|
+
* write-side compression entirely. Reads are unaffected — payloads
|
|
54
|
+
* that were already written compressed remain readable.
|
|
55
|
+
*/
|
|
56
|
+
function isCompressionDisabledByEnv() {
|
|
57
|
+
try {
|
|
58
|
+
return (typeof process !== 'undefined' &&
|
|
59
|
+
process.env?.WORKFLOW_DISABLE_COMPRESSION === '1');
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Optional codec override (`WORKFLOW_COMPRESSION_CODEC=gzip|zstd`). Lets an
|
|
67
|
+
* operator pin the portable codec (gzip) — useful for A/B comparisons or
|
|
68
|
+
* runtimes where zstd read support isn't yet everywhere.
|
|
69
|
+
*/
|
|
70
|
+
function codecOverrideFromEnv() {
|
|
71
|
+
try {
|
|
72
|
+
const v = process.env?.WORKFLOW_COMPRESSION_CODEC;
|
|
73
|
+
return v === 'gzip' || v === 'zstd' ? v : undefined;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
return undefined;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Resolve `node:zlib` via `process.getBuiltinModule` — no static import, so
|
|
81
|
+
* this module stays bundler-safe for browser/edge targets (where it returns
|
|
82
|
+
* undefined and we fall back to gzip).
|
|
83
|
+
*/
|
|
84
|
+
function getNodeZlib() {
|
|
85
|
+
try {
|
|
86
|
+
return globalThis.process?.getBuiltinModule?.('node:zlib');
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
return undefined;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
function isZstdAvailable() {
|
|
93
|
+
const z = getNodeZlib();
|
|
94
|
+
return (typeof z?.zstdCompressSync === 'function' &&
|
|
95
|
+
typeof z?.zstdDecompressSync === 'function');
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* gzip via the web-standard `CompressionStream` (Node 18+, browsers, edge).
|
|
99
|
+
*/
|
|
100
|
+
function isGzipAvailable() {
|
|
101
|
+
return (typeof CompressionStream === 'function' &&
|
|
102
|
+
typeof DecompressionStream === 'function');
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Pipe bytes through a (De)CompressionStream and collect the output.
|
|
106
|
+
*/
|
|
107
|
+
async function pipeThroughTransform(data, transform) {
|
|
108
|
+
const writer = transform.writable.getWriter();
|
|
109
|
+
// Don't await the write before reading — the transform's internal
|
|
110
|
+
// queue can fill up on large payloads, deadlocking writer vs reader.
|
|
111
|
+
const writePromise = writer.write(data).then(() => writer.close());
|
|
112
|
+
// If the transform errors, the reader.read() below rejects first and
|
|
113
|
+
// propagates; mark the write side as handled so the mirrored rejection
|
|
114
|
+
// doesn't surface as an unhandled rejection.
|
|
115
|
+
writePromise.catch(() => { });
|
|
116
|
+
const chunks = [];
|
|
117
|
+
let total = 0;
|
|
118
|
+
const reader = transform.readable.getReader();
|
|
119
|
+
for (;;) {
|
|
120
|
+
const { done, value } = await reader.read();
|
|
121
|
+
if (done)
|
|
122
|
+
break;
|
|
123
|
+
chunks.push(value);
|
|
124
|
+
total += value.length;
|
|
125
|
+
}
|
|
126
|
+
await writePromise;
|
|
127
|
+
const out = new Uint8Array(total);
|
|
128
|
+
let offset = 0;
|
|
129
|
+
for (const chunk of chunks) {
|
|
130
|
+
out.set(chunk, offset);
|
|
131
|
+
offset += chunk.length;
|
|
132
|
+
}
|
|
133
|
+
return out;
|
|
134
|
+
}
|
|
135
|
+
async function gzipBytes(data) {
|
|
136
|
+
return pipeThroughTransform(data, new CompressionStream('gzip'));
|
|
137
|
+
}
|
|
138
|
+
async function gunzipBytes(data) {
|
|
139
|
+
return pipeThroughTransform(data, new DecompressionStream('gzip'));
|
|
140
|
+
}
|
|
141
|
+
function zstdBytes(data) {
|
|
142
|
+
const z = getNodeZlib();
|
|
143
|
+
const level = z?.constants?.ZSTD_c_compressionLevel;
|
|
144
|
+
const opts = level !== undefined ? { params: { [level]: ZSTD_LEVEL } } : undefined;
|
|
145
|
+
// biome-ignore lint/style/noNonNullAssertion: guarded by isZstdAvailable()
|
|
146
|
+
return new Uint8Array(z.zstdCompressSync(data, opts));
|
|
147
|
+
}
|
|
148
|
+
function unzstdBytes(data) {
|
|
149
|
+
const z = getNodeZlib();
|
|
150
|
+
if (!z?.zstdDecompressSync) {
|
|
151
|
+
throw new Error('Compressed (zstd) workflow data encountered but node:zlib zstd ' +
|
|
152
|
+
'support is not available in this runtime (requires Node.js 22.15+). ' +
|
|
153
|
+
'In the browser, register a zstd decoder via registerZstdDecoder ' +
|
|
154
|
+
'(serialization-format.ts).');
|
|
155
|
+
}
|
|
156
|
+
return new Uint8Array(z.zstdDecompressSync(data));
|
|
157
|
+
}
|
|
158
|
+
function recordStats(stats, codec, uncompressedBytes, storedBytes) {
|
|
159
|
+
if (!stats)
|
|
160
|
+
return;
|
|
161
|
+
stats.recorded = true;
|
|
162
|
+
stats.compressed = codec !== 'none';
|
|
163
|
+
stats.codec = codec;
|
|
164
|
+
stats.uncompressedBytes = uncompressedBytes;
|
|
165
|
+
stats.storedBytes = storedBytes;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Choose the write-side codec given runtime availability and the optional
|
|
169
|
+
* env override. zstd is preferred; gzip is the portable fallback.
|
|
170
|
+
*/
|
|
171
|
+
function selectWriteCodec() {
|
|
172
|
+
const override = codecOverrideFromEnv();
|
|
173
|
+
if (override === 'gzip')
|
|
174
|
+
return isGzipAvailable() ? 'gzip' : 'none';
|
|
175
|
+
// Default and explicit 'zstd' both prefer zstd, then fall back to gzip.
|
|
176
|
+
if (isZstdAvailable())
|
|
177
|
+
return 'zstd';
|
|
178
|
+
if (isGzipAvailable())
|
|
179
|
+
return 'gzip';
|
|
180
|
+
return 'none';
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Compress a format-prefixed payload if compression is enabled for the
|
|
184
|
+
* target run and the payload is worth compressing.
|
|
185
|
+
*
|
|
186
|
+
* @param data - The format-prefixed serialized data (e.g. 'devl' + bytes)
|
|
187
|
+
* @param enabled - Whether the target run supports compressed payloads
|
|
188
|
+
* (run specVersion >= SPEC_VERSION_SUPPORTS_COMPRESSION, and for
|
|
189
|
+
* cross-deployment writes, the target deployment's capabilities —
|
|
190
|
+
* see `getRunCapabilities` in capabilities.ts). zstd and gzip read
|
|
191
|
+
* support co-ship, so a single boolean is sufficient.
|
|
192
|
+
* @param stats - Optional telemetry sink; populated when `data` is binary.
|
|
193
|
+
* @returns The compressed data with a codec prefix, or the original data
|
|
194
|
+
* when compression is disabled, unavailable, or not worthwhile.
|
|
195
|
+
*/
|
|
196
|
+
export async function compress(data, enabled, stats) {
|
|
197
|
+
if (!(data instanceof Uint8Array))
|
|
198
|
+
return data;
|
|
199
|
+
// From here `data` is binary, so every return path records stats.
|
|
200
|
+
if (!enabled ||
|
|
201
|
+
data.length < COMPRESSION_MIN_BYTES ||
|
|
202
|
+
isCompressionDisabledByEnv()) {
|
|
203
|
+
recordStats(stats, 'none', data.length, data.length);
|
|
204
|
+
return data;
|
|
205
|
+
}
|
|
206
|
+
const codec = selectWriteCodec();
|
|
207
|
+
if (codec === 'none') {
|
|
208
|
+
recordStats(stats, 'none', data.length, data.length);
|
|
209
|
+
return data;
|
|
210
|
+
}
|
|
211
|
+
const compressed = codec === 'zstd' ? zstdBytes(data) : await gzipBytes(data);
|
|
212
|
+
const format = codec === 'zstd' ? SerializationFormat.ZSTD : SerializationFormat.GZIP;
|
|
213
|
+
const wrappedLength = 4 + compressed.length; // format prefix + payload
|
|
214
|
+
if (wrappedLength >= data.length * (1 - COMPRESSION_MIN_SAVINGS_RATIO)) {
|
|
215
|
+
recordStats(stats, 'none', data.length, data.length);
|
|
216
|
+
return data;
|
|
217
|
+
}
|
|
218
|
+
recordStats(stats, codec, data.length, wrappedLength);
|
|
219
|
+
return encodeWithFormatPrefix(format, compressed);
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Decompress a format-prefixed payload if it's compressed.
|
|
223
|
+
* Dispatches on the prefix ('zstd' or 'gzip') and inflates the inner
|
|
224
|
+
* payload (which carries its own format prefix, e.g. 'devl').
|
|
225
|
+
*
|
|
226
|
+
* Non-compressed data (including non-binary legacy data) is returned
|
|
227
|
+
* unchanged, so this is safe to apply unconditionally on read paths.
|
|
228
|
+
*/
|
|
229
|
+
export async function decompress(data, stats) {
|
|
230
|
+
if (!(data instanceof Uint8Array))
|
|
231
|
+
return data;
|
|
232
|
+
const prefix = peekFormatPrefix(data);
|
|
233
|
+
if (prefix === SerializationFormat.ZSTD) {
|
|
234
|
+
const { payload } = decodeFormatPrefix(data);
|
|
235
|
+
const inflated = unzstdBytes(payload);
|
|
236
|
+
recordStats(stats, 'zstd', inflated.length, data.length);
|
|
237
|
+
return inflated;
|
|
238
|
+
}
|
|
239
|
+
if (prefix === SerializationFormat.GZIP) {
|
|
240
|
+
if (!isGzipAvailable()) {
|
|
241
|
+
throw new Error('Compressed (gzip) workflow data encountered but DecompressionStream ' +
|
|
242
|
+
'is not available in this runtime. Node.js 18+, browsers, and edge ' +
|
|
243
|
+
'runtimes all support it.');
|
|
244
|
+
}
|
|
245
|
+
const { payload } = decodeFormatPrefix(data);
|
|
246
|
+
const inflated = await gunzipBytes(payload);
|
|
247
|
+
recordStats(stats, 'gzip', inflated.length, data.length);
|
|
248
|
+
return inflated;
|
|
249
|
+
}
|
|
250
|
+
recordStats(stats, 'none', data.length, data.length);
|
|
251
|
+
return data;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Check if data is compressed (has a 'zstd' or 'gzip' format prefix).
|
|
255
|
+
*/
|
|
256
|
+
export function isCompressed(data) {
|
|
257
|
+
const prefix = peekFormatPrefix(data);
|
|
258
|
+
return (prefix === SerializationFormat.ZSTD || prefix === SerializationFormat.GZIP);
|
|
259
|
+
}
|
|
260
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tcHJlc3Npb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VyaWFsaXphdGlvbi9jb21wcmVzc2lvbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FnQ0c7QUFFSCxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0QixnQkFBZ0IsR0FDakIsTUFBTSxhQUFhLENBQUM7QUFDckIsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRWpEOzs7O0dBSUc7QUFDSCxNQUFNLENBQUMsTUFBTSxxQkFBcUIsR0FBRyxJQUFJLENBQUM7QUFFMUM7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxJQUFJLENBQUM7QUFFbEQseUVBQXlFO0FBQ3pFLE1BQU0sVUFBVSxHQUFHLENBQUMsQ0FBQztBQUtyQjs7OztHQUlHO0FBQ0gsU0FBUywwQkFBMEI7SUFDakMsSUFBSSxDQUFDO1FBQ0gsT0FBTyxDQUNMLE9BQU8sT0FBTyxLQUFLLFdBQVc7WUFDOUIsT0FBTyxDQUFDLEdBQUcsRUFBRSw0QkFBNEIsS0FBSyxHQUFHLENBQ2xELENBQUM7SUFDSixDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0FBQ0gsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLG9CQUFvQjtJQUMzQixJQUFJLENBQUM7UUFDSCxNQUFNLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxFQUFFLDBCQUEwQixDQUFDO1FBQ2xELE9BQU8sQ0FBQyxLQUFLLE1BQU0sSUFBSSxDQUFDLEtBQUssTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztJQUN0RCxDQUFDO0lBQUMsTUFBTSxDQUFDO1FBQ1AsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztBQUNILENBQUM7QUFR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LHNFQUFzRTtnQkFDcEUsb0VBQW9FO2dCQUNwRSwwQkFBMEIsQ0FDN0IsQ0FBQztRQUNKLENBQUM7UUFDRCxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsa0JBQWtCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0MsTUFBTSxRQUFRLEdBQUcsTUFBTSxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUMsV0FBVyxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsUUFBUSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDekQsT0FBTyxRQUFRLENBQUM7SUFDbEIsQ0FBQztJQUVELFdBQVcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQ3JELE9BQU8sSUFBSSxDQUFDO0FBQ2QsQ0FBQztBQUVEOztHQUVHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxJQUEwQjtJQUNyRCxNQUFNLE1BQU0sR0FBRyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUN0QyxPQUFPLENBQ0wsTUFBTSxLQUFLLG1CQUFtQixDQUFDLElBQUksSUFBSSxNQUFNLEtBQUssbUJBQW1CLENBQUMsSUFBSSxDQUMzRSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29tcG9zYWJsZSBjb21wcmVzc2lvbiBsYXllciBmb3Igc2VyaWFsaXplZCBkYXRhLlxuICpcbiAqIFdyYXBzL3Vud3JhcHMgc2VyaWFsaXplZCBwYXlsb2FkcyB3aXRoIGEgY29tcHJlc3Npb24gY29kZWMsIHVzaW5nIHRoZVxuICogZm9ybWF0IHByZWZpeCBzeXN0ZW0gdG8gbWFyayBjb21wcmVzc2VkIGRhdGEgKGUuZy4gJ3pzdGQnIG9yICdnemlwJ1xuICogd3JhcHBpbmcgdGhlIGlubmVyIGZvcm1hdDogJ3pzdGQnICsgenN0ZCgnZGV2bCcgKyBwYXlsb2FkKSkuXG4gKlxuICogQ29kZWMgc2VsZWN0aW9uICh3cml0ZSBzaWRlKTogenN0ZCBpcyBwcmVmZXJyZWQg4oCUIGl0IGlzIG1hcmtlZGx5IGZhc3RlclxuICogdGhhbiBnemlwIGF0IGEgY29tcGFyYWJsZS1vci1iZXR0ZXIgcmF0aW8gKHNlZSBzY3JpcHRzL1JFQURNRS5tZCksIGFuZFxuICogY29tcHJlc3Npb24gcnVucyBhdCBldmVyeSBzdGVwIGJvdW5kYXJ5IHNvIHRoZSB3cml0ZSBDUFUgaXMgYSBwZXItc3RlcFxuICogdGF4LiB6c3RkIHJlcXVpcmVzIGBub2RlOnpsaWJgID49IDIyLjE1IChXZWIgYENvbXByZXNzaW9uU3RyZWFtYCBoYXMgbm9cbiAqIHpzdGQpLCBzbyBvbiBhIHJ1bnRpbWUgd2l0aG91dCBpdCB3ZSBmYWxsIGJhY2sgdG8gZ3ppcCB2aWEgdGhlIHBvcnRhYmxlXG4gKiBgQ29tcHJlc3Npb25TdHJlYW1gLiBgV09SS0ZMT1dfQ09NUFJFU1NJT05fQ09ERUM9Z3ppcGAgZm9yY2VzIHRoZVxuICogcG9ydGFibGUgY29kZWMuXG4gKlxuICogUmVhZCBzaWRlOiBkaXNwYXRjaCBvbiB0aGUgZm9ybWF0IHByZWZpeCwgc28gYm90aCAnenN0ZCcgYW5kICdnemlwJ1xuICogcGF5bG9hZHMgYXJlIGFsd2F5cyBkZWNvZGFibGUgcmVnYXJkbGVzcyBvZiB3aGljaCBjb2RlYyB3cm90ZSB0aGVtLlxuICogKFRoZSBicm93c2VyIG8xMXkgcmVhZCBwYXRoIGRlY29kZXMgenN0ZCB2aWEgYSByZWdpc3RlcmVkIFdBU00gZGVjb2RlciDigJRcbiAqIHNlZSBgc2VyaWFsaXphdGlvbi1mb3JtYXQudHNgOyB0aGlzIG1vZHVsZSdzIGBkZWNvbXByZXNzYCBpcyB0aGUgTm9kZVxuICogcnVudGltZS9yZXBsYXkgcGF0aCBhbmQgdXNlcyBgbm9kZTp6bGliYC4pXG4gKlxuICogTGF5ZXJpbmcgb3JkZXIgd2l0aCBlbmNyeXB0aW9uOiBjb21wcmVzc2lvbiBpcyBhcHBsaWVkIEJFRk9SRVxuICogZW5jcnlwdGlvbiAoZW5jcih6c3RkKGRldmwpKSkg4oCUIGVuY3J5cHRlZCBieXRlcyBhcmUgaGlnaC1lbnRyb3B5IGFuZFxuICogZG8gbm90IGNvbXByZXNzLCBzbyB0aGUgcmV2ZXJzZSBvcmRlciB3b3VsZCBiZSBhIG5vLW9wLlxuICpcbiAqIENvbXByZXNzaW9uIGlzIGNvbmRpdGlvbmFsOlxuICogLSBQYXlsb2FkcyBzbWFsbGVyIHRoYW4ge0BsaW5rIENPTVBSRVNTSU9OX01JTl9CWVRFU30gYXJlIHBhc3NlZFxuICogICB0aHJvdWdoIHVuY2hhbmdlZCAoY29kZWMgb3ZlcmhlYWQgaXNuJ3Qgd29ydGggaXQpLlxuICogLSBJZiB0aGUgY29tcHJlc3NlZCByZXN1bHQgaXNuJ3QgbWVhbmluZ2Z1bGx5IHNtYWxsZXIgdGhhbiB0aGVcbiAqICAgb3JpZ2luYWwgKHNlZSB7QGxpbmsgQ09NUFJFU1NJT05fTUlOX1NBVklOR1NfUkFUSU99KSwgdGhlIG9yaWdpbmFsXG4gKiAgIGlzIGtlcHQuIFRoaXMgcHJvdGVjdHMgYWxyZWFkeS1jb21wcmVzc2VkIGJpbmFyeSBwYXlsb2FkcyAoaW1hZ2VzLFxuICogICBhcmNoaXZlcywgZXRjLikgZnJvbSB3YXN0ZWQgQ1BVIGFuZCBzaXplIGluZmxhdGlvbi5cbiAqL1xuXG5pbXBvcnQge1xuICBkZWNvZGVGb3JtYXRQcmVmaXgsXG4gIGVuY29kZVdpdGhGb3JtYXRQcmVmaXgsXG4gIHBlZWtGb3JtYXRQcmVmaXgsXG59IGZyb20gJy4vZm9ybWF0LmpzJztcbmltcG9ydCB7IFNlcmlhbGl6YXRpb25Gb3JtYXQgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuLyoqXG4gKiBQYXlsb2FkcyBiZWxvdyB0aGlzIHNpemUgYXJlIG5ldmVyIGNvbXByZXNzZWQuIFRoZSA0LWJ5dGUgZm9ybWF0XG4gKiBwcmVmaXggKyBjb2RlYyBoZWFkZXIvdHJhaWxlciBvdmVyaGVhZCBtZWFucyBzbWFsbCBwYXlsb2FkcyBnYWluXG4gKiBub3RoaW5nLCBhbmQgdGlueSBvbmVzIHdvdWxkIGdyb3cuXG4gKi9cbmV4cG9ydCBjb25zdCBDT01QUkVTU0lPTl9NSU5fQllURVMgPSAxMDI0O1xuXG4vKipcbiAqIENvbXByZXNzaW9uIG11c3Qgc2hhdmUgb2ZmIGF0IGxlYXN0IHRoaXMgZnJhY3Rpb24gb2YgdGhlIHBheWxvYWRcbiAqIHNpemUgdG8gYmUga2VwdDsgb3RoZXJ3aXNlIHRoZSB1bmNvbXByZXNzZWQgb3JpZ2luYWwgaXMgc3RvcmVkLlxuICogR3VhcmRzIGFnYWluc3QgaW5jb21wcmVzc2libGUgKGFscmVhZHktY29tcHJlc3NlZCAvIGhpZ2gtZW50cm9weSlcbiAqIGRhdGEgcGF5aW5nIGEgcGVybWFuZW50IGRlY29tcHJlc3Npb24gdGF4IGZvciBhIG5lZ2xpZ2libGUgd2luLlxuICovXG5leHBvcnQgY29uc3QgQ09NUFJFU1NJT05fTUlOX1NBVklOR1NfUkFUSU8gPSAwLjA1O1xuXG4vKiogRGVmYXVsdCB6c3RkIGNvbXByZXNzaW9uIGxldmVsIOKAlCB0aGUgc3dlZXQgc3BvdCBvZiBzcGVlZCB2cyByYXRpby4gKi9cbmNvbnN0IFpTVERfTEVWRUwgPSAzO1xuXG4vKiogV2hpY2ggY29kZWMgY29tcHJlc3NlZCBhIHBheWxvYWQgKG9yIGBub25lYCB3aGVuIHN0b3JlZCB1bmNvbXByZXNzZWQpLiAqL1xuZXhwb3J0IHR5cGUgQ29tcHJlc3Npb25Db2RlYyA9ICd6c3RkJyB8ICdnemlwJyB8ICdub25lJztcblxuLyoqXG4gKiBFc2NhcGUgaGF0Y2g6IHNldCBXT1JLRkxPV19ESVNBQkxFX0NPTVBSRVNTSU9OPTEgdG8gZGlzYWJsZVxuICogd3JpdGUtc2lkZSBjb21wcmVzc2lvbiBlbnRpcmVseS4gUmVhZHMgYXJlIHVuYWZmZWN0ZWQg4oCUIHBheWxvYWRzXG4gKiB0aGF0IHdlcmUgYWxyZWFkeSB3cml0dGVuIGNvbXByZXNzZWQgcmVtYWluIHJlYWRhYmxlLlxuICovXG5mdW5jdGlvbiBpc0NvbXByZXNzaW9uRGlzYWJsZWRCeUVudigpOiBib29sZWFuIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gKFxuICAgICAgdHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmXG4gICAgICBwcm9jZXNzLmVudj8uV09SS0ZMT1dfRElTQUJMRV9DT01QUkVTU0lPTiA9PT0gJzEnXG4gICAgKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG5cbi8qKlxuICogT3B0aW9uYWwgY29kZWMgb3ZlcnJpZGUgKGBXT1JLRkxPV19DT01QUkVTU0lPTl9DT0RFQz1nemlwfHpzdGRgKS4gTGV0cyBhblxuICogb3BlcmF0b3IgcGluIHRoZSBwb3J0YWJsZSBjb2RlYyAoZ3ppcCkg4oCUIHVzZWZ1bCBmb3IgQS9CIGNvbXBhcmlzb25zIG9yXG4gKiBydW50aW1lcyB3aGVyZSB6c3RkIHJlYWQgc3VwcG9ydCBpc24ndCB5ZXQgZXZlcnl3aGVyZS5cbiAqL1xuZnVuY3Rpb24gY29kZWNPdmVycmlkZUZyb21FbnYoKTogJ2d6aXAnIHwgJ3pzdGQnIHwgdW5kZWZpbmVkIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB2ID0gcHJvY2Vzcy5lbnY/LldPUktGTE9XX0NPTVBSRVNTSU9OX0NPREVDO1xuICAgIHJldHVybiB2ID09PSAnZ3ppcCcgfHwgdiA9PT0gJ3pzdGQnID8gdiA6IHVuZGVmaW5lZDtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxufVxuXG5pbnRlcmZhY2UgTm9kZVpsaWIge1xuICB6c3RkQ29tcHJlc3NTeW5jPzogKGRhdGE6IFVpbnQ4QXJyYXksIG9wdHM/OiB1bmtub3duKSA9PiBVaW50OEFycmF5O1xuICB6c3RkRGVjb21wcmVzc1N5bmM/OiAoZGF0YTogVWludDhBcnJheSkgPT4gVWludDhBcnJheTtcbiAgY29uc3RhbnRzPzogUmVjb3JkPHN0cmluZywgbnVtYmVyPjtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGBub2RlOnpsaWJgIHZpYSBgcHJvY2Vzcy5nZXRCdWlsdGluTW9kdWxlYCDigJQgbm8gc3RhdGljIGltcG9ydCwgc29cbiAqIHRoaXMgbW9kdWxlIHN0YXlzIGJ1bmRsZXItc2FmZSBmb3IgYnJvd3Nlci9lZGdlIHRhcmdldHMgKHdoZXJlIGl0IHJldHVybnNcbiAqIHVuZGVmaW5lZCBhbmQgd2UgZmFsbCBiYWNrIHRvIGd6aXApLlxuICovXG5mdW5jdGlvbiBnZXROb2RlWmxpYigpOiBOb2RlWmxpYiB8IHVuZGVmaW5lZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIChcbiAgICAgIGdsb2JhbFRoaXMgYXMge1xuICAgICAgICBwcm9jZXNzPzogeyBnZXRCdWlsdGluTW9kdWxlPzogKGlkOiBzdHJpbmcpID0+IE5vZGVabGliIH07XG4gICAgICB9XG4gICAgKS5wcm9jZXNzPy5nZXRCdWlsdGluTW9kdWxlPy4oJ25vZGU6emxpYicpO1xuICB9IGNhdGNoIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG59XG5cbmZ1bmN0aW9uIGlzWnN0ZEF2YWlsYWJsZSgpOiBib29sZWFuIHtcbiAgY29uc3QgeiA9IGdldE5vZGVabGliKCk7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIHo/LnpzdGRDb21wcmVzc1N5bmMgPT09ICdmdW5jdGlvbicgJiZcbiAgICB0eXBlb2Ygej8uenN0ZERlY29tcHJlc3NTeW5jID09PSAnZnVuY3Rpb24nXG4gICk7XG59XG5cbi8qKlxuICogZ3ppcCB2aWEgdGhlIHdlYi1zdGFuZGFyZCBgQ29tcHJlc3Npb25TdHJlYW1gIChOb2RlIDE4KywgYnJvd3NlcnMsIGVkZ2UpLlxuICovXG5mdW5jdGlvbiBpc0d6aXBBdmFpbGFibGUoKTogYm9vbGVhbiB7XG4gIHJldHVybiAoXG4gICAgdHlwZW9mIENvbXByZXNzaW9uU3RyZWFtID09PSAnZnVuY3Rpb24nICYmXG4gICAgdHlwZW9mIERlY29tcHJlc3Npb25TdHJlYW0gPT09ICdmdW5jdGlvbidcbiAgKTtcbn1cblxuLyoqXG4gKiBQaXBlIGJ5dGVzIHRocm91Z2ggYSAoRGUpQ29tcHJlc3Npb25TdHJlYW0gYW5kIGNvbGxlY3QgdGhlIG91dHB1dC5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcGlwZVRocm91Z2hUcmFuc2Zvcm0oXG4gIGRhdGE6IFVpbnQ4QXJyYXksXG4gIHRyYW5zZm9ybToge1xuICAgIHJlYWRhYmxlOiBSZWFkYWJsZVN0cmVhbTxVaW50OEFycmF5PjtcbiAgICB3cml0YWJsZTogV3JpdGFibGVTdHJlYW08VWludDhBcnJheT47XG4gIH1cbik6IFByb21pc2U8VWludDhBcnJheT4ge1xuICBjb25zdCB3cml0ZXIgPSB0cmFuc2Zvcm0ud3JpdGFibGUuZ2V0V3JpdGVyKCk7XG4gIC8vIERvbid0IGF3YWl0IHRoZSB3cml0ZSBiZWZvcmUgcmVhZGluZyDigJQgdGhlIHRyYW5zZm9ybSdzIGludGVybmFsXG4gIC8vIHF1ZXVlIGNhbiBmaWxsIHVwIG9uIGxhcmdlIHBheWxvYWRzLCBkZWFkbG9ja2luZyB3cml0ZXIgdnMgcmVhZGVyLlxuICBjb25zdCB3cml0ZVByb21pc2UgPSB3cml0ZXIud3JpdGUoZGF0YSkudGhlbigoKSA9PiB3cml0ZXIuY2xvc2UoKSk7XG4gIC8vIElmIHRoZSB0cmFuc2Zvcm0gZXJyb3JzLCB0aGUgcmVhZGVyLnJlYWQoKSBiZWxvdyByZWplY3RzIGZpcnN0IGFuZFxuICAvLyBwcm9wYWdhdGVzOyBtYXJrIHRoZSB3cml0ZSBzaWRlIGFzIGhhbmRsZWQgc28gdGhlIG1pcnJvcmVkIHJlamVjdGlvblxuICAvLyBkb2Vzbid0IHN1cmZhY2UgYXMgYW4gdW5oYW5kbGVkIHJlamVjdGlvbi5cbiAgd3JpdGVQcm9taXNlLmNhdGNoKCgpID0+IHt9KTtcbiAgY29uc3QgY2h1bmtzOiBVaW50OEFycmF5W10gPSBbXTtcbiAgbGV0IHRvdGFsID0gMDtcbiAgY29uc3QgcmVhZGVyID0gdHJhbnNmb3JtLnJlYWRhYmxlLmdldFJlYWRlcigpO1xuICBmb3IgKDs7KSB7XG4gICAgY29uc3QgeyBkb25lLCB2YWx1ZSB9ID0gYXdhaXQgcmVhZGVyLnJlYWQoKTtcbiAgICBpZiAoZG9uZSkgYnJlYWs7XG4gICAgY2h1bmtzLnB1c2godmFsdWUpO1xuICAgIHRvdGFsICs9IHZhbHVlLmxlbmd0aDtcbiAgfVxuICBhd2FpdCB3cml0ZVByb21pc2U7XG4gIGNvbnN0IG91dCA9IG5ldyBVaW50OEFycmF5KHRvdGFsKTtcbiAgbGV0IG9mZnNldCA9IDA7XG4gIGZvciAoY29uc3QgY2h1bmsgb2YgY2h1bmtzKSB7XG4gICAgb3V0LnNldChjaHVuaywgb2Zmc2V0KTtcbiAgICBvZmZzZXQgKz0gY2h1bmsubGVuZ3RoO1xuICB9XG4gIHJldHVybiBvdXQ7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGd6aXBCeXRlcyhkYXRhOiBVaW50OEFycmF5KTogUHJvbWlzZTxVaW50OEFycmF5PiB7XG4gIHJldHVybiBwaXBlVGhyb3VnaFRyYW5zZm9ybShkYXRhLCBuZXcgQ29tcHJlc3Npb25TdHJlYW0oJ2d6aXAnKSk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGd1bnppcEJ5dGVzKGRhdGE6IFVpbnQ4QXJyYXkpOiBQcm9taXNlPFVpbnQ4QXJyYXk+IHtcbiAgcmV0dXJuIHBpcGVUaHJvdWdoVHJhbnNmb3JtKGRhdGEsIG5ldyBEZWNvbXByZXNzaW9uU3RyZWFtKCdnemlwJykpO1xufVxuXG5mdW5jdGlvbiB6c3RkQnl0ZXMoZGF0YTogVWludDhBcnJheSk6IFVpbnQ4QXJyYXkge1xuICBjb25zdCB6ID0gZ2V0Tm9kZVpsaWIoKTtcbiAgY29uc3QgbGV2ZWwgPSB6Py5jb25zdGFudHM/LlpTVERfY19jb21wcmVzc2lvbkxldmVsO1xuICBjb25zdCBvcHRzID1cbiAgICBsZXZlbCAhPT0gdW5kZWZpbmVkID8geyBwYXJhbXM6IHsgW2xldmVsXTogWlNURF9MRVZFTCB9IH0gOiB1bmRlZmluZWQ7XG4gIC8vIGJpb21lLWlnbm9yZSBsaW50L3N0eWxlL25vTm9uTnVsbEFzc2VydGlvbjogZ3VhcmRlZCBieSBpc1pzdGRBdmFpbGFibGUoKVxuICByZXR1cm4gbmV3IFVpbnQ4QXJyYXkoeiEuenN0ZENvbXByZXNzU3luYyEoZGF0YSwgb3B0cykpO1xufVxuXG5mdW5jdGlvbiB1bnpzdGRCeXRlcyhkYXRhOiBVaW50OEFycmF5KTogVWludDhBcnJheSB7XG4gIGNvbnN0IHogPSBnZXROb2RlWmxpYigpO1xuICBpZiAoIXo/LnpzdGREZWNvbXByZXNzU3luYykge1xuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICdDb21wcmVzc2VkICh6c3RkKSB3b3JrZmxvdyBkYXRhIGVuY291bnRlcmVkIGJ1dCBub2RlOnpsaWIgenN0ZCAnICtcbiAgICAgICAgJ3N1cHBvcnQgaXMgbm90IGF2YWlsYWJsZSBpbiB0aGlzIHJ1bnRpbWUgKHJlcXVpcmVzIE5vZGUuanMgMjIuMTUrKS4gJyArXG4gICAgICAgICdJbiB0aGUgYnJvd3NlciwgcmVnaXN0ZXIgYSB6c3RkIGRlY29kZXIgdmlhIHJlZ2lzdGVyWnN0ZERlY29kZXIgJyArXG4gICAgICAgICcoc2VyaWFsaXphdGlvbi1mb3JtYXQudHMpLidcbiAgICApO1xuICB9XG4gIHJldHVybiBuZXcgVWludDhBcnJheSh6LnpzdGREZWNvbXByZXNzU3luYyhkYXRhKSk7XG59XG5cbi8qKlxuICogVGVsZW1ldHJ5IHNpbmsgZGVzY3JpYmluZyB3aGF0IHRoZSBjb21wcmVzc2lvbiBsYXllciBkaWQgdG8gYSBwYXlsb2FkLlxuICogUG9wdWxhdGVkIGJ5IHtAbGluayBjb21wcmVzc30gKHdyaXRlKSBhbmQge0BsaW5rIGRlY29tcHJlc3N9IChyZWFkKSB3aGVuXG4gKiBhIGBzdGF0c2Agb2JqZWN0IGlzIHBhc3NlZC4gU2l6ZXMgYXJlIG1lYXN1cmVkIGF0IHRoZSBjb21wcmVzc2lvblxuICogYm91bmRhcnkg4oCUIGkuZS4gYmVmb3JlIGVuY3J5cHRpb24gaXMgbGF5ZXJlZCBvbiB0aGUgd3JpdGUgc2lkZSBhbmQgYWZ0ZXJcbiAqIGRlY3J5cHRpb24gb24gdGhlIHJlYWQgc2lkZSDigJQgc28gdGhleSByZWZsZWN0IGNvbXByZXNzaW9uJ3MgZWZmZWN0LCBub3RcbiAqIHRoZSBhdC1yZXN0IHNpemUgKHdoaWNoIGFsc28gaW5jbHVkZXMgdGhlIGBlbmNyYCBlbnZlbG9wZSBhbmQsIG9uIHNvbWVcbiAqIGJhY2tlbmRzLCBiYXNlNjQgZXhwYW5zaW9uKS5cbiAqXG4gKiBGaWVsZCBtZWFuaW5ncyBhcmUgaWRlbnRpY2FsIGZvciBib3RoIGRpcmVjdGlvbnM6XG4gKiAtIGB1bmNvbXByZXNzZWRCeXRlc2A6IHRoZSBsb2dpY2FsIChkZXZhbHVlLXByZWZpeGVkKSBwYXlsb2FkIHNpemUuXG4gKiAtIGBzdG9yZWRCeXRlc2A6IHRoZSBzaXplIGhhbmRlZCB0byAvIHJlYWQgZnJvbSBzdG9yYWdlIChjb21wcmVzc2VkIHdoZW5cbiAqICAgYSBjb2RlYyBhcHBsaWVkLCBvdGhlcndpc2UgZXF1YWwgdG8gYHVuY29tcHJlc3NlZEJ5dGVzYCkuXG4gKiAtIGBjb2RlY2A6IHdoaWNoIGNvZGVjIGFwcGxpZWQgKGBub25lYCB3aGVuIHN0b3JlZCB1bmNvbXByZXNzZWQpLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbXByZXNzaW9uU3RhdHMge1xuICAvKiogVHJ1ZSBvbmNlIHRoZSBjb21wcmVzc2lvbiBsYXllciByYW4gKGkuZS4gc2F3IGJpbmFyeSBkYXRhKS4gKi9cbiAgcmVjb3JkZWQ/OiBib29sZWFuO1xuICAvKiogV2hldGhlciBhIGNvZGVjIHdhcyBhcHBsaWVkICh3cml0ZSkgb3IgcHJlc2VudCAocmVhZCkuICovXG4gIGNvbXByZXNzZWQ/OiBib29sZWFuO1xuICAvKiogV2hpY2ggY29kZWMgYXBwbGllZCAvIHdhcyBwcmVzZW50LiAqL1xuICBjb2RlYz86IENvbXByZXNzaW9uQ29kZWM7XG4gIC8qKiBMb2dpY2FsLCB1bmNvbXByZXNzZWQgcGF5bG9hZCBzaXplIGluIGJ5dGVzLiAqL1xuICB1bmNvbXByZXNzZWRCeXRlcz86IG51bWJlcjtcbiAgLyoqIFN0b3JlZCAocG9zdC1jb21wcmVzc2lvbikgcGF5bG9hZCBzaXplIGluIGJ5dGVzLiAqL1xuICBzdG9yZWRCeXRlcz86IG51bWJlcjtcbn1cblxuZnVuY3Rpb24gcmVjb3JkU3RhdHMoXG4gIHN0YXRzOiBDb21wcmVzc2lvblN0YXRzIHwgdW5kZWZpbmVkLFxuICBjb2RlYzogQ29tcHJlc3Npb25Db2RlYyxcbiAgdW5jb21wcmVzc2VkQnl0ZXM6IG51bWJlcixcbiAgc3RvcmVkQnl0ZXM6IG51bWJlclxuKTogdm9pZCB7XG4gIGlmICghc3RhdHMpIHJldHVybjtcbiAgc3RhdHMucmVjb3JkZWQgPSB0cnVlO1xuICBzdGF0cy5jb21wcmVzc2VkID0gY29kZWMgIT09ICdub25lJztcbiAgc3RhdHMuY29kZWMgPSBjb2RlYztcbiAgc3RhdHMudW5jb21wcmVzc2VkQnl0ZXMgPSB1bmNvbXByZXNzZWRCeXRlcztcbiAgc3RhdHMuc3RvcmVkQnl0ZXMgPSBzdG9yZWRCeXRlcztcbn1cblxuLyoqXG4gKiBDaG9vc2UgdGhlIHdyaXRlLXNpZGUgY29kZWMgZ2l2ZW4gcnVudGltZSBhdmFpbGFiaWxpdHkgYW5kIHRoZSBvcHRpb25hbFxuICogZW52IG92ZXJyaWRlLiB6c3RkIGlzIHByZWZlcnJlZDsgZ3ppcCBpcyB0aGUgcG9ydGFibGUgZmFsbGJhY2suXG4gKi9cbmZ1bmN0aW9uIHNlbGVjdFdyaXRlQ29kZWMoKTogJ3pzdGQnIHwgJ2d6aXAnIHwgJ25vbmUnIHtcbiAgY29uc3Qgb3ZlcnJpZGUgPSBjb2RlY092ZXJyaWRlRnJvbUVudigpO1xuICBpZiAob3ZlcnJpZGUgPT09ICdnemlwJykgcmV0dXJuIGlzR3ppcEF2YWlsYWJsZSgpID8gJ2d6aXAnIDogJ25vbmUnO1xuICAvLyBEZWZhdWx0IGFuZCBleHBsaWNpdCAnenN0ZCcgYm90aCBwcmVmZXIgenN0ZCwgdGhlbiBmYWxsIGJhY2sgdG8gZ3ppcC5cbiAgaWYgKGlzWnN0ZEF2YWlsYWJsZSgpKSByZXR1cm4gJ3pzdGQnO1xuICBpZiAoaXNHemlwQXZhaWxhYmxlKCkpIHJldHVybiAnZ3ppcCc7XG4gIHJldHVybiAnbm9uZSc7XG59XG5cbi8qKlxuICogQ29tcHJlc3MgYSBmb3JtYXQtcHJlZml4ZWQgcGF5bG9hZCBpZiBjb21wcmVzc2lvbiBpcyBlbmFibGVkIGZvciB0aGVcbiAqIHRhcmdldCBydW4gYW5kIHRoZSBwYXlsb2FkIGlzIHdvcnRoIGNvbXByZXNzaW5nLlxuICpcbiAqIEBwYXJhbSBkYXRhIC0gVGhlIGZvcm1hdC1wcmVmaXhlZCBzZXJpYWxpemVkIGRhdGEgKGUuZy4gJ2RldmwnICsgYnl0ZXMpXG4gKiBAcGFyYW0gZW5hYmxlZCAtIFdoZXRoZXIgdGhlIHRhcmdldCBydW4gc3VwcG9ydHMgY29tcHJlc3NlZCBwYXlsb2Fkc1xuICogICAocnVuIHNwZWNWZXJzaW9uID49IFNQRUNfVkVSU0lPTl9TVVBQT1JUU19DT01QUkVTU0lPTiwgYW5kIGZvclxuICogICBjcm9zcy1kZXBsb3ltZW50IHdyaXRlcywgdGhlIHRhcmdldCBkZXBsb3ltZW50J3MgY2FwYWJpbGl0aWVzIOKAlFxuICogICBzZWUgYGdldFJ1bkNhcGFiaWxpdGllc2AgaW4gY2FwYWJpbGl0aWVzLnRzKS4genN0ZCBhbmQgZ3ppcCByZWFkXG4gKiAgIHN1cHBvcnQgY28tc2hpcCwgc28gYSBzaW5nbGUgYm9vbGVhbiBpcyBzdWZmaWNpZW50LlxuICogQHBhcmFtIHN0YXRzIC0gT3B0aW9uYWwgdGVsZW1ldHJ5IHNpbms7IHBvcHVsYXRlZCB3aGVuIGBkYXRhYCBpcyBiaW5hcnkuXG4gKiBAcmV0dXJucyBUaGUgY29tcHJlc3NlZCBkYXRhIHdpdGggYSBjb2RlYyBwcmVmaXgsIG9yIHRoZSBvcmlnaW5hbCBkYXRhXG4gKiAgIHdoZW4gY29tcHJlc3Npb24gaXMgZGlzYWJsZWQsIHVuYXZhaWxhYmxlLCBvciBub3Qgd29ydGh3aGlsZS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNvbXByZXNzKFxuICBkYXRhOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgZW5hYmxlZDogYm9vbGVhbixcbiAgc3RhdHM/OiBDb21wcmVzc2lvblN0YXRzXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICghKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkgcmV0dXJuIGRhdGE7XG4gIC8vIEZyb20gaGVyZSBgZGF0YWAgaXMgYmluYXJ5LCBzbyBldmVyeSByZXR1cm4gcGF0aCByZWNvcmRzIHN0YXRzLlxuICBpZiAoXG4gICAgIWVuYWJsZWQgfHxcbiAgICBkYXRhLmxlbmd0aCA8IENPTVBSRVNTSU9OX01JTl9CWVRFUyB8fFxuICAgIGlzQ29tcHJlc3Npb25EaXNhYmxlZEJ5RW52KClcbiAgKSB7XG4gICAgcmVjb3JkU3RhdHMoc3RhdHMsICdub25lJywgZGF0YS5sZW5ndGgsIGRhdGEubGVuZ3RoKTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIGNvbnN0IGNvZGVjID0gc2VsZWN0V3JpdGVDb2RlYygpO1xuICBpZiAoY29kZWMgPT09ICdub25lJykge1xuICAgIHJlY29yZFN0YXRzKHN0YXRzLCAnbm9uZScsIGRhdGEubGVuZ3RoLCBkYXRhLmxlbmd0aCk7XG4gICAgcmV0dXJuIGRhdGE7XG4gIH1cblxuICBjb25zdCBjb21wcmVzc2VkID0gY29kZWMgPT09ICd6c3RkJyA/IHpzdGRCeXRlcyhkYXRhKSA6IGF3YWl0IGd6aXBCeXRlcyhkYXRhKTtcbiAgY29uc3QgZm9ybWF0ID1cbiAgICBjb2RlYyA9PT0gJ3pzdGQnID8gU2VyaWFsaXphdGlvbkZvcm1hdC5aU1REIDogU2VyaWFsaXphdGlvbkZvcm1hdC5HWklQO1xuICBjb25zdCB3cmFwcGVkTGVuZ3RoID0gNCArIGNvbXByZXNzZWQubGVuZ3RoOyAvLyBmb3JtYXQgcHJlZml4ICsgcGF5bG9hZFxuICBpZiAod3JhcHBlZExlbmd0aCA+PSBkYXRhLmxlbmd0aCAqICgxIC0gQ09NUFJFU1NJT05fTUlOX1NBVklOR1NfUkFUSU8pKSB7XG4gICAgcmVjb3JkU3RhdHMoc3RhdHMsICdub25lJywgZGF0YS5sZW5ndGgsIGRhdGEubGVuZ3RoKTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuICByZWNvcmRTdGF0cyhzdGF0cywgY29kZWMsIGRhdGEubGVuZ3RoLCB3cmFwcGVkTGVuZ3RoKTtcbiAgcmV0dXJuIGVuY29kZVdpdGhGb3JtYXRQcmVmaXgoZm9ybWF0LCBjb21wcmVzc2VkKTtcbn1cblxuLyoqXG4gKiBEZWNvbXByZXNzIGEgZm9ybWF0LXByZWZpeGVkIHBheWxvYWQgaWYgaXQncyBjb21wcmVzc2VkLlxuICogRGlzcGF0Y2hlcyBvbiB0aGUgcHJlZml4ICgnenN0ZCcgb3IgJ2d6aXAnKSBhbmQgaW5mbGF0ZXMgdGhlIGlubmVyXG4gKiBwYXlsb2FkICh3aGljaCBjYXJyaWVzIGl0cyBvd24gZm9ybWF0IHByZWZpeCwgZS5nLiAnZGV2bCcpLlxuICpcbiAqIE5vbi1jb21wcmVzc2VkIGRhdGEgKGluY2x1ZGluZyBub24tYmluYXJ5IGxlZ2FjeSBkYXRhKSBpcyByZXR1cm5lZFxuICogdW5jaGFuZ2VkLCBzbyB0aGlzIGlzIHNhZmUgdG8gYXBwbHkgdW5jb25kaXRpb25hbGx5IG9uIHJlYWQgcGF0aHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWNvbXByZXNzKFxuICBkYXRhOiBVaW50OEFycmF5IHwgdW5rbm93bixcbiAgc3RhdHM/OiBDb21wcmVzc2lvblN0YXRzXG4pOiBQcm9taXNlPFVpbnQ4QXJyYXkgfCB1bmtub3duPiB7XG4gIGlmICghKGRhdGEgaW5zdGFuY2VvZiBVaW50OEFycmF5KSkgcmV0dXJuIGRhdGE7XG4gIGNvbnN0IHByZWZpeCA9IHBlZWtGb3JtYXRQcmVmaXgoZGF0YSk7XG5cbiAgaWYgKHByZWZpeCA9PT0gU2VyaWFsaXphdGlvbkZvcm1hdC5aU1REKSB7XG4gICAgY29uc3QgeyBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGF0YSk7XG4gICAgY29uc3QgaW5mbGF0ZWQgPSB1bnpzdGRCeXRlcyhwYXlsb2FkKTtcbiAgICByZWNvcmRTdGF0cyhzdGF0cywgJ3pzdGQnLCBpbmZsYXRlZC5sZW5ndGgsIGRhdGEubGVuZ3RoKTtcbiAgICByZXR1cm4gaW5mbGF0ZWQ7XG4gIH1cblxuICBpZiAocHJlZml4ID09PSBTZXJpYWxpemF0aW9uRm9ybWF0LkdaSVApIHtcbiAgICBpZiAoIWlzR3ppcEF2YWlsYWJsZSgpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICdDb21wcmVzc2VkIChnemlwKSB3b3JrZmxvdyBkYXRhIGVuY291bnRlcmVkIGJ1dCBEZWNvbXByZXNzaW9uU3RyZWFtICcgK1xuICAgICAgICAgICdpcyBub3QgYXZhaWxhYmxlIGluIHRoaXMgcnVudGltZS4gTm9kZS5qcyAxOCssIGJyb3dzZXJzLCBhbmQgZWRnZSAnICtcbiAgICAgICAgICAncnVudGltZXMgYWxsIHN1cHBvcnQgaXQuJ1xuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgeyBwYXlsb2FkIH0gPSBkZWNvZGVGb3JtYXRQcmVmaXgoZGF0YSk7XG4gICAgY29uc3QgaW5mbGF0ZWQgPSBhd2FpdCBndW56aXBCeXRlcyhwYXlsb2FkKTtcbiAgICByZWNvcmRTdGF0cyhzdGF0cywgJ2d6aXAnLCBpbmZsYXRlZC5sZW5ndGgsIGRhdGEubGVuZ3RoKTtcbiAgICByZXR1cm4gaW5mbGF0ZWQ7XG4gIH1cblxuICByZWNvcmRTdGF0cyhzdGF0cywgJ25vbmUnLCBkYXRhLmxlbmd0aCwgZGF0YS5sZW5ndGgpO1xuICByZXR1cm4gZGF0YTtcbn1cblxuLyoqXG4gKiBDaGVjayBpZiBkYXRhIGlzIGNvbXByZXNzZWQgKGhhcyBhICd6c3RkJyBvciAnZ3ppcCcgZm9ybWF0IHByZWZpeCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0NvbXByZXNzZWQoZGF0YTogVWludDhBcnJheSB8IHVua25vd24pOiBib29sZWFuIHtcbiAgY29uc3QgcHJlZml4ID0gcGVla0Zvcm1hdFByZWZpeChkYXRhKTtcbiAgcmV0dXJuIChcbiAgICBwcmVmaXggPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuWlNURCB8fCBwcmVmaXggPT09IFNlcmlhbGl6YXRpb25Gb3JtYXQuR1pJUFxuICApO1xufVxuIl19
|
|
@@ -4,15 +4,16 @@
|
|
|
4
4
|
* Re-exports the mode-specific serialize/deserialize functions and
|
|
5
5
|
* the codec/format/encryption abstractions.
|
|
6
6
|
*/
|
|
7
|
-
export type { FormatPrefix, SerializableSpecial, Reducers, Revivers, } from './types.js';
|
|
8
|
-
export { SerializationFormat, isFormatPrefix } from './types.js';
|
|
9
7
|
export type { Codec, SerializationMode } from './codec.js';
|
|
10
8
|
export { devalueCodec } from './codec-devalue.js';
|
|
11
|
-
export {
|
|
12
|
-
export {
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
export { COMPRESSION_MIN_BYTES, type CompressionCodec, type CompressionStats, compress, decompress, isCompressed, } from './compression.js';
|
|
10
|
+
export { type CryptoKey, decrypt, type EncryptionKeyParam, encrypt, } from './encryption.js';
|
|
11
|
+
export { decodeFormatPrefix, encodeWithFormatPrefix, isEncrypted, peekFormatPrefix, } from './format.js';
|
|
12
|
+
export type { FormatPrefix, Reducers, Revivers, SerializableSpecial, } from './types.js';
|
|
13
|
+
export { isFormatPrefix, SerializationFormat } from './types.js';
|
|
15
14
|
import * as client from './client.js';
|
|
15
|
+
import * as step from './step.js';
|
|
16
|
+
import * as workflow from './workflow.js';
|
|
16
17
|
export { workflow, step, client };
|
|
17
18
|
export { revive } from './reducers/common.js';
|
|
18
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/serialization/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/serialization/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,YAAY,EAAE,KAAK,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD,OAAO,EACL,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,QAAQ,EACR,UAAU,EACV,YAAY,GACb,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,KAAK,SAAS,EACd,OAAO,EACP,KAAK,kBAAkB,EACvB,OAAO,GACR,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,gBAAgB,GACjB,MAAM,aAAa,CAAC;AAErB,YAAY,EACV,YAAY,EACZ,QAAQ,EACR,QAAQ,EACR,mBAAmB,GACpB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,cAAc,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjE,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,OAAO,KAAK,QAAQ,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;AAGlC,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC"}
|
|
@@ -4,17 +4,19 @@
|
|
|
4
4
|
* Re-exports the mode-specific serialize/deserialize functions and
|
|
5
5
|
* the codec/format/encryption abstractions.
|
|
6
6
|
*/
|
|
7
|
-
export { SerializationFormat, isFormatPrefix } from './types.js';
|
|
8
7
|
export { devalueCodec } from './codec-devalue.js';
|
|
9
|
-
// Re-export
|
|
10
|
-
export {
|
|
8
|
+
// Re-export composable compression
|
|
9
|
+
export { COMPRESSION_MIN_BYTES, compress, decompress, isCompressed, } from './compression.js';
|
|
11
10
|
// Re-export composable encryption
|
|
12
|
-
export {
|
|
11
|
+
export { decrypt, encrypt, } from './encryption.js';
|
|
12
|
+
// Re-export format prefix utilities
|
|
13
|
+
export { decodeFormatPrefix, encodeWithFormatPrefix, isEncrypted, peekFormatPrefix, } from './format.js';
|
|
14
|
+
export { isFormatPrefix, SerializationFormat } from './types.js';
|
|
15
|
+
import * as client from './client.js';
|
|
16
|
+
import * as step from './step.js';
|
|
13
17
|
// Re-export mode-specific modules as namespaces
|
|
14
18
|
import * as workflow from './workflow.js';
|
|
15
|
-
import * as step from './step.js';
|
|
16
|
-
import * as client from './client.js';
|
|
17
19
|
export { workflow, step, client };
|
|
18
20
|
// Re-export revive helper (used by legacy compat in serialization.ts)
|
|
19
21
|
export { revive } from './reducers/common.js';
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvc2VyaWFsaXphdGlvbi9pbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7R0FLRztBQUlILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUNsRCxtQ0FBbUM7QUFDbkMsT0FBTyxFQUNMLHFCQUFxQixFQUdyQixRQUFRLEVBQ1IsVUFBVSxFQUNWLFlBQVksR0FDYixNQUFNLGtCQUFrQixDQUFDO0FBQzFCLGtDQUFrQztBQUNsQyxPQUFPLEVBRUwsT0FBTyxFQUVQLE9BQU8sR0FDUixNQUFNLGlCQUFpQixDQUFDO0FBRXpCLG9DQUFvQztBQUNwQyxPQUFPLEVBQ0wsa0JBQWtCLEVBQ2xCLHNCQUFzQixFQUN0QixXQUFXLEVBQ1gsZ0JBQWdCLEdBQ2pCLE1BQU0sYUFBYSxDQUFDO0FBUXJCLE9BQU8sRUFBRSxjQUFjLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFFakUsT0FBTyxLQUFLLE1BQU0sTUFBTSxhQUFhLENBQUM7QUFDdEMsT0FBTyxLQUFLLElBQUksTUFBTSxXQUFXLENBQUM7QUFDbEMsZ0RBQWdEO0FBQ2hELE9BQU8sS0FBSyxRQUFRLE1BQU0sZUFBZSxDQUFDO0FBQzFDLE9BQU8sRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLE1BQU0sRUFBRSxDQUFDO0FBRWxDLHNFQUFzRTtBQUN0RSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sc0JBQXNCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNlcmlhbGl6YXRpb24gbW9kdWxlIOKAlCBwdWJsaWMgQVBJLlxuICpcbiAqIFJlLWV4cG9ydHMgdGhlIG1vZGUtc3BlY2lmaWMgc2VyaWFsaXplL2Rlc2VyaWFsaXplIGZ1bmN0aW9ucyBhbmRcbiAqIHRoZSBjb2RlYy9mb3JtYXQvZW5jcnlwdGlvbiBhYnN0cmFjdGlvbnMuXG4gKi9cblxuLy8gUmUtZXhwb3J0IGNvZGVjIGludGVyZmFjZSBhbmQgbW9kZSB0eXBlXG5leHBvcnQgdHlwZSB7IENvZGVjLCBTZXJpYWxpemF0aW9uTW9kZSB9IGZyb20gJy4vY29kZWMuanMnO1xuZXhwb3J0IHsgZGV2YWx1ZUNvZGVjIH0gZnJvbSAnLi9jb2RlYy1kZXZhbHVlLmpzJztcbi8vIFJlLWV4cG9ydCBjb21wb3NhYmxlIGNvbXByZXNzaW9uXG5leHBvcnQge1xuICBDT01QUkVTU0lPTl9NSU5fQllURVMsXG4gIHR5cGUgQ29tcHJlc3Npb25Db2RlYyxcbiAgdHlwZSBDb21wcmVzc2lvblN0YXRzLFxuICBjb21wcmVzcyxcbiAgZGVjb21wcmVzcyxcbiAgaXNDb21wcmVzc2VkLFxufSBmcm9tICcuL2NvbXByZXNzaW9uLmpzJztcbi8vIFJlLWV4cG9ydCBjb21wb3NhYmxlIGVuY3J5cHRpb25cbmV4cG9ydCB7XG4gIHR5cGUgQ3J5cHRvS2V5LFxuICBkZWNyeXB0LFxuICB0eXBlIEVuY3J5cHRpb25LZXlQYXJhbSxcbiAgZW5jcnlwdCxcbn0gZnJvbSAnLi9lbmNyeXB0aW9uLmpzJztcblxuLy8gUmUtZXhwb3J0IGZvcm1hdCBwcmVmaXggdXRpbGl0aWVzXG5leHBvcnQge1xuICBkZWNvZGVGb3JtYXRQcmVmaXgsXG4gIGVuY29kZVdpdGhGb3JtYXRQcmVmaXgsXG4gIGlzRW5jcnlwdGVkLFxuICBwZWVrRm9ybWF0UHJlZml4LFxufSBmcm9tICcuL2Zvcm1hdC5qcyc7XG4vLyBSZS1leHBvcnQgdHlwZXNcbmV4cG9ydCB0eXBlIHtcbiAgRm9ybWF0UHJlZml4LFxuICBSZWR1Y2VycyxcbiAgUmV2aXZlcnMsXG4gIFNlcmlhbGl6YWJsZVNwZWNpYWwsXG59IGZyb20gJy4vdHlwZXMuanMnO1xuZXhwb3J0IHsgaXNGb3JtYXRQcmVmaXgsIFNlcmlhbGl6YXRpb25Gb3JtYXQgfSBmcm9tICcuL3R5cGVzLmpzJztcblxuaW1wb3J0ICogYXMgY2xpZW50IGZyb20gJy4vY2xpZW50LmpzJztcbmltcG9ydCAqIGFzIHN0ZXAgZnJvbSAnLi9zdGVwLmpzJztcbi8vIFJlLWV4cG9ydCBtb2RlLXNwZWNpZmljIG1vZHVsZXMgYXMgbmFtZXNwYWNlc1xuaW1wb3J0ICogYXMgd29ya2Zsb3cgZnJvbSAnLi93b3JrZmxvdy5qcyc7XG5leHBvcnQgeyB3b3JrZmxvdywgc3RlcCwgY2xpZW50IH07XG5cbi8vIFJlLWV4cG9ydCByZXZpdmUgaGVscGVyICh1c2VkIGJ5IGxlZ2FjeSBjb21wYXQgaW4gc2VyaWFsaXphdGlvbi50cylcbmV4cG9ydCB7IHJldml2ZSB9IGZyb20gJy4vcmVkdWNlcnMvY29tbW9uLmpzJztcbiJdfQ==
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../../src/serialization/step.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../../src/serialization/step.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,EACL,KAAK,SAAS,EAGf,MAAM,iBAAiB,CAAC;AAKzB;;GAEG;AACH,wBAAsB,SAAS,CAC7B,KAAK,EAAE,OAAO,EACd,aAAa,CAAC,EAAE,SAAS,EACzB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,UAAU,GAAG,OAAO,CAAC,CAmB/B;AAED;;GAEG;AACH,wBAAsB,WAAW,CAC/B,IAAI,EAAE,UAAU,GAAG,OAAO,EAC1B,aAAa,CAAC,EAAE,SAAS,EACzB,OAAO,CAAC,EAAE,YAAY,GACrB,OAAO,CAAC,OAAO,CAAC,CAsBlB"}
|