@abyss-project/main 34.1.2 → 34.2.0
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/server/archive/archive-seal.util.d.ts +7 -0
- package/dist/server/archive/archive-seal.util.js +75 -0
- package/dist/server/archive/archive-seal.util.js.map +1 -0
- package/dist/server/archive/archive-stream.service.d.ts +31 -0
- package/dist/server/archive/archive-stream.service.js +259 -0
- package/dist/server/archive/archive-stream.service.js.map +1 -0
- package/dist/server/archive/archive-upload-session.d.ts +5 -0
- package/dist/server/archive/archive-upload-session.js +3 -0
- package/dist/server/archive/archive-upload-session.js.map +1 -0
- package/dist/server/archive/index.d.ts +4 -0
- package/dist/server/archive/index.js +21 -0
- package/dist/server/archive/index.js.map +1 -0
- package/dist/server/archive/tests/archive-fixture.spec.d.ts +1 -0
- package/dist/server/archive/tests/archive-fixture.spec.js +84 -0
- package/dist/server/archive/tests/archive-fixture.spec.js.map +1 -0
- package/dist/server/archive/tests/archive-seal.util.spec.d.ts +1 -0
- package/dist/server/archive/tests/archive-seal.util.spec.js +98 -0
- package/dist/server/archive/tests/archive-seal.util.spec.js.map +1 -0
- package/dist/server/archive/tests/archive-stream.service.spec.d.ts +1 -0
- package/dist/server/archive/tests/archive-stream.service.spec.js +309 -0
- package/dist/server/archive/tests/archive-stream.service.spec.js.map +1 -0
- package/dist/server/archive/zstd.util.d.ts +19 -0
- package/dist/server/archive/zstd.util.js +43 -0
- package/dist/server/archive/zstd.util.js.map +1 -0
- package/dist/server/index.d.ts +1 -0
- package/dist/server/index.js +1 -0
- package/dist/server/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const ARCHIVE_KEY_BYTES = 32;
|
|
2
|
+
export declare const seal: (plaintext: Buffer, key: Buffer) => Buffer;
|
|
3
|
+
export declare const unseal: (payload: Buffer, key: Buffer) => Buffer;
|
|
4
|
+
export declare const generateArchiveKey: () => Buffer;
|
|
5
|
+
export declare const parseMasterKey: (raw: string, variableName: string) => Buffer;
|
|
6
|
+
export declare const wrapKey: (organizationKey: Buffer, masterKey: Buffer) => string;
|
|
7
|
+
export declare const unwrapKey: (wrappedKey: string, masterKey: Buffer) => Buffer;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.unwrapKey = exports.wrapKey = exports.parseMasterKey = exports.generateArchiveKey = exports.unseal = exports.seal = exports.ARCHIVE_KEY_BYTES = void 0;
|
|
37
|
+
const crypto = __importStar(require("crypto"));
|
|
38
|
+
const ALGORITHM = 'aes-256-gcm';
|
|
39
|
+
exports.ARCHIVE_KEY_BYTES = 32;
|
|
40
|
+
const IV_BYTES = 12;
|
|
41
|
+
const AUTH_TAG_BYTES = 16;
|
|
42
|
+
const seal = (plaintext, key) => {
|
|
43
|
+
const iv = crypto.randomBytes(IV_BYTES);
|
|
44
|
+
const cipher = crypto.createCipheriv(ALGORITHM, key, iv);
|
|
45
|
+
const ciphertext = Buffer.concat([cipher.update(plaintext), cipher.final()]);
|
|
46
|
+
return Buffer.concat([iv, cipher.getAuthTag(), ciphertext]);
|
|
47
|
+
};
|
|
48
|
+
exports.seal = seal;
|
|
49
|
+
const unseal = (payload, key) => {
|
|
50
|
+
if (payload.length < IV_BYTES + AUTH_TAG_BYTES) {
|
|
51
|
+
throw new Error('Malformed sealed payload');
|
|
52
|
+
}
|
|
53
|
+
const iv = payload.subarray(0, IV_BYTES);
|
|
54
|
+
const authTag = payload.subarray(IV_BYTES, IV_BYTES + AUTH_TAG_BYTES);
|
|
55
|
+
const ciphertext = payload.subarray(IV_BYTES + AUTH_TAG_BYTES);
|
|
56
|
+
const decipher = crypto.createDecipheriv(ALGORITHM, key, iv);
|
|
57
|
+
decipher.setAuthTag(authTag);
|
|
58
|
+
return Buffer.concat([decipher.update(ciphertext), decipher.final()]);
|
|
59
|
+
};
|
|
60
|
+
exports.unseal = unseal;
|
|
61
|
+
const generateArchiveKey = () => crypto.randomBytes(exports.ARCHIVE_KEY_BYTES);
|
|
62
|
+
exports.generateArchiveKey = generateArchiveKey;
|
|
63
|
+
const parseMasterKey = (raw, variableName) => {
|
|
64
|
+
const key = Buffer.from(raw, 'hex');
|
|
65
|
+
if (key.length !== exports.ARCHIVE_KEY_BYTES) {
|
|
66
|
+
throw new Error(`${variableName} must be ${exports.ARCHIVE_KEY_BYTES} bytes of hex (${exports.ARCHIVE_KEY_BYTES * 2} characters), got ${key.length} bytes`);
|
|
67
|
+
}
|
|
68
|
+
return key;
|
|
69
|
+
};
|
|
70
|
+
exports.parseMasterKey = parseMasterKey;
|
|
71
|
+
const wrapKey = (organizationKey, masterKey) => (0, exports.seal)(organizationKey, masterKey).toString('base64');
|
|
72
|
+
exports.wrapKey = wrapKey;
|
|
73
|
+
const unwrapKey = (wrappedKey, masterKey) => (0, exports.unseal)(Buffer.from(wrappedKey, 'base64'), masterKey);
|
|
74
|
+
exports.unwrapKey = unwrapKey;
|
|
75
|
+
//# sourceMappingURL=archive-seal.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-seal.util.js","sourceRoot":"","sources":["../../../src/server/archive/archive-seal.util.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAUjC,MAAM,SAAS,GAAG,aAAa,CAAC;AACnB,QAAA,iBAAiB,GAAG,EAAE,CAAC;AACpC,MAAM,QAAQ,GAAG,EAAE,CAAC;AACpB,MAAM,cAAc,GAAG,EAAE,CAAC;AAGnB,MAAM,IAAI,GAAG,CAAC,SAAiB,EAAE,GAAW,EAAU,EAAE;IAC7D,MAAM,EAAE,GAAG,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,MAAM,GAAG,MAAM,CAAC,cAAc,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IAE7E,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,MAAM,CAAC,UAAU,EAAE,EAAE,UAAU,CAAC,CAAC,CAAC;AAC9D,CAAC,CAAC;AANW,QAAA,IAAI,QAMf;AAEK,MAAM,MAAM,GAAG,CAAC,OAAe,EAAE,GAAW,EAAU,EAAE;IAC7D,IAAI,OAAO,CAAC,MAAM,GAAG,QAAQ,GAAG,cAAc,EAAE,CAAC;QAC/C,MAAM,IAAI,KAAK,CAAC,0BAA0B,CAAC,CAAC;IAC9C,CAAC;IAED,MAAM,EAAE,GAAG,OAAO,CAAC,QAAQ,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,CAAC,CAAC;IACtE,MAAM,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,QAAQ,GAAG,cAAc,CAAC,CAAC;IAE/D,MAAM,QAAQ,GAAG,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,CAAC,CAAC;IAC7D,QAAQ,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IAK7B,OAAO,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACxE,CAAC,CAAC;AAhBW,QAAA,MAAM,UAgBjB;AAGK,MAAM,kBAAkB,GAAG,GAAW,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,yBAAiB,CAAC,CAAC;AAAzE,QAAA,kBAAkB,sBAAuD;AAM/E,MAAM,cAAc,GAAG,CAAC,GAAW,EAAE,YAAoB,EAAU,EAAE;IAC1E,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEpC,IAAI,GAAG,CAAC,MAAM,KAAK,yBAAiB,EAAE,CAAC;QAGrC,MAAM,IAAI,KAAK,CACb,GAAG,YAAY,YAAY,yBAAiB,kBAC1C,yBAAiB,GAAG,CACtB,qBAAqB,GAAG,CAAC,MAAM,QAAQ,CACxC,CAAC;IACJ,CAAC;IAED,OAAO,GAAG,CAAC;AACb,CAAC,CAAC;AAdW,QAAA,cAAc,kBAczB;AAGK,MAAM,OAAO,GAAG,CAAC,eAAuB,EAAE,SAAiB,EAAU,EAAE,CAC5E,IAAA,YAAI,EAAC,eAAe,EAAE,SAAS,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;AADzC,QAAA,OAAO,WACkC;AAE/C,MAAM,SAAS,GAAG,CAAC,UAAkB,EAAE,SAAiB,EAAU,EAAE,CACzE,IAAA,cAAM,EAAC,MAAM,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,EAAE,SAAS,CAAC,CAAC;AAD1C,QAAA,SAAS,aACiC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import type { ArchiveUploadSession } from './archive-upload-session';
|
|
2
|
+
export type ArchiveRow = Record<string, unknown>;
|
|
3
|
+
export interface ArchivePart {
|
|
4
|
+
partNumber: number;
|
|
5
|
+
bytes: number;
|
|
6
|
+
rowCount: number;
|
|
7
|
+
firstTimestamp: string;
|
|
8
|
+
}
|
|
9
|
+
export interface ArchiveWriteResult {
|
|
10
|
+
parts: ArchivePart[];
|
|
11
|
+
totalRows: number;
|
|
12
|
+
totalBytes: number;
|
|
13
|
+
sha256: string;
|
|
14
|
+
}
|
|
15
|
+
export interface ArchiveWriteOptions {
|
|
16
|
+
key: Buffer;
|
|
17
|
+
session: Pick<ArchiveUploadSession, 'putPart'>;
|
|
18
|
+
timeColumn: string;
|
|
19
|
+
compressionLevel: number;
|
|
20
|
+
partMaxBytes: number;
|
|
21
|
+
}
|
|
22
|
+
export declare const ARCHIVE_PART_MAX_BYTES: number;
|
|
23
|
+
export declare const ARCHIVE_MAX_PARTS = 10000;
|
|
24
|
+
export declare const ARCHIVE_ROW_BATCH_SIZE = 1000;
|
|
25
|
+
export declare const SEAL_OVERHEAD_BYTES: number;
|
|
26
|
+
export declare const writeArchiveStream: (batches: AsyncIterable<ArchiveRow[]>, options: ArchiveWriteOptions) => Promise<ArchiveWriteResult>;
|
|
27
|
+
export declare function decodeArchiveFrame(sealedFrame: Buffer, key: Buffer): AsyncGenerator<ArchiveRow>;
|
|
28
|
+
export declare function splitArchiveFrames(source: AsyncIterable<Buffer>, parts: ArchivePart[]): AsyncGenerator<{
|
|
29
|
+
part: ArchivePart;
|
|
30
|
+
sealed: Buffer;
|
|
31
|
+
}>;
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.writeArchiveStream = exports.SEAL_OVERHEAD_BYTES = exports.ARCHIVE_ROW_BATCH_SIZE = exports.ARCHIVE_MAX_PARTS = exports.ARCHIVE_PART_MAX_BYTES = void 0;
|
|
37
|
+
exports.decodeArchiveFrame = decodeArchiveFrame;
|
|
38
|
+
exports.splitArchiveFrames = splitArchiveFrames;
|
|
39
|
+
const crypto = __importStar(require("crypto"));
|
|
40
|
+
const events_1 = require("events");
|
|
41
|
+
const promises_1 = require("stream/promises");
|
|
42
|
+
const zstd_util_1 = require("./zstd.util");
|
|
43
|
+
const archive_seal_util_1 = require("./archive-seal.util");
|
|
44
|
+
exports.ARCHIVE_PART_MAX_BYTES = 16 * 1024 * 1024;
|
|
45
|
+
exports.ARCHIVE_MAX_PARTS = 10_000;
|
|
46
|
+
exports.ARCHIVE_ROW_BATCH_SIZE = 1000;
|
|
47
|
+
exports.SEAL_OVERHEAD_BYTES = 12 + 16;
|
|
48
|
+
const NDJSON_SEPARATOR = '\n';
|
|
49
|
+
const NDJSON_SEPARATOR_BYTE = 0x0a;
|
|
50
|
+
const COMPRESSOR_WRITE_BYTES = 64 * 1024;
|
|
51
|
+
const ZSTD_BLOCK_SIZE_MAX = 128 * 1024;
|
|
52
|
+
const ZSTD_FRAME_EPILOGUE_BYTES = 3 + 4;
|
|
53
|
+
const zstdCompressBound = (size) => size +
|
|
54
|
+
Math.floor(size / 256) +
|
|
55
|
+
(size < ZSTD_BLOCK_SIZE_MAX ? Math.floor((ZSTD_BLOCK_SIZE_MAX - size) / 2048) : 0);
|
|
56
|
+
const timestampOf = (row, timeColumn) => {
|
|
57
|
+
const value = row[timeColumn];
|
|
58
|
+
const date = value instanceof Date ? value : typeof value === 'string' ? new Date(value) : undefined;
|
|
59
|
+
if (!date || Number.isNaN(date.getTime())) {
|
|
60
|
+
throw new Error(`Archive row has no usable ${timeColumn} (got ${String(value)})`);
|
|
61
|
+
}
|
|
62
|
+
return date;
|
|
63
|
+
};
|
|
64
|
+
class ZstdFrame {
|
|
65
|
+
constructor(compressionLevel, firstTimestamp) {
|
|
66
|
+
this.firstTimestamp = firstTimestamp;
|
|
67
|
+
this.rowCount = 0;
|
|
68
|
+
this.output = [];
|
|
69
|
+
this.emittedBytes = 0;
|
|
70
|
+
this.unflushedRawBytes = 0;
|
|
71
|
+
this.pendingLines = [];
|
|
72
|
+
this.pendingBytes = 0;
|
|
73
|
+
this.failure = null;
|
|
74
|
+
this.compressor = zstd_util_1.zstd.createZstdCompress((0, zstd_util_1.zstdCompressionOptions)(compressionLevel));
|
|
75
|
+
this.compressor.on('data', (chunk) => {
|
|
76
|
+
this.output.push(chunk);
|
|
77
|
+
this.emittedBytes += chunk.length;
|
|
78
|
+
});
|
|
79
|
+
this.compressor.on('error', (error) => {
|
|
80
|
+
this.failure = error;
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async fits(lineBytes, budget) {
|
|
84
|
+
if (this.upperBound(lineBytes) <= budget) {
|
|
85
|
+
return true;
|
|
86
|
+
}
|
|
87
|
+
await this.flush();
|
|
88
|
+
return this.upperBound(lineBytes) <= budget;
|
|
89
|
+
}
|
|
90
|
+
async append(line, lineBytes) {
|
|
91
|
+
this.throwIfFailed();
|
|
92
|
+
this.pendingLines.push(line);
|
|
93
|
+
this.pendingBytes += lineBytes;
|
|
94
|
+
this.unflushedRawBytes += lineBytes;
|
|
95
|
+
this.rowCount += 1;
|
|
96
|
+
if (this.pendingBytes >= COMPRESSOR_WRITE_BYTES) {
|
|
97
|
+
await this.writePending();
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async finish() {
|
|
101
|
+
await this.writePending();
|
|
102
|
+
this.compressor.end();
|
|
103
|
+
await (0, promises_1.finished)(this.compressor);
|
|
104
|
+
this.throwIfFailed();
|
|
105
|
+
return Buffer.concat(this.output);
|
|
106
|
+
}
|
|
107
|
+
destroy() {
|
|
108
|
+
this.compressor.destroy();
|
|
109
|
+
}
|
|
110
|
+
upperBound(extraRawBytes) {
|
|
111
|
+
return (this.emittedBytes +
|
|
112
|
+
zstdCompressBound(this.unflushedRawBytes + extraRawBytes) +
|
|
113
|
+
ZSTD_FRAME_EPILOGUE_BYTES);
|
|
114
|
+
}
|
|
115
|
+
async writePending() {
|
|
116
|
+
this.throwIfFailed();
|
|
117
|
+
if (this.pendingBytes === 0) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const chunk = Buffer.from(this.pendingLines.join(''), 'utf8');
|
|
121
|
+
this.pendingLines = [];
|
|
122
|
+
this.pendingBytes = 0;
|
|
123
|
+
if (!this.compressor.write(chunk)) {
|
|
124
|
+
await (0, events_1.once)(this.compressor, 'drain');
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
async flush() {
|
|
128
|
+
await this.writePending();
|
|
129
|
+
await new Promise((resolve, reject) => {
|
|
130
|
+
this.compressor.flush((error) => (error ? reject(error) : resolve()));
|
|
131
|
+
});
|
|
132
|
+
while (this.compressor.readableLength > 0) {
|
|
133
|
+
await (0, events_1.once)(this.compressor, 'data');
|
|
134
|
+
}
|
|
135
|
+
this.throwIfFailed();
|
|
136
|
+
this.unflushedRawBytes = 0;
|
|
137
|
+
}
|
|
138
|
+
throwIfFailed() {
|
|
139
|
+
if (this.failure) {
|
|
140
|
+
throw this.failure;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const writeArchiveStream = async (batches, options) => {
|
|
145
|
+
const { key, session, timeColumn, compressionLevel, partMaxBytes } = options;
|
|
146
|
+
const frameBudget = partMaxBytes - exports.SEAL_OVERHEAD_BYTES;
|
|
147
|
+
if (frameBudget <= 0) {
|
|
148
|
+
throw new Error(`Archive part size ${partMaxBytes} leaves no room for a frame after the ${exports.SEAL_OVERHEAD_BYTES}-byte seal`);
|
|
149
|
+
}
|
|
150
|
+
const digest = crypto.createHash('sha256');
|
|
151
|
+
const parts = [];
|
|
152
|
+
let frame = null;
|
|
153
|
+
let previousDateMs = Number.NEGATIVE_INFINITY;
|
|
154
|
+
const closeFrame = async (current) => {
|
|
155
|
+
const sealed = (0, archive_seal_util_1.seal)(await current.finish(), key);
|
|
156
|
+
const partNumber = parts.length + 1;
|
|
157
|
+
if (sealed.length > partMaxBytes) {
|
|
158
|
+
throw new Error(`Archive part ${partNumber} seals to ${sealed.length} bytes, above the ${partMaxBytes}-byte part size: a single row larger than a part cannot be archived`);
|
|
159
|
+
}
|
|
160
|
+
if (partNumber > exports.ARCHIVE_MAX_PARTS) {
|
|
161
|
+
throw new Error(`Archive object needs more than ${exports.ARCHIVE_MAX_PARTS} parts, the most one AbyssStorage upload session accepts`);
|
|
162
|
+
}
|
|
163
|
+
await session.putPart(partNumber, sealed);
|
|
164
|
+
digest.update(sealed);
|
|
165
|
+
parts.push({
|
|
166
|
+
partNumber,
|
|
167
|
+
bytes: sealed.length,
|
|
168
|
+
rowCount: current.rowCount,
|
|
169
|
+
firstTimestamp: current.firstTimestamp,
|
|
170
|
+
});
|
|
171
|
+
};
|
|
172
|
+
try {
|
|
173
|
+
for await (const batch of batches) {
|
|
174
|
+
for (const row of batch) {
|
|
175
|
+
const date = timestampOf(row, timeColumn);
|
|
176
|
+
if (date.getTime() < previousDateMs) {
|
|
177
|
+
throw new Error(`Archive rows must arrive ordered by ${timeColumn}: ${date.toISOString()} came after ${new Date(previousDateMs).toISOString()}`);
|
|
178
|
+
}
|
|
179
|
+
previousDateMs = date.getTime();
|
|
180
|
+
const line = `${JSON.stringify(row)}${NDJSON_SEPARATOR}`;
|
|
181
|
+
const lineBytes = Buffer.byteLength(line, 'utf8');
|
|
182
|
+
if (frame && !(await frame.fits(lineBytes, frameBudget))) {
|
|
183
|
+
await closeFrame(frame);
|
|
184
|
+
frame = null;
|
|
185
|
+
}
|
|
186
|
+
if (!frame) {
|
|
187
|
+
frame = new ZstdFrame(compressionLevel, date.toISOString());
|
|
188
|
+
}
|
|
189
|
+
await frame.append(line, lineBytes);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
if (frame) {
|
|
193
|
+
await closeFrame(frame);
|
|
194
|
+
frame = null;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch (error) {
|
|
198
|
+
frame?.destroy();
|
|
199
|
+
throw error;
|
|
200
|
+
}
|
|
201
|
+
return {
|
|
202
|
+
parts,
|
|
203
|
+
totalRows: parts.reduce((total, part) => total + part.rowCount, 0),
|
|
204
|
+
totalBytes: parts.reduce((total, part) => total + part.bytes, 0),
|
|
205
|
+
sha256: digest.digest('hex'),
|
|
206
|
+
};
|
|
207
|
+
};
|
|
208
|
+
exports.writeArchiveStream = writeArchiveStream;
|
|
209
|
+
async function* decodeArchiveFrame(sealedFrame, key) {
|
|
210
|
+
const decompressor = zstd_util_1.zstd.createZstdDecompress();
|
|
211
|
+
decompressor.end((0, archive_seal_util_1.unseal)(sealedFrame, key));
|
|
212
|
+
let carry = [];
|
|
213
|
+
for await (const chunk of decompressor) {
|
|
214
|
+
let start = 0;
|
|
215
|
+
let separator = chunk.indexOf(NDJSON_SEPARATOR_BYTE, start);
|
|
216
|
+
while (separator !== -1) {
|
|
217
|
+
const tail = chunk.subarray(start, separator);
|
|
218
|
+
const line = carry.length === 0 ? tail : Buffer.concat([...carry, tail]);
|
|
219
|
+
carry = [];
|
|
220
|
+
yield JSON.parse(line.toString('utf8'));
|
|
221
|
+
start = separator + 1;
|
|
222
|
+
separator = chunk.indexOf(NDJSON_SEPARATOR_BYTE, start);
|
|
223
|
+
}
|
|
224
|
+
if (start < chunk.length) {
|
|
225
|
+
carry.push(chunk.subarray(start));
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (carry.length > 0) {
|
|
229
|
+
throw new Error('Archive frame ends inside a row');
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
async function* splitArchiveFrames(source, parts) {
|
|
233
|
+
let index = 0;
|
|
234
|
+
let held = [];
|
|
235
|
+
let heldBytes = 0;
|
|
236
|
+
for await (const chunk of source) {
|
|
237
|
+
let offset = 0;
|
|
238
|
+
while (offset < chunk.length) {
|
|
239
|
+
const part = parts[index];
|
|
240
|
+
if (!part) {
|
|
241
|
+
throw new Error(`Archive object is longer than its ${parts.length}-part index`);
|
|
242
|
+
}
|
|
243
|
+
const take = Math.min(part.bytes - heldBytes, chunk.length - offset);
|
|
244
|
+
held.push(chunk.subarray(offset, offset + take));
|
|
245
|
+
heldBytes += take;
|
|
246
|
+
offset += take;
|
|
247
|
+
if (heldBytes === part.bytes) {
|
|
248
|
+
yield { part, sealed: Buffer.concat(held) };
|
|
249
|
+
held = [];
|
|
250
|
+
heldBytes = 0;
|
|
251
|
+
index += 1;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
if (index !== parts.length) {
|
|
256
|
+
throw new Error(`Archive object ends inside part ${parts[index].partNumber}: ${heldBytes} of its ${parts[index].bytes} indexed bytes arrived`);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=archive-stream.service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-stream.service.js","sourceRoot":"","sources":["../../../src/server/archive/archive-stream.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+VA,gDAmCC;AAaD,gDAoCC;AAnbD,+CAAiC;AACjC,mCAA8B;AAC9B,8CAA2C;AAC3C,2CAA+E;AAC/E,2DAAmD;AA6DtC,QAAA,sBAAsB,GAAG,EAAE,GAAG,IAAI,GAAG,IAAI,CAAC;AAG1C,QAAA,iBAAiB,GAAG,MAAM,CAAC;AAG3B,QAAA,sBAAsB,GAAG,IAAI,CAAC;AAG9B,QAAA,mBAAmB,GAAG,EAAE,GAAG,EAAE,CAAC;AAI3C,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAC9B,MAAM,qBAAqB,GAAG,IAAI,CAAC;AAKnC,MAAM,sBAAsB,GAAG,EAAE,GAAG,IAAI,CAAC;AAGzC,MAAM,mBAAmB,GAAG,GAAG,GAAG,IAAI,CAAC;AAQvC,MAAM,yBAAyB,GAAG,CAAC,GAAG,CAAC,CAAC;AAGxC,MAAM,iBAAiB,GAAG,CAAC,IAAY,EAAU,EAAE,CACjD,IAAI;IACJ,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,GAAG,CAAC;IACtB,CAAC,IAAI,GAAG,mBAAmB,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,mBAAmB,GAAG,IAAI,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAIrF,MAAM,WAAW,GAAG,CAAC,GAAe,EAAE,UAAkB,EAAQ,EAAE;IAChE,MAAM,KAAK,GAAG,GAAG,CAAC,UAAU,CAAC,CAAC;IAC9B,MAAM,IAAI,GACR,KAAK,YAAY,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IAE1F,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAG1C,MAAM,IAAI,KAAK,CAAC,6BAA6B,UAAU,SAAS,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACpF,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC,CAAC;AAaF,MAAM,SAAS;IAab,YAAY,gBAAwB,EAAkB,cAAsB;QAAtB,mBAAc,GAAd,cAAc,CAAQ;QAZrE,aAAQ,GAAG,CAAC,CAAC;QAGH,WAAM,GAAa,EAAE,CAAC;QAE/B,iBAAY,GAAG,CAAC,CAAC;QAEjB,sBAAiB,GAAG,CAAC,CAAC;QACtB,iBAAY,GAAa,EAAE,CAAC;QAC5B,iBAAY,GAAG,CAAC,CAAC;QACjB,YAAO,GAAiB,IAAI,CAAC;QAGnC,IAAI,CAAC,UAAU,GAAG,gBAAI,CAAC,kBAAkB,CAAC,IAAA,kCAAsB,EAAC,gBAAgB,CAAC,CAAC,CAAC;QACpF,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,CAAC,KAAa,EAAE,EAAE;YAC3C,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACxB,IAAI,CAAC,YAAY,IAAI,KAAK,CAAC,MAAM,CAAC;QACpC,CAAC,CAAC,CAAC;QAGH,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAY,EAAE,EAAE;YAC3C,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACvB,CAAC,CAAC,CAAC;IACL,CAAC;IAGM,KAAK,CAAC,IAAI,CAAC,SAAiB,EAAE,MAAc;QACjD,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,EAAE,CAAC;YACzC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;QACnB,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC;IAC9C,CAAC;IAEM,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,SAAiB;QACjD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,YAAY,IAAI,SAAS,CAAC;QAC/B,IAAI,CAAC,iBAAiB,IAAI,SAAS,CAAC;QACpC,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;QAEnB,IAAI,IAAI,CAAC,YAAY,IAAI,sBAAsB,EAAE,CAAC;YAChD,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC5B,CAAC;IACH,CAAC;IAGM,KAAK,CAAC,MAAM;QACjB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,CAAC,GAAG,EAAE,CAAC;QACtB,MAAM,IAAA,mBAAQ,EAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,OAAO,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACpC,CAAC;IAEM,OAAO;QACZ,IAAI,CAAC,UAAU,CAAC,OAAO,EAAE,CAAC;IAC5B,CAAC;IAEO,UAAU,CAAC,aAAqB;QACtC,OAAO,CACL,IAAI,CAAC,YAAY;YACjB,iBAAiB,CAAC,IAAI,CAAC,iBAAiB,GAAG,aAAa,CAAC;YACzD,yBAAyB,CAC1B,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,YAAY;QACxB,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,IAAI,CAAC,YAAY,KAAK,CAAC,EAAE,CAAC;YAC5B,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC;QAC9D,IAAI,CAAC,YAAY,GAAG,EAAE,CAAC;QACvB,IAAI,CAAC,YAAY,GAAG,CAAC,CAAC;QAItB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YAClC,MAAM,IAAA,aAAI,EAAC,IAAI,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,MAAM,IAAI,CAAC,YAAY,EAAE,CAAC;QAC1B,MAAM,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YAC1C,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAIH,OAAO,IAAI,CAAC,UAAU,CAAC,cAAc,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAA,aAAI,EAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QACtC,CAAC;QACD,IAAI,CAAC,aAAa,EAAE,CAAC;QACrB,IAAI,CAAC,iBAAiB,GAAG,CAAC,CAAC;IAC7B,CAAC;IAEO,aAAa;QACnB,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC;QACrB,CAAC;IACH,CAAC;CACF;AAYM,MAAM,kBAAkB,GAAG,KAAK,EACrC,OAAoC,EACpC,OAA4B,EACC,EAAE;IAC/B,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC;IAC7E,MAAM,WAAW,GAAG,YAAY,GAAG,2BAAmB,CAAC;IACvD,IAAI,WAAW,IAAI,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,qBAAqB,YAAY,yCAAyC,2BAAmB,YAAY,CAC1G,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,IAAI,KAAK,GAAqB,IAAI,CAAC;IACnC,IAAI,cAAc,GAAG,MAAM,CAAC,iBAAiB,CAAC;IAE9C,MAAM,UAAU,GAAG,KAAK,EAAE,OAAkB,EAAiB,EAAE;QAC7D,MAAM,MAAM,GAAG,IAAA,wBAAI,EAAC,MAAM,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;QAEpC,IAAI,MAAM,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;YAIjC,MAAM,IAAI,KAAK,CACb,gBAAgB,UAAU,aAAa,MAAM,CAAC,MAAM,qBAAqB,YAAY,qEAAqE,CAC3J,CAAC;QACJ,CAAC;QACD,IAAI,UAAU,GAAG,yBAAiB,EAAE,CAAC;YACnC,MAAM,IAAI,KAAK,CACb,kCAAkC,yBAAiB,0DAA0D,CAC9G,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,CAAC,OAAO,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC;YACT,UAAU;YACV,KAAK,EAAE,MAAM,CAAC,MAAM;YACpB,QAAQ,EAAE,OAAO,CAAC,QAAQ;YAC1B,cAAc,EAAE,OAAO,CAAC,cAAc;SACvC,CAAC,CAAC;IACL,CAAC,CAAC;IAEF,IAAI,CAAC;QACH,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAClC,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;gBAC1C,IAAI,IAAI,CAAC,OAAO,EAAE,GAAG,cAAc,EAAE,CAAC;oBACpC,MAAM,IAAI,KAAK,CACb,uCAAuC,UAAU,KAAK,IAAI,CAAC,WAAW,EAAE,eAAe,IAAI,IAAI,CAC7F,cAAc,CACf,CAAC,WAAW,EAAE,EAAE,CAClB,CAAC;gBACJ,CAAC;gBACD,cAAc,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;gBAEhC,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,GAAG,gBAAgB,EAAE,CAAC;gBACzD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBAElD,IAAI,KAAK,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC,EAAE,CAAC;oBACzD,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;oBACxB,KAAK,GAAG,IAAI,CAAC;gBACf,CAAC;gBAED,IAAI,CAAC,KAAK,EAAE,CAAC;oBACX,KAAK,GAAG,IAAI,SAAS,CAAC,gBAAgB,EAAE,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;gBAC9D,CAAC;gBACD,MAAM,KAAK,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACtC,CAAC;QACH,CAAC;QAED,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,UAAU,CAAC,KAAK,CAAC,CAAC;YACxB,KAAK,GAAG,IAAI,CAAC;QACf,CAAC;IACH,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,KAAK,EAAE,OAAO,EAAE,CAAC;QACjB,MAAM,KAAK,CAAC;IACd,CAAC;IAED,OAAO;QACL,KAAK;QACL,SAAS,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;QAClE,UAAU,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;QAChE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC;KAC7B,CAAC;AACJ,CAAC,CAAC;AAxFW,QAAA,kBAAkB,sBAwF7B;AAgBK,KAAK,SAAS,CAAC,CAAC,kBAAkB,CACvC,WAAmB,EACnB,GAAW;IAEX,MAAM,YAAY,GAAG,gBAAI,CAAC,oBAAoB,EAAE,CAAC;IACjD,YAAY,CAAC,GAAG,CAAC,IAAA,0BAAM,EAAC,WAAW,EAAE,GAAG,CAAC,CAAC,CAAC;IAK3C,IAAI,KAAK,GAAa,EAAE,CAAC;IAEzB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,YAAqC,EAAE,CAAC;QAChE,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAE5D,OAAO,SAAS,KAAK,CAAC,CAAC,EAAE,CAAC;YACxB,MAAM,IAAI,GAAG,KAAK,CAAC,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;YAC9C,MAAM,IAAI,GAAG,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;YACzE,KAAK,GAAG,EAAE,CAAC;YACX,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAe,CAAC;YACtD,KAAK,GAAG,SAAS,GAAG,CAAC,CAAC;YACtB,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,KAAK,CAAC,CAAC;QAC1D,CAAC;QAED,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YACzB,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;QACpC,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAGrB,MAAM,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC;IACrD,CAAC;AACH,CAAC;AAaM,KAAK,SAAS,CAAC,CAAC,kBAAkB,CACvC,MAA6B,EAC7B,KAAoB;IAEpB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,IAAI,GAAa,EAAE,CAAC;IACxB,IAAI,SAAS,GAAG,CAAC,CAAC;IAElB,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACjC,IAAI,MAAM,GAAG,CAAC,CAAC;QAEf,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,CAAC,IAAI,EAAE,CAAC;gBACV,MAAM,IAAI,KAAK,CAAC,qCAAqC,KAAK,CAAC,MAAM,aAAa,CAAC,CAAC;YAClF,CAAC;YAED,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,GAAG,SAAS,EAAE,KAAK,CAAC,MAAM,GAAG,MAAM,CAAC,CAAC;YACrE,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC;YACjD,SAAS,IAAI,IAAI,CAAC;YAClB,MAAM,IAAI,IAAI,CAAC;YAEf,IAAI,SAAS,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;gBAC7B,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC;gBAC5C,IAAI,GAAG,EAAE,CAAC;gBACV,SAAS,GAAG,CAAC,CAAC;gBACd,KAAK,IAAI,CAAC,CAAC;YACb,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,KAAK,KAAK,KAAK,CAAC,MAAM,EAAE,CAAC;QAC3B,MAAM,IAAI,KAAK,CACb,mCAAmC,KAAK,CAAC,KAAK,CAAC,CAAC,UAAU,KAAK,SAAS,WAAW,KAAK,CAAC,KAAK,CAAC,CAAC,KAAK,wBAAwB,CAC9H,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-upload-session.js","sourceRoot":"","sources":["../../../src/server/archive/archive-upload-session.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./archive-seal.util"), exports);
|
|
18
|
+
__exportStar(require("./archive-stream.service"), exports);
|
|
19
|
+
__exportStar(require("./archive-upload-session"), exports);
|
|
20
|
+
__exportStar(require("./zstd.util"), exports);
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/archive/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,sDAAoC;AACpC,2DAAyC;AACzC,2DAAyC;AACzC,8CAA4B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const crypto = __importStar(require("crypto"));
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const stream_1 = require("stream");
|
|
40
|
+
const archive_seal_util_1 = require("../archive-seal.util");
|
|
41
|
+
const archive_stream_service_1 = require("../archive-stream.service");
|
|
42
|
+
const FIXTURES = path.join(__dirname, 'fixtures');
|
|
43
|
+
const object = fs.readFileSync(path.join(FIXTURES, 'archive-object.bin'));
|
|
44
|
+
const expected = JSON.parse(fs.readFileSync(path.join(FIXTURES, 'archive-object.expected.json'), 'utf8'));
|
|
45
|
+
const key = Buffer.from(expected.keyHex, 'hex');
|
|
46
|
+
const decodeAll = async (source) => {
|
|
47
|
+
const rows = [];
|
|
48
|
+
for await (const { part, sealed } of (0, archive_stream_service_1.splitArchiveFrames)(source, expected.parts)) {
|
|
49
|
+
const decoded = [];
|
|
50
|
+
for await (const row of (0, archive_stream_service_1.decodeArchiveFrame)(sealed, key)) {
|
|
51
|
+
decoded.push(row);
|
|
52
|
+
}
|
|
53
|
+
expect(decoded).toHaveLength(part.rowCount);
|
|
54
|
+
expect(decoded[0].dateValue).toBe(part.firstTimestamp);
|
|
55
|
+
rows.push(...decoded);
|
|
56
|
+
}
|
|
57
|
+
return rows;
|
|
58
|
+
};
|
|
59
|
+
describe('archive object written by Monitor before the move', () => {
|
|
60
|
+
it('has the shape the fixture claims', () => {
|
|
61
|
+
expect(expected.parts.length).toBeGreaterThanOrEqual(2);
|
|
62
|
+
expect(object.length).toBe(expected.totalBytes);
|
|
63
|
+
expect(expected.parts.reduce((total, part) => total + part.bytes, 0)).toBe(object.length);
|
|
64
|
+
});
|
|
65
|
+
it('has the sha256 the writer recorded', () => {
|
|
66
|
+
expect(crypto.createHash('sha256').update(object).digest('hex')).toBe(expected.sha256);
|
|
67
|
+
});
|
|
68
|
+
it('unwraps the stored organization key with the master key', () => {
|
|
69
|
+
expect((0, archive_seal_util_1.unwrapKey)(expected.wrappedKey, Buffer.from(expected.masterKey, 'hex')).toString('hex')).toBe(expected.keyHex);
|
|
70
|
+
});
|
|
71
|
+
it('reads back to the exact rows, part by part', async () => {
|
|
72
|
+
const rows = await decodeAll(stream_1.Readable.from([object]));
|
|
73
|
+
expect(rows).toEqual(expected.rows);
|
|
74
|
+
expect(rows).toHaveLength(expected.totalRows);
|
|
75
|
+
});
|
|
76
|
+
it('is read the same when the stream arrives in arbitrary chunks', async () => {
|
|
77
|
+
const chunks = [];
|
|
78
|
+
for (let offset = 0; offset < object.length; offset += 97) {
|
|
79
|
+
chunks.push(object.subarray(offset, offset + 97));
|
|
80
|
+
}
|
|
81
|
+
expect(await decodeAll(stream_1.Readable.from(chunks))).toEqual(expected.rows);
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=archive-fixture.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-fixture.spec.js","sourceRoot":"","sources":["../../../../src/server/archive/tests/archive-fixture.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const crypto = __importStar(require("crypto"));
|
|
37
|
+
const archive_seal_util_1 = require("../archive-seal.util");
|
|
38
|
+
describe('seal / unseal', () => {
|
|
39
|
+
it('round-trips', () => {
|
|
40
|
+
const key = crypto.randomBytes(32);
|
|
41
|
+
const plaintext = Buffer.from('a log line with an Authorization header in it');
|
|
42
|
+
expect((0, archive_seal_util_1.unseal)((0, archive_seal_util_1.seal)(plaintext, key), key)).toEqual(plaintext);
|
|
43
|
+
});
|
|
44
|
+
it('produces an exact frame length: iv (12 o) + authTag (16 o) + ciphertext', () => {
|
|
45
|
+
const key = crypto.randomBytes(32);
|
|
46
|
+
const plaintext = crypto.randomBytes(1024 * 1024);
|
|
47
|
+
const sealed = (0, archive_seal_util_1.seal)(plaintext, key);
|
|
48
|
+
expect(sealed.length).toBe(12 + 16 + plaintext.length);
|
|
49
|
+
expect((0, archive_seal_util_1.unseal)(sealed, key)).toEqual(plaintext);
|
|
50
|
+
});
|
|
51
|
+
it('produces a different payload every time, so identical inputs do not look identical', () => {
|
|
52
|
+
const key = crypto.randomBytes(32);
|
|
53
|
+
const plaintext = Buffer.from('same input');
|
|
54
|
+
expect((0, archive_seal_util_1.seal)(plaintext, key)).not.toEqual((0, archive_seal_util_1.seal)(plaintext, key));
|
|
55
|
+
});
|
|
56
|
+
it('refuses a tampered payload instead of returning garbage', () => {
|
|
57
|
+
const key = crypto.randomBytes(32);
|
|
58
|
+
const sealed = (0, archive_seal_util_1.seal)(Buffer.from('trustworthy'), key);
|
|
59
|
+
const tampered = Buffer.from(sealed);
|
|
60
|
+
tampered[tampered.length - 1] ^= 0xff;
|
|
61
|
+
expect(() => (0, archive_seal_util_1.unseal)(tampered, key)).toThrow();
|
|
62
|
+
});
|
|
63
|
+
it('refuses the wrong key', () => {
|
|
64
|
+
const sealed = (0, archive_seal_util_1.seal)(Buffer.from('secret'), crypto.randomBytes(32));
|
|
65
|
+
expect(() => (0, archive_seal_util_1.unseal)(sealed, crypto.randomBytes(32))).toThrow();
|
|
66
|
+
});
|
|
67
|
+
it('refuses a payload shorter than its iv and tag', () => {
|
|
68
|
+
expect(() => (0, archive_seal_util_1.unseal)(Buffer.alloc(27), crypto.randomBytes(32))).toThrow('Malformed sealed payload');
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
describe('organization key wrapping', () => {
|
|
72
|
+
it('generates 32-byte keys, different every time', () => {
|
|
73
|
+
const a = (0, archive_seal_util_1.generateArchiveKey)();
|
|
74
|
+
expect(a.length).toBe(32);
|
|
75
|
+
expect((0, archive_seal_util_1.generateArchiveKey)()).not.toEqual(a);
|
|
76
|
+
});
|
|
77
|
+
it('wraps to base64 and unwraps to the same key, without storing it in the clear', () => {
|
|
78
|
+
const master = crypto.randomBytes(32);
|
|
79
|
+
const key = (0, archive_seal_util_1.generateArchiveKey)();
|
|
80
|
+
const wrapped = (0, archive_seal_util_1.wrapKey)(key, master);
|
|
81
|
+
const raw = Buffer.from(wrapped, 'base64');
|
|
82
|
+
expect((0, archive_seal_util_1.unwrapKey)(wrapped, master)).toEqual(key);
|
|
83
|
+
expect(raw.includes(key)).toBe(false);
|
|
84
|
+
expect(raw.length).toBe(12 + 16 + key.length);
|
|
85
|
+
});
|
|
86
|
+
it('does not unwrap with another master key', () => {
|
|
87
|
+
const wrapped = (0, archive_seal_util_1.wrapKey)((0, archive_seal_util_1.generateArchiveKey)(), crypto.randomBytes(32));
|
|
88
|
+
expect(() => (0, archive_seal_util_1.unwrapKey)(wrapped, crypto.randomBytes(32))).toThrow();
|
|
89
|
+
});
|
|
90
|
+
it('parses a 32-byte hex master key', () => {
|
|
91
|
+
const master = crypto.randomBytes(32);
|
|
92
|
+
expect((0, archive_seal_util_1.parseMasterKey)(master.toString('hex'), 'SOME_MASTER_KEY')).toEqual(master);
|
|
93
|
+
});
|
|
94
|
+
it('refuses a short master key and names the variable', () => {
|
|
95
|
+
expect(() => (0, archive_seal_util_1.parseMasterKey)('abcd', 'SOME_MASTER_KEY')).toThrow('SOME_MASTER_KEY must be 32 bytes of hex (64 characters), got 2 bytes');
|
|
96
|
+
});
|
|
97
|
+
});
|
|
98
|
+
//# sourceMappingURL=archive-seal.util.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-seal.util.spec.js","sourceRoot":"","sources":["../../../../src/server/archive/tests/archive-seal.util.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,309 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const crypto = __importStar(require("crypto"));
|
|
37
|
+
const stream_1 = require("stream");
|
|
38
|
+
const archive_seal_util_1 = require("../archive-seal.util");
|
|
39
|
+
const archive_stream_service_1 = require("../archive-stream.service");
|
|
40
|
+
const COMPRESSION_LEVEL = 1;
|
|
41
|
+
const TIME_COLUMN = 'dateValue';
|
|
42
|
+
const DAY_START = Date.UTC(2026, 0, 10);
|
|
43
|
+
const newKey = () => crypto.randomBytes(32);
|
|
44
|
+
const recordingSession = () => {
|
|
45
|
+
const payloads = new Map();
|
|
46
|
+
return {
|
|
47
|
+
payloads,
|
|
48
|
+
putPart: jest.fn(async (partNumber, payload) => {
|
|
49
|
+
payloads.set(partNumber, Buffer.from(payload));
|
|
50
|
+
}),
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
const noise = (seed, length) => {
|
|
54
|
+
let text = '';
|
|
55
|
+
for (let counter = 0; text.length < length; counter += 1) {
|
|
56
|
+
text += crypto.createHash('sha256').update(`${seed}:${counter}`).digest('base64');
|
|
57
|
+
}
|
|
58
|
+
return text.slice(0, length);
|
|
59
|
+
};
|
|
60
|
+
const makeRows = (count, messageLength = () => 24) => Array.from({ length: count }, (_, index) => ({
|
|
61
|
+
id: `row-${index}`,
|
|
62
|
+
applicationId: 'application-under-test',
|
|
63
|
+
level: index % 6,
|
|
64
|
+
message: `message ${index} ${noise(index, messageLength(index))}`,
|
|
65
|
+
dateValue: new Date(DAY_START + index * 1000),
|
|
66
|
+
}));
|
|
67
|
+
async function* inBatches(rows, size) {
|
|
68
|
+
for (let start = 0; start < rows.length; start += size) {
|
|
69
|
+
yield rows.slice(start, start + size);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
const asArchived = (rows) => JSON.parse(JSON.stringify(rows));
|
|
73
|
+
const decodeAll = async (sealed, key) => {
|
|
74
|
+
const rows = [];
|
|
75
|
+
for await (const row of (0, archive_stream_service_1.decodeArchiveFrame)(sealed, key)) {
|
|
76
|
+
rows.push(row);
|
|
77
|
+
}
|
|
78
|
+
return rows;
|
|
79
|
+
};
|
|
80
|
+
const sha256Of = (buffers) => crypto.createHash('sha256').update(Buffer.concat(buffers)).digest('hex');
|
|
81
|
+
const payloadsInOrder = (session, parts) => parts.map((part) => session.payloads.get(part.partNumber));
|
|
82
|
+
describe('archive-stream.service', () => {
|
|
83
|
+
describe('writeArchiveStream', () => {
|
|
84
|
+
it('cuts a day bigger than a part into parts that each decode alone and give the day back in order', async () => {
|
|
85
|
+
const key = newKey();
|
|
86
|
+
const session = recordingSession();
|
|
87
|
+
const rows = makeRows(50_000);
|
|
88
|
+
const partMaxBytes = 16 * 1024;
|
|
89
|
+
const result = await (0, archive_stream_service_1.writeArchiveStream)(inBatches(rows, 1000), {
|
|
90
|
+
key,
|
|
91
|
+
session,
|
|
92
|
+
timeColumn: TIME_COLUMN,
|
|
93
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
94
|
+
partMaxBytes,
|
|
95
|
+
});
|
|
96
|
+
expect(result.parts.length).toBeGreaterThanOrEqual(3);
|
|
97
|
+
expect(result.parts.map((part) => part.partNumber)).toEqual(result.parts.map((_, index) => index + 1));
|
|
98
|
+
expect([...session.payloads.keys()]).toEqual(result.parts.map((part) => part.partNumber));
|
|
99
|
+
const decoded = [];
|
|
100
|
+
for (const part of result.parts) {
|
|
101
|
+
const sealed = session.payloads.get(part.partNumber);
|
|
102
|
+
const partRows = await decodeAll(sealed, key);
|
|
103
|
+
expect(sealed.length).toBeLessThanOrEqual(partMaxBytes);
|
|
104
|
+
expect(part.bytes).toBe(sealed.length);
|
|
105
|
+
expect(part.rowCount).toBe(partRows.length);
|
|
106
|
+
expect(part.firstTimestamp).toBe(partRows[0].dateValue);
|
|
107
|
+
decoded.push(...partRows);
|
|
108
|
+
}
|
|
109
|
+
expect(decoded).toEqual(asArchived(rows));
|
|
110
|
+
expect(result.totalRows).toBe(rows.length);
|
|
111
|
+
const stored = payloadsInOrder(session, result.parts);
|
|
112
|
+
expect(result.totalBytes).toBe(stored.reduce((total, sealed) => total + sealed.length, 0));
|
|
113
|
+
expect(result.sha256).toBe(sha256Of(stored));
|
|
114
|
+
});
|
|
115
|
+
it('never holds more rows at once than one batch', async () => {
|
|
116
|
+
const batchSize = 250;
|
|
117
|
+
let handedOut = 0;
|
|
118
|
+
let encoded = 0;
|
|
119
|
+
let mostAlive = 0;
|
|
120
|
+
const observe = () => {
|
|
121
|
+
mostAlive = Math.max(mostAlive, handedOut - encoded);
|
|
122
|
+
};
|
|
123
|
+
const rows = makeRows(20_000).map((row) => ({
|
|
124
|
+
...row,
|
|
125
|
+
toJSON: () => {
|
|
126
|
+
encoded += 1;
|
|
127
|
+
observe();
|
|
128
|
+
return row;
|
|
129
|
+
},
|
|
130
|
+
}));
|
|
131
|
+
async function* spiedBatches() {
|
|
132
|
+
for (let start = 0; start < rows.length; start += batchSize) {
|
|
133
|
+
const batch = rows.slice(start, start + batchSize);
|
|
134
|
+
handedOut += batch.length;
|
|
135
|
+
observe();
|
|
136
|
+
yield batch;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
const result = await (0, archive_stream_service_1.writeArchiveStream)(spiedBatches(), {
|
|
140
|
+
key: newKey(),
|
|
141
|
+
session: recordingSession(),
|
|
142
|
+
timeColumn: TIME_COLUMN,
|
|
143
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
144
|
+
partMaxBytes: 16 * 1024,
|
|
145
|
+
});
|
|
146
|
+
expect(result.totalRows).toBe(rows.length);
|
|
147
|
+
expect(encoded).toBe(rows.length);
|
|
148
|
+
expect(mostAlive).toBe(batchSize);
|
|
149
|
+
});
|
|
150
|
+
it('cuts on the bytes written, never on a number of rows', async () => {
|
|
151
|
+
const session = recordingSession();
|
|
152
|
+
const partMaxBytes = 16 * 1024;
|
|
153
|
+
const rows = makeRows(3_000, (index) => 50 + ((index * 7919) % 1500));
|
|
154
|
+
const result = await (0, archive_stream_service_1.writeArchiveStream)(inBatches(rows, 500), {
|
|
155
|
+
key: newKey(),
|
|
156
|
+
session,
|
|
157
|
+
timeColumn: TIME_COLUMN,
|
|
158
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
159
|
+
partMaxBytes,
|
|
160
|
+
});
|
|
161
|
+
const sizes = payloadsInOrder(session, result.parts).map((sealed) => sealed.length);
|
|
162
|
+
for (const size of sizes) {
|
|
163
|
+
expect(size).toBeLessThanOrEqual(partMaxBytes);
|
|
164
|
+
}
|
|
165
|
+
for (const size of sizes.slice(0, -1)) {
|
|
166
|
+
expect(size).toBeGreaterThan(partMaxBytes * 0.75);
|
|
167
|
+
}
|
|
168
|
+
expect(new Set(result.parts.map((part) => part.rowCount)).size).toBeGreaterThan(1);
|
|
169
|
+
});
|
|
170
|
+
it('refuses a single row larger than a part rather than sending an oversized part', async () => {
|
|
171
|
+
const session = recordingSession();
|
|
172
|
+
await expect((0, archive_stream_service_1.writeArchiveStream)(inBatches(makeRows(1, () => 8_000), 1), {
|
|
173
|
+
key: newKey(),
|
|
174
|
+
session,
|
|
175
|
+
timeColumn: TIME_COLUMN,
|
|
176
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
177
|
+
partMaxBytes: 2048,
|
|
178
|
+
})).rejects.toThrow(/above the 2048-byte part size/);
|
|
179
|
+
expect(session.putPart).not.toHaveBeenCalled();
|
|
180
|
+
});
|
|
181
|
+
it('refuses rows that go back in time, rather than writing an index that lies', async () => {
|
|
182
|
+
const [first, second, ...rest] = makeRows(10);
|
|
183
|
+
await expect((0, archive_stream_service_1.writeArchiveStream)(inBatches([second, first, ...rest], 10), {
|
|
184
|
+
key: newKey(),
|
|
185
|
+
session: recordingSession(),
|
|
186
|
+
timeColumn: TIME_COLUMN,
|
|
187
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
188
|
+
partMaxBytes: 16 * 1024,
|
|
189
|
+
})).rejects.toThrow(/ordered by dateValue/);
|
|
190
|
+
});
|
|
191
|
+
it("orders and indexes on the table's own time column, which is not always dateValue", async () => {
|
|
192
|
+
const key = newKey();
|
|
193
|
+
const session = recordingSession();
|
|
194
|
+
const rows = Array.from({ length: 3_000 }, (_, index) => ({
|
|
195
|
+
id: `history-${index}`,
|
|
196
|
+
applicationCronTaskId: 'cron-task-under-test',
|
|
197
|
+
startDate: new Date(DAY_START + index * 1000),
|
|
198
|
+
responseBody: noise(index, 40),
|
|
199
|
+
}));
|
|
200
|
+
const result = await (0, archive_stream_service_1.writeArchiveStream)(inBatches(rows, 500), {
|
|
201
|
+
key,
|
|
202
|
+
session,
|
|
203
|
+
timeColumn: 'startDate',
|
|
204
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
205
|
+
partMaxBytes: 8 * 1024,
|
|
206
|
+
});
|
|
207
|
+
expect(result.parts.length).toBeGreaterThanOrEqual(3);
|
|
208
|
+
for (const part of result.parts) {
|
|
209
|
+
const partRows = await decodeAll(session.payloads.get(part.partNumber), key);
|
|
210
|
+
expect(part.firstTimestamp).toBe(partRows[0].startDate);
|
|
211
|
+
}
|
|
212
|
+
const [first, second, ...rest] = rows;
|
|
213
|
+
await expect((0, archive_stream_service_1.writeArchiveStream)(inBatches([second, first, ...rest], 500), {
|
|
214
|
+
key,
|
|
215
|
+
session: recordingSession(),
|
|
216
|
+
timeColumn: 'startDate',
|
|
217
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
218
|
+
partMaxBytes: 8 * 1024,
|
|
219
|
+
})).rejects.toThrow(/ordered by startDate/);
|
|
220
|
+
});
|
|
221
|
+
it('refuses a row without a usable dateValue, which the index could not place', async () => {
|
|
222
|
+
await expect((0, archive_stream_service_1.writeArchiveStream)(inBatches([{ id: 'no-date', message: 'orphan' }], 1), {
|
|
223
|
+
key: newKey(),
|
|
224
|
+
session: recordingSession(),
|
|
225
|
+
timeColumn: TIME_COLUMN,
|
|
226
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
227
|
+
partMaxBytes: 16 * 1024,
|
|
228
|
+
})).rejects.toThrow(/no usable dateValue/);
|
|
229
|
+
});
|
|
230
|
+
it('writes no part for a day without rows', async () => {
|
|
231
|
+
const session = recordingSession();
|
|
232
|
+
const result = await (0, archive_stream_service_1.writeArchiveStream)(inBatches([], 10), {
|
|
233
|
+
key: newKey(),
|
|
234
|
+
session,
|
|
235
|
+
timeColumn: TIME_COLUMN,
|
|
236
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
237
|
+
partMaxBytes: 16 * 1024,
|
|
238
|
+
});
|
|
239
|
+
expect(result).toEqual({ parts: [], totalRows: 0, totalBytes: 0, sha256: sha256Of([]) });
|
|
240
|
+
expect(session.putPart).not.toHaveBeenCalled();
|
|
241
|
+
});
|
|
242
|
+
it('accounts for exactly what seal adds to a frame', () => {
|
|
243
|
+
expect((0, archive_seal_util_1.seal)(Buffer.alloc(1234), newKey()).length).toBe(1234 + archive_stream_service_1.SEAL_OVERHEAD_BYTES);
|
|
244
|
+
});
|
|
245
|
+
});
|
|
246
|
+
describe('decodeArchiveFrame', () => {
|
|
247
|
+
it('refuses a tampered part instead of returning rows from it', async () => {
|
|
248
|
+
const key = newKey();
|
|
249
|
+
const session = recordingSession();
|
|
250
|
+
await (0, archive_stream_service_1.writeArchiveStream)(inBatches(makeRows(100), 100), {
|
|
251
|
+
key,
|
|
252
|
+
session,
|
|
253
|
+
timeColumn: TIME_COLUMN,
|
|
254
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
255
|
+
partMaxBytes: 16 * 1024,
|
|
256
|
+
});
|
|
257
|
+
const tampered = Buffer.from(session.payloads.get(1));
|
|
258
|
+
tampered[tampered.length - 1] ^= 0xff;
|
|
259
|
+
await expect(decodeAll(tampered, key)).rejects.toThrow();
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
describe('splitArchiveFrames', () => {
|
|
263
|
+
const writeObject = async () => {
|
|
264
|
+
const key = newKey();
|
|
265
|
+
const session = recordingSession();
|
|
266
|
+
const result = await (0, archive_stream_service_1.writeArchiveStream)(inBatches(makeRows(5_000), 1000), {
|
|
267
|
+
key,
|
|
268
|
+
session,
|
|
269
|
+
timeColumn: TIME_COLUMN,
|
|
270
|
+
compressionLevel: COMPRESSION_LEVEL,
|
|
271
|
+
partMaxBytes: 4 * 1024,
|
|
272
|
+
});
|
|
273
|
+
return { key, parts: result.parts, stored: payloadsInOrder(session, result.parts) };
|
|
274
|
+
};
|
|
275
|
+
const streamed = (bytes, chunkBytes = 333) => {
|
|
276
|
+
const chunks = [];
|
|
277
|
+
for (let offset = 0; offset < bytes.length; offset += chunkBytes) {
|
|
278
|
+
chunks.push(bytes.subarray(offset, offset + chunkBytes));
|
|
279
|
+
}
|
|
280
|
+
return stream_1.Readable.from(chunks);
|
|
281
|
+
};
|
|
282
|
+
const drain = async (source, parts) => {
|
|
283
|
+
const frames = [];
|
|
284
|
+
for await (const frame of (0, archive_stream_service_1.splitArchiveFrames)(source, parts)) {
|
|
285
|
+
frames.push(frame.sealed);
|
|
286
|
+
}
|
|
287
|
+
return frames;
|
|
288
|
+
};
|
|
289
|
+
it('cuts an object streamed in arbitrary chunks back into its parts', async () => {
|
|
290
|
+
const { key, parts, stored } = await writeObject();
|
|
291
|
+
expect(parts.length).toBeGreaterThanOrEqual(3);
|
|
292
|
+
const frames = await drain(streamed(Buffer.concat(stored)), parts);
|
|
293
|
+
expect(frames).toEqual(stored);
|
|
294
|
+
const decoded = (await Promise.all(frames.map((frame) => decodeAll(frame, key)))).flat();
|
|
295
|
+
expect(decoded).toHaveLength(5_000);
|
|
296
|
+
});
|
|
297
|
+
it('refuses an object shorter than its index', async () => {
|
|
298
|
+
const { parts, stored } = await writeObject();
|
|
299
|
+
const truncated = Buffer.concat(stored).subarray(0, -10);
|
|
300
|
+
await expect(drain(streamed(truncated), parts)).rejects.toThrow(/ends inside part/);
|
|
301
|
+
});
|
|
302
|
+
it('refuses an object longer than its index', async () => {
|
|
303
|
+
const { parts, stored } = await writeObject();
|
|
304
|
+
const extended = Buffer.concat([...stored, Buffer.from('trailing bytes')]);
|
|
305
|
+
await expect(drain(streamed(extended), parts)).rejects.toThrow(/longer than its/);
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
});
|
|
309
|
+
//# sourceMappingURL=archive-stream.service.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"archive-stream.service.spec.js","sourceRoot":"","sources":["../../../../src/server/archive/tests/archive-stream.service.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Transform } from 'stream';
|
|
2
|
+
export interface ZstdOptions {
|
|
3
|
+
params: Record<number, number>;
|
|
4
|
+
}
|
|
5
|
+
export interface ZstdCompressStream extends Transform {
|
|
6
|
+
flush(callback: (error?: Error | null) => void): void;
|
|
7
|
+
}
|
|
8
|
+
interface ZstdBindings {
|
|
9
|
+
createZstdCompress(options: ZstdOptions): ZstdCompressStream;
|
|
10
|
+
createZstdDecompress(): Transform;
|
|
11
|
+
zstdCompressSync(buffer: Buffer, options: ZstdOptions): Buffer;
|
|
12
|
+
zstdDecompressSync(buffer: Buffer): Buffer;
|
|
13
|
+
constants: {
|
|
14
|
+
ZSTD_c_compressionLevel: number;
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
export declare const zstd: ZstdBindings;
|
|
18
|
+
export declare const zstdCompressionOptions: (compressionLevel: number) => ZstdOptions;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.zstdCompressionOptions = exports.zstd = void 0;
|
|
37
|
+
const zlib = __importStar(require("zlib"));
|
|
38
|
+
exports.zstd = zlib;
|
|
39
|
+
const zstdCompressionOptions = (compressionLevel) => ({
|
|
40
|
+
params: { [exports.zstd.constants.ZSTD_c_compressionLevel]: compressionLevel },
|
|
41
|
+
});
|
|
42
|
+
exports.zstdCompressionOptions = zstdCompressionOptions;
|
|
43
|
+
//# sourceMappingURL=zstd.util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"zstd.util.js","sourceRoot":"","sources":["../../../src/server/archive/zstd.util.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AACA,2CAA6B;AAiChB,QAAA,IAAI,GAAG,IAA+B,CAAC;AAG7C,MAAM,sBAAsB,GAAG,CAAC,gBAAwB,EAAe,EAAE,CAAC,CAAC;IAChF,MAAM,EAAE,EAAE,CAAC,YAAI,CAAC,SAAS,CAAC,uBAAuB,CAAC,EAAE,gBAAgB,EAAE;CACvE,CAAC,CAAC;AAFU,QAAA,sBAAsB,0BAEhC"}
|
package/dist/server/index.d.ts
CHANGED
package/dist/server/index.js
CHANGED
|
@@ -22,4 +22,5 @@ __exportStar(require("./explore/field-catalog.types"), exports);
|
|
|
22
22
|
__exportStar(require("./explore/sql-translator"), exports);
|
|
23
23
|
__exportStar(require("./explore/like-escape"), exports);
|
|
24
24
|
__exportStar(require("./abyss-signature.util"), exports);
|
|
25
|
+
__exportStar(require("./archive"), exports);
|
|
25
26
|
//# sourceMappingURL=index.js.map
|
package/dist/server/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAgBA,kDAAgC;AAGhC,2DAAyC;AAKzC,wDAAsC;AAGtC,yCAAuB;AAIvB,gEAA8C;AAC9C,2DAAyC;AACzC,wDAAsC;AAGtC,yDAAuC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAgBA,kDAAgC;AAGhC,2DAAyC;AAKzC,wDAAsC;AAGtC,yCAAuB;AAIvB,gEAA8C;AAC9C,2DAAyC;AACzC,wDAAsC;AAGtC,yDAAuC;AAKvC,4CAA0B"}
|