@stacks/api-toolkit 1.12.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/LICENSE +202 -0
- package/README.md +74 -0
- package/bin/api-toolkit-git-info.js +25 -0
- package/dist/fastify/cache.d.ts +31 -0
- package/dist/fastify/cache.js +63 -0
- package/dist/fastify/cache.js.map +1 -0
- package/dist/fastify/fastify.d.ts +16 -0
- package/dist/fastify/fastify.js +46 -0
- package/dist/fastify/fastify.js.map +1 -0
- package/dist/fastify/index.d.ts +4 -0
- package/dist/fastify/index.js +21 -0
- package/dist/fastify/index.js.map +1 -0
- package/dist/fastify/openapi.d.ts +13 -0
- package/dist/fastify/openapi.js +23 -0
- package/dist/fastify/openapi.js.map +1 -0
- package/dist/fastify/schemas.d.ts +9 -0
- package/dist/fastify/schemas.js +16 -0
- package/dist/fastify/schemas.js.map +1 -0
- package/dist/helpers/events.d.ts +52 -0
- package/dist/helpers/events.js +93 -0
- package/dist/helpers/events.js.map +1 -0
- package/dist/helpers/index.d.ts +7 -0
- package/dist/helpers/index.js +25 -0
- package/dist/helpers/index.js.map +1 -0
- package/dist/helpers/is-debugging.d.ts +1 -0
- package/dist/helpers/is-debugging.js +15 -0
- package/dist/helpers/is-debugging.js.map +1 -0
- package/dist/helpers/iterators.d.ts +27 -0
- package/dist/helpers/iterators.js +74 -0
- package/dist/helpers/iterators.js.map +1 -0
- package/dist/helpers/serialize-error.d.ts +20 -0
- package/dist/helpers/serialize-error.js +135 -0
- package/dist/helpers/serialize-error.js.map +1 -0
- package/dist/helpers/time.d.ts +54 -0
- package/dist/helpers/time.js +121 -0
- package/dist/helpers/time.js.map +1 -0
- package/dist/helpers/values.d.ts +68 -0
- package/dist/helpers/values.js +165 -0
- package/dist/helpers/values.js.map +1 -0
- package/dist/helpers/worker-thread-init.d.ts +1 -0
- package/dist/helpers/worker-thread-init.js +67 -0
- package/dist/helpers/worker-thread-init.js.map +1 -0
- package/dist/helpers/worker-thread-manager.d.ts +53 -0
- package/dist/helpers/worker-thread-manager.js +148 -0
- package/dist/helpers/worker-thread-manager.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -0
- package/dist/logger/index.d.ts +20 -0
- package/dist/logger/index.js +14 -0
- package/dist/logger/index.js.map +1 -0
- package/dist/postgres/base-pg-store.d.ts +68 -0
- package/dist/postgres/base-pg-store.js +109 -0
- package/dist/postgres/base-pg-store.js.map +1 -0
- package/dist/postgres/connection.d.ts +62 -0
- package/dist/postgres/connection.js +126 -0
- package/dist/postgres/connection.js.map +1 -0
- package/dist/postgres/errors.d.ts +5 -0
- package/dist/postgres/errors.js +71 -0
- package/dist/postgres/errors.js.map +1 -0
- package/dist/postgres/index.d.ts +5 -0
- package/dist/postgres/index.js +22 -0
- package/dist/postgres/index.js.map +1 -0
- package/dist/postgres/migrations.d.ts +47 -0
- package/dist/postgres/migrations.js +134 -0
- package/dist/postgres/migrations.js.map +1 -0
- package/dist/postgres/types.d.ts +14 -0
- package/dist/postgres/types.js +48 -0
- package/dist/postgres/types.js.map +1 -0
- package/dist/profiler/index.d.ts +2 -0
- package/dist/profiler/index.js +19 -0
- package/dist/profiler/index.js.map +1 -0
- package/dist/profiler/inspector-util.d.ts +29 -0
- package/dist/profiler/inspector-util.js +268 -0
- package/dist/profiler/inspector-util.js.map +1 -0
- package/dist/profiler/server.d.ts +6 -0
- package/dist/profiler/server.js +186 -0
- package/dist/profiler/server.js.map +1 -0
- package/dist/server-version/index.d.ts +8 -0
- package/dist/server-version/index.js +33 -0
- package/dist/server-version/index.js.map +1 -0
- package/dist/shutdown-handler/index.d.ts +17 -0
- package/dist/shutdown-handler/index.js +82 -0
- package/dist/shutdown-handler/index.js.map +1 -0
- package/package.json +73 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.runMigrations = runMigrations;
|
|
4
|
+
exports.cycleMigrations = cycleMigrations;
|
|
5
|
+
exports.databaseHasData = databaseHasData;
|
|
6
|
+
exports.dangerousDropAllTables = dangerousDropAllTables;
|
|
7
|
+
const node_pg_migrate_1 = require("node-pg-migrate");
|
|
8
|
+
const logger_1 = require("../logger");
|
|
9
|
+
const connection_1 = require("./connection");
|
|
10
|
+
const values_1 = require("../helpers/values");
|
|
11
|
+
/**
|
|
12
|
+
* Run migrations in one direction.
|
|
13
|
+
* @param dir - Migrations directory
|
|
14
|
+
* @param direction - Migration direction (`'down'` or `'up'`)
|
|
15
|
+
* @param connectionArgs - Postgres connection args
|
|
16
|
+
* @param opts - Migration options
|
|
17
|
+
*/
|
|
18
|
+
async function runMigrations(dir, direction, connectionArgs, opts) {
|
|
19
|
+
if (!opts?.dangerousAllowDataLoss && direction !== 'up' && !values_1.isTestEnv && !values_1.isDevEnv) {
|
|
20
|
+
throw new Error('Whoa there! This is a testing function that will drop all data from PG. ' +
|
|
21
|
+
'Set NODE_ENV to "test" or "development" to enable migration testing.');
|
|
22
|
+
}
|
|
23
|
+
const args = (0, connection_1.standardizedConnectionArgs)(connectionArgs, 'migrations');
|
|
24
|
+
await (0, node_pg_migrate_1.default)({
|
|
25
|
+
dir,
|
|
26
|
+
direction,
|
|
27
|
+
count: Infinity,
|
|
28
|
+
ignorePattern: '.*(\\.map|\\.d\\.ts)',
|
|
29
|
+
databaseUrl: typeof args === 'string'
|
|
30
|
+
? args
|
|
31
|
+
: {
|
|
32
|
+
host: args.host,
|
|
33
|
+
port: args.port,
|
|
34
|
+
user: args.user,
|
|
35
|
+
password: args.password,
|
|
36
|
+
database: args.database,
|
|
37
|
+
},
|
|
38
|
+
migrationsTable: opts?.migrationsTable ?? 'pgmigrations',
|
|
39
|
+
schema: typeof args === 'string' ? 'public' : args.schema,
|
|
40
|
+
logger: opts?.logger ?? {
|
|
41
|
+
info: msg => (opts?.logMigrations === true ? logger_1.logger.info(msg) : {}),
|
|
42
|
+
warn: msg => logger_1.logger.warn(msg),
|
|
43
|
+
error: msg => logger_1.logger.error(msg),
|
|
44
|
+
},
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Cycle migrations down and up.
|
|
49
|
+
* @param dir - Migrations directory
|
|
50
|
+
* @param connectionArgs - Postgres connection args
|
|
51
|
+
* @param opts - Migration options
|
|
52
|
+
*/
|
|
53
|
+
async function cycleMigrations(dir, connectionArgs, opts) {
|
|
54
|
+
await runMigrations(dir, 'down', connectionArgs, opts);
|
|
55
|
+
if (opts?.checkForEmptyData &&
|
|
56
|
+
(await databaseHasData(connectionArgs, {
|
|
57
|
+
ignoreMigrationTables: true,
|
|
58
|
+
migrationsTable: opts.migrationsTable,
|
|
59
|
+
}))) {
|
|
60
|
+
throw new Error('Migration down process did not completely remove DB tables');
|
|
61
|
+
}
|
|
62
|
+
await runMigrations(dir, 'up', connectionArgs, opts);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Check the `pg_class` table for any data structures contained in the database. We will consider
|
|
66
|
+
* any and all results here as "data" contained in the DB, since anything that is not a completely
|
|
67
|
+
* empty DB could lead to strange errors when running the API. See:
|
|
68
|
+
* https://www.postgresql.org/docs/current/catalog-pg-class.html
|
|
69
|
+
* @returns `boolean` if the DB has data
|
|
70
|
+
*/
|
|
71
|
+
async function databaseHasData(connectionArgs, opts) {
|
|
72
|
+
const sql = await (0, connection_1.connectPostgres)({
|
|
73
|
+
usageName: 'contains-data-check',
|
|
74
|
+
connectionArgs: (0, connection_1.standardizedConnectionArgs)(connectionArgs, 'contains-data-check'),
|
|
75
|
+
});
|
|
76
|
+
try {
|
|
77
|
+
const ignoreMigrationTables = opts?.ignoreMigrationTables ?? false;
|
|
78
|
+
const tableName = opts?.migrationsTable ?? 'pgmigrations';
|
|
79
|
+
const result = await sql `
|
|
80
|
+
SELECT COUNT(*)
|
|
81
|
+
FROM pg_class c
|
|
82
|
+
JOIN pg_namespace s ON s.oid = c.relnamespace
|
|
83
|
+
WHERE s.nspname = ${sql.options.connection.search_path}
|
|
84
|
+
${ignoreMigrationTables ? sql `AND c.relname NOT LIKE ${tableName}::text || '%'` : sql ``}
|
|
85
|
+
`;
|
|
86
|
+
return result.count > 0 && result[0].count > 0;
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
if (error.message?.includes('does not exist')) {
|
|
90
|
+
return false;
|
|
91
|
+
}
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
finally {
|
|
95
|
+
await sql.end();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Drops all tables from the Postgres DB. DANGEROUS!!!
|
|
100
|
+
*/
|
|
101
|
+
async function dangerousDropAllTables(connectionArgs, opts) {
|
|
102
|
+
if (opts?.acknowledgePotentialCatastrophicConsequences !== 'yes') {
|
|
103
|
+
throw new Error('Dangerous usage error.');
|
|
104
|
+
}
|
|
105
|
+
const sql = await (0, connection_1.connectPostgres)({
|
|
106
|
+
usageName: 'dangerous-drop-all-tables',
|
|
107
|
+
connectionArgs: (0, connection_1.standardizedConnectionArgs)(connectionArgs, 'dangerous-drop-all-tables'),
|
|
108
|
+
});
|
|
109
|
+
const schema = sql.options.connection.search_path;
|
|
110
|
+
try {
|
|
111
|
+
await sql.begin(async (sql) => {
|
|
112
|
+
const relNamesQuery = async (kind) => sql `
|
|
113
|
+
SELECT relname
|
|
114
|
+
FROM pg_class c
|
|
115
|
+
JOIN pg_namespace s ON s.oid = c.relnamespace
|
|
116
|
+
WHERE s.nspname = ${schema} AND c.relkind = ${kind}
|
|
117
|
+
`;
|
|
118
|
+
// Remove materialized views first and tables second.
|
|
119
|
+
// Using CASCADE in these DROP statements also removes associated indexes and constraints.
|
|
120
|
+
const views = await relNamesQuery('m');
|
|
121
|
+
for (const view of views) {
|
|
122
|
+
await sql `DROP MATERIALIZED VIEW IF EXISTS ${sql(view.relname)} CASCADE`;
|
|
123
|
+
}
|
|
124
|
+
const tables = await relNamesQuery('r');
|
|
125
|
+
for (const table of tables) {
|
|
126
|
+
await sql `DROP TABLE IF EXISTS ${sql(table.relname)} CASCADE`;
|
|
127
|
+
}
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
finally {
|
|
131
|
+
await sql.end();
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=migrations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"migrations.js","sourceRoot":"","sources":["../../src/postgres/migrations.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const PG_TYPE_MAPPINGS: {
|
|
2
|
+
bytea: {
|
|
3
|
+
to: number;
|
|
4
|
+
from: number[];
|
|
5
|
+
serialize: (x: any) => string;
|
|
6
|
+
parse: (x: any) => string;
|
|
7
|
+
};
|
|
8
|
+
};
|
|
9
|
+
/** Values will be automatically converted into a `bytea` compatible string before sending to pg. */
|
|
10
|
+
export type PgBytea = string | Buffer;
|
|
11
|
+
/** The `string` type guarantees the value will fit into the `numeric` pg type. */
|
|
12
|
+
export type PgNumeric = string;
|
|
13
|
+
/** JSON objects will be automatically stringified before insertion. */
|
|
14
|
+
export type PgJsonb = any;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PG_TYPE_MAPPINGS = void 0;
|
|
4
|
+
exports.PG_TYPE_MAPPINGS = {
|
|
5
|
+
// Make both `string` and `Buffer` be compatible with a `bytea` columns.
|
|
6
|
+
// * Buffers and strings with `0x` prefixes will be transformed to hex format (`\x`).
|
|
7
|
+
// * Other strings will be passed as-is.
|
|
8
|
+
// From postgres, all values will be returned as strings with `0x` prefix.
|
|
9
|
+
bytea: {
|
|
10
|
+
to: 17,
|
|
11
|
+
from: [17],
|
|
12
|
+
serialize: (x) => {
|
|
13
|
+
if (typeof x === 'string') {
|
|
14
|
+
if (/^(0x|0X)[a-fA-F0-9]*$/.test(x)) {
|
|
15
|
+
// hex string with "0x" prefix
|
|
16
|
+
if (x.length % 2 !== 0) {
|
|
17
|
+
throw new Error(`Hex string is an odd number of digits`);
|
|
18
|
+
}
|
|
19
|
+
return '\\x' + x.slice(2);
|
|
20
|
+
}
|
|
21
|
+
else if (x.length === 0) {
|
|
22
|
+
return '\\x';
|
|
23
|
+
}
|
|
24
|
+
else if (/^\\x[a-fA-F0-9]*$/.test(x)) {
|
|
25
|
+
// hex string with "\x" prefix (already encoded for postgres)
|
|
26
|
+
if (x.length % 2 !== 0) {
|
|
27
|
+
throw new Error(`Hex string is an odd number of digits`);
|
|
28
|
+
}
|
|
29
|
+
return x;
|
|
30
|
+
}
|
|
31
|
+
else {
|
|
32
|
+
throw new Error(`String value for bytea column does not have 0x prefix`);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
else if (Buffer.isBuffer(x)) {
|
|
36
|
+
return '\\x' + x.toString('hex');
|
|
37
|
+
}
|
|
38
|
+
else if (ArrayBuffer.isView(x)) {
|
|
39
|
+
return '\\x' + Buffer.from(x.buffer, x.byteOffset, x.byteLength).toString('hex');
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
throw new Error(`Cannot serialize unexpected type "${x.constructor.name}" to bytea hex string`);
|
|
43
|
+
}
|
|
44
|
+
},
|
|
45
|
+
parse: (x) => `0x${x.slice(2)}`,
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/postgres/types.ts"],"names":[],"mappings":";;;AAAa,QAAA,gBAAgB,GAAG;IAC9B,wEAAwE;IACxE,qFAAqF;IACrF,wCAAwC;IACxC,0EAA0E;IAC1E,KAAK,EAAE;QACL,EAAE,EAAE,EAAE;QACN,IAAI,EAAE,CAAC,EAAE,CAAC;QACV,SAAS,EAAE,CAAC,CAAM,EAAE,EAAE;YACpB,IAAI,OAAO,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAC1B,IAAI,uBAAuB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACpC,8BAA8B;oBAC9B,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;wBACvB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;oBAC3D,CAAC;oBACD,OAAO,KAAK,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAC5B,CAAC;qBAAM,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;oBAC1B,OAAO,KAAK,CAAC;gBACf,CAAC;qBAAM,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;oBACvC,6DAA6D;oBAC7D,IAAI,CAAC,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;wBACvB,MAAM,IAAI,KAAK,CAAC,uCAAuC,CAAC,CAAC;oBAC3D,CAAC;oBACD,OAAO,CAAC,CAAC;gBACX,CAAC;qBAAM,CAAC;oBACN,MAAM,IAAI,KAAK,CAAC,uDAAuD,CAAC,CAAC;gBAC3E,CAAC;YACH,CAAC;iBAAM,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;gBAC9B,OAAO,KAAK,GAAG,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnC,CAAC;iBAAM,IAAI,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC;gBACjC,OAAO,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YACnF,CAAC;iBAAM,CAAC;gBACN,MAAM,IAAI,KAAK,CACb,qCAAqC,CAAC,CAAC,WAAW,CAAC,IAAI,uBAAuB,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC;QACD,KAAK,EAAE,CAAC,CAAM,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE;KACrC;CACF,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
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("./inspector-util"), exports);
|
|
18
|
+
__exportStar(require("./server"), exports);
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/profiler/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,mDAAiC;AACjC,2CAAyB"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import * as inspector from 'inspector';
|
|
2
|
+
import * as stream from 'stream';
|
|
3
|
+
import { Stopwatch } from '../helpers';
|
|
4
|
+
export type CpuProfileResult = inspector.Profiler.Profile;
|
|
5
|
+
export interface ProfilerInstance<TStopResult = void> {
|
|
6
|
+
start: () => Promise<void>;
|
|
7
|
+
stop: () => Promise<TStopResult>;
|
|
8
|
+
dispose: () => Promise<void>;
|
|
9
|
+
session: inspector.Session;
|
|
10
|
+
sessionType: 'cpu' | 'memory';
|
|
11
|
+
stopwatch: Stopwatch;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Connects and enables a new `inspector` session, then starts an internal v8 CPU profiling process.
|
|
15
|
+
* @returns A function to stop the profiling, and return the CPU profile result object.
|
|
16
|
+
* The result object can be used to create a `.cpuprofile` file using JSON.stringify.
|
|
17
|
+
* Use VSCode or Chrome's 'DevTools for Node' (under chrome://inspect) to visualize the `.cpuprofile` file.
|
|
18
|
+
* @param samplingInterval - Optionally set sampling interval in microseconds, default is 1000 microseconds.
|
|
19
|
+
*/
|
|
20
|
+
export declare function initCpuProfiling(samplingInterval?: number): ProfilerInstance<CpuProfileResult>;
|
|
21
|
+
/**
|
|
22
|
+
* Connects and enables a new `inspector` session, then creates an internal v8 Heap profiler snapshot.
|
|
23
|
+
* @param outputStream - An output stream that heap snapshot chunks are written to.
|
|
24
|
+
* The result stream can be used to create a `.heapsnapshot` file.
|
|
25
|
+
* Use Chrome's 'DevTools for Node' (under chrome://inspect) to visualize the `.heapsnapshot` file.
|
|
26
|
+
*/
|
|
27
|
+
export declare function initHeapSnapshot(outputStream: stream.Writable): ProfilerInstance<{
|
|
28
|
+
totalSnapshotByteSize: number;
|
|
29
|
+
}>;
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.initCpuProfiling = initCpuProfiling;
|
|
4
|
+
exports.initHeapSnapshot = initHeapSnapshot;
|
|
5
|
+
const inspector = require("inspector");
|
|
6
|
+
const helpers_1 = require("../helpers");
|
|
7
|
+
const logger_1 = require("../logger");
|
|
8
|
+
function isInspectorNotConnectedError(error) {
|
|
9
|
+
const ERR_INSPECTOR_NOT_CONNECTED = 'ERR_INSPECTOR_NOT_CONNECTED';
|
|
10
|
+
const isNodeError = (r) => r instanceof Error && 'code' in r;
|
|
11
|
+
return isNodeError(error) && error.code === ERR_INSPECTOR_NOT_CONNECTED;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Connects and enables a new `inspector` session, then starts an internal v8 CPU profiling process.
|
|
15
|
+
* @returns A function to stop the profiling, and return the CPU profile result object.
|
|
16
|
+
* The result object can be used to create a `.cpuprofile` file using JSON.stringify.
|
|
17
|
+
* Use VSCode or Chrome's 'DevTools for Node' (under chrome://inspect) to visualize the `.cpuprofile` file.
|
|
18
|
+
* @param samplingInterval - Optionally set sampling interval in microseconds, default is 1000 microseconds.
|
|
19
|
+
*/
|
|
20
|
+
function initCpuProfiling(samplingInterval) {
|
|
21
|
+
const sessionStopwatch = (0, helpers_1.stopwatch)();
|
|
22
|
+
const session = new inspector.Session();
|
|
23
|
+
session.connect();
|
|
24
|
+
logger_1.logger.info(`[CpuProfiler] Connect session took ${sessionStopwatch.getElapsedAndRestart()}ms`);
|
|
25
|
+
const start = async () => {
|
|
26
|
+
const sw = (0, helpers_1.stopwatch)();
|
|
27
|
+
logger_1.logger.info(`[CpuProfiler] Enabling profiling...`);
|
|
28
|
+
await new Promise((resolve, reject) => {
|
|
29
|
+
try {
|
|
30
|
+
session.post('Profiler.enable', error => {
|
|
31
|
+
if (error) {
|
|
32
|
+
logger_1.logger.error(error, '[CpuProfiler] Error enabling profiling');
|
|
33
|
+
reject(error);
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
logger_1.logger.info(`[CpuProfiler] Profiling enabled`);
|
|
37
|
+
resolve();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
logger_1.logger.error(error, '[CpuProfiler] Error enabling profiling');
|
|
43
|
+
reject(error);
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
logger_1.logger.info(`[CpuProfiler] Enable session took ${sw.getElapsedAndRestart()}ms`);
|
|
47
|
+
if (samplingInterval !== undefined) {
|
|
48
|
+
logger_1.logger.info(`[CpuProfiler] Setting sampling interval to ${samplingInterval} microseconds`);
|
|
49
|
+
await new Promise((resolve, reject) => {
|
|
50
|
+
try {
|
|
51
|
+
session.post('Profiler.setSamplingInterval', { interval: samplingInterval }, error => {
|
|
52
|
+
if (error) {
|
|
53
|
+
logger_1.logger.error(error, '[CpuProfiler] Error setting sampling interval');
|
|
54
|
+
reject(error);
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
logger_1.logger.info(`[CpuProfiler] Set sampling interval`);
|
|
58
|
+
resolve();
|
|
59
|
+
}
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
logger_1.logger.error(error, '[CpuProfiler] Error setting sampling interval');
|
|
64
|
+
reject(error);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
logger_1.logger.info(`[CpuProfiler] Set sampling interval took ${sw.getElapsedAndRestart()}ms`);
|
|
68
|
+
}
|
|
69
|
+
logger_1.logger.info(`[CpuProfiler] Profiling starting...`);
|
|
70
|
+
await new Promise((resolve, reject) => {
|
|
71
|
+
try {
|
|
72
|
+
session.post('Profiler.start', error => {
|
|
73
|
+
if (error) {
|
|
74
|
+
logger_1.logger.error(error, '[CpuProfiler] Error starting profiling');
|
|
75
|
+
reject(error);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
sessionStopwatch.restart();
|
|
79
|
+
logger_1.logger.info(`[CpuProfiler] Profiling started`);
|
|
80
|
+
resolve();
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
logger_1.logger.error(error, '[CpuProfiler] Error starting profiling');
|
|
86
|
+
reject(error);
|
|
87
|
+
}
|
|
88
|
+
});
|
|
89
|
+
logger_1.logger.info(`[CpuProfiler] Start profiler took ${sw.getElapsedAndRestart()}ms`);
|
|
90
|
+
};
|
|
91
|
+
const stop = async () => {
|
|
92
|
+
const sw = (0, helpers_1.stopwatch)();
|
|
93
|
+
logger_1.logger.info(`[CpuProfiler] Profiling stopping...`);
|
|
94
|
+
try {
|
|
95
|
+
return await new Promise((resolve, reject) => {
|
|
96
|
+
try {
|
|
97
|
+
session.post('Profiler.stop', (error, profileResult) => {
|
|
98
|
+
if (error) {
|
|
99
|
+
logger_1.logger.error(error, '[CpuProfiler] Error stopping profiling');
|
|
100
|
+
reject(error);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
logger_1.logger.info(`[CpuProfiler] Profiling stopped`);
|
|
104
|
+
resolve(profileResult.profile);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
reject(error);
|
|
110
|
+
}
|
|
111
|
+
});
|
|
112
|
+
}
|
|
113
|
+
finally {
|
|
114
|
+
logger_1.logger.info(`[CpuProfiler] Stop profiler took ${sw.getElapsedAndRestart()}ms`);
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
const dispose = async () => {
|
|
118
|
+
const sw = (0, helpers_1.stopwatch)();
|
|
119
|
+
try {
|
|
120
|
+
logger_1.logger.info(`[CpuProfiler] Disabling profiling...`);
|
|
121
|
+
await new Promise((resolve, reject) => {
|
|
122
|
+
try {
|
|
123
|
+
session.post('Profiler.disable', error => {
|
|
124
|
+
if (error && isInspectorNotConnectedError(error)) {
|
|
125
|
+
logger_1.logger.info(`[CpuProfiler] Profiler already disconnected`);
|
|
126
|
+
resolve();
|
|
127
|
+
}
|
|
128
|
+
else if (error) {
|
|
129
|
+
logger_1.logger.error(error, '[CpuProfiler] Error disabling profiling');
|
|
130
|
+
reject(error);
|
|
131
|
+
}
|
|
132
|
+
else {
|
|
133
|
+
logger_1.logger.info(`[CpuProfiler] Profiling disabled`);
|
|
134
|
+
resolve();
|
|
135
|
+
}
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
if (isInspectorNotConnectedError(error)) {
|
|
140
|
+
logger_1.logger.info(`[CpuProfiler] Profiler already disconnected`);
|
|
141
|
+
resolve();
|
|
142
|
+
}
|
|
143
|
+
else {
|
|
144
|
+
reject();
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
finally {
|
|
150
|
+
session.disconnect();
|
|
151
|
+
logger_1.logger.info(`[CpuProfiler] Disable and disconnect profiler took ${sw.getElapsedAndRestart()}ms`);
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
return { start, stop, dispose, session, sessionType: 'cpu', stopwatch: sessionStopwatch };
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* Connects and enables a new `inspector` session, then creates an internal v8 Heap profiler snapshot.
|
|
158
|
+
* @param outputStream - An output stream that heap snapshot chunks are written to.
|
|
159
|
+
* The result stream can be used to create a `.heapsnapshot` file.
|
|
160
|
+
* Use Chrome's 'DevTools for Node' (under chrome://inspect) to visualize the `.heapsnapshot` file.
|
|
161
|
+
*/
|
|
162
|
+
function initHeapSnapshot(outputStream) {
|
|
163
|
+
const sw = (0, helpers_1.stopwatch)();
|
|
164
|
+
const session = new inspector.Session();
|
|
165
|
+
session.connect();
|
|
166
|
+
let totalSnapshotByteSize = 0;
|
|
167
|
+
const start = async () => {
|
|
168
|
+
logger_1.logger.info(`[HeapProfiler] Enabling profiling...`);
|
|
169
|
+
await new Promise((resolve, reject) => {
|
|
170
|
+
try {
|
|
171
|
+
session.post('HeapProfiler.enable', error => {
|
|
172
|
+
if (error) {
|
|
173
|
+
logger_1.logger.error(error, '[HeapProfiler] Error enabling profiling');
|
|
174
|
+
reject(error);
|
|
175
|
+
}
|
|
176
|
+
else {
|
|
177
|
+
sw.restart();
|
|
178
|
+
logger_1.logger.info(`[HeapProfiler] Profiling enabled`);
|
|
179
|
+
resolve();
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
catch (error) {
|
|
184
|
+
logger_1.logger.error(error, '[HeapProfiler] Error enabling profiling');
|
|
185
|
+
reject(error);
|
|
186
|
+
}
|
|
187
|
+
});
|
|
188
|
+
session.on('HeapProfiler.addHeapSnapshotChunk', message => {
|
|
189
|
+
// Note: this doesn't handle stream back-pressure, but we don't have control over the
|
|
190
|
+
// `HeapProfiler.addHeapSnapshotChunk` callback in order to use something like piping.
|
|
191
|
+
// So in theory on a slow `outputStream` (usually an http connection response) this can cause OOM.
|
|
192
|
+
logger_1.logger.info(`[HeapProfiler] Writing heap snapshot chunk of size ${message.params.chunk.length}`);
|
|
193
|
+
totalSnapshotByteSize += message.params.chunk.length;
|
|
194
|
+
outputStream.write(message.params.chunk, error => {
|
|
195
|
+
if (error) {
|
|
196
|
+
logger_1.logger.error(error, `[HeapProfiler] Error writing heap profile chunk to output stream: ${error.message}`);
|
|
197
|
+
}
|
|
198
|
+
});
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
const stop = async () => {
|
|
202
|
+
logger_1.logger.info(`[HeapProfiler] Taking snapshot...`);
|
|
203
|
+
await new Promise((resolve, reject) => {
|
|
204
|
+
try {
|
|
205
|
+
session.post('HeapProfiler.takeHeapSnapshot', undefined, (error) => {
|
|
206
|
+
if (error) {
|
|
207
|
+
logger_1.logger.error(error, '[HeapProfiler] Error taking snapshot');
|
|
208
|
+
reject(error);
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
logger_1.logger.info(`[HeapProfiler] Taking snapshot completed, ${totalSnapshotByteSize} bytes...`);
|
|
212
|
+
resolve();
|
|
213
|
+
}
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
logger_1.logger.error(error, '[HeapProfiler] Error taking snapshot');
|
|
218
|
+
reject(error);
|
|
219
|
+
}
|
|
220
|
+
});
|
|
221
|
+
logger_1.logger.info(`[HeapProfiler] Draining snapshot buffer to stream...`);
|
|
222
|
+
const writeFinishedPromise = new Promise((resolve, reject) => {
|
|
223
|
+
outputStream.on('finish', () => resolve());
|
|
224
|
+
outputStream.on('error', error => reject(error));
|
|
225
|
+
});
|
|
226
|
+
outputStream.end();
|
|
227
|
+
await writeFinishedPromise;
|
|
228
|
+
logger_1.logger.info(`[HeapProfiler] Finished draining snapshot buffer to stream`);
|
|
229
|
+
return { totalSnapshotByteSize };
|
|
230
|
+
};
|
|
231
|
+
const dispose = async () => {
|
|
232
|
+
try {
|
|
233
|
+
logger_1.logger.info(`[HeapProfiler] Disabling profiling...`);
|
|
234
|
+
await new Promise((resolve, reject) => {
|
|
235
|
+
try {
|
|
236
|
+
session.post('HeapProfiler.disable', error => {
|
|
237
|
+
if (error && isInspectorNotConnectedError(error)) {
|
|
238
|
+
logger_1.logger.info(`[HeapProfiler] Profiler already disconnected`);
|
|
239
|
+
resolve();
|
|
240
|
+
}
|
|
241
|
+
else if (error) {
|
|
242
|
+
logger_1.logger.error(error, '[HeapProfiler] Error disabling profiling');
|
|
243
|
+
reject(error);
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
logger_1.logger.info(`[HeapProfiler] Profiling disabled`);
|
|
247
|
+
resolve();
|
|
248
|
+
}
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
catch (error) {
|
|
252
|
+
if (isInspectorNotConnectedError(error)) {
|
|
253
|
+
logger_1.logger.info(`[HeapProfiler] Profiler already disconnected`);
|
|
254
|
+
resolve();
|
|
255
|
+
}
|
|
256
|
+
else {
|
|
257
|
+
reject();
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
});
|
|
261
|
+
}
|
|
262
|
+
finally {
|
|
263
|
+
session.disconnect();
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
return { start, stop, dispose, session, sessionType: 'memory', stopwatch: sw };
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=inspector-util.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inspector-util.js","sourceRoot":"","sources":["../../src/profiler/inspector-util.ts"],"names":[],"mappings":"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"}
|