@xsynaptic/astro-build-logger 0.2.0 → 1.1.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/README.md +2 -2
- package/dist/index.d.mts +0 -1
- package/dist/index.mjs +20 -11
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @xsynaptic/astro-build-logger
|
|
2
2
|
|
|
3
|
-
An [Astro][] integration that records how long each build takes and appends a structured entry to a [JSONL][] file. Each entry captures the build duration, page count, total output size, and the Astro and Node versions used, making it easy to track build performance over time.
|
|
3
|
+
An [Astro][] integration that records how long each build takes and appends a structured entry to a [JSONL][] file. Each entry captures the build duration, page count, output file count, total output size, and the Astro and Node versions used, making it easy to track build performance over time.
|
|
4
4
|
|
|
5
5
|
_Note_: this package is ESM-only.
|
|
6
6
|
|
|
@@ -26,7 +26,7 @@ export default defineConfig({
|
|
|
26
26
|
After each build, an entry is appended to `astro-build.jsonl` in the project root:
|
|
27
27
|
|
|
28
28
|
```text
|
|
29
|
-
{"timestamp":"2026-06-07T12:00:00.000Z","durationSeconds":42.5,"pageCount":1280,"outputBytes":83214946,"astroVersion":"6.4.4","nodeVersion":"22.22.2","summary":"42s (1280 pages, 79.4 MB)"}
|
|
29
|
+
{"timestamp":"2026-06-07T12:00:00.000Z","durationSeconds":42.5,"pageCount":1280,"fileCount":4120,"outputBytes":83214946,"astroVersion":"6.4.4","nodeVersion":"22.22.2","summary":"42s (1280 pages, 4120 files, 79.4 MB)"}
|
|
30
30
|
```
|
|
31
31
|
|
|
32
32
|
One JSON object per line means the file is append-only and trivially parseable: read it line by line, or pipe it through tools like `jq`.
|
package/dist/index.d.mts
CHANGED
package/dist/index.mjs
CHANGED
|
@@ -17,11 +17,12 @@ function buildLogger(options) {
|
|
|
17
17
|
"astro:build:done": async ({ dir, logger, pages }) => {
|
|
18
18
|
const buildEndTime = Date.now();
|
|
19
19
|
const durationSeconds = Number(((buildEndTime - buildStartTime) / 1e3).toFixed(2));
|
|
20
|
-
const outputBytes = await
|
|
21
|
-
const summary = formatSummary(durationSeconds, pages.length, outputBytes);
|
|
20
|
+
const { fileCount, outputBytes } = await measureDirectory(dir);
|
|
21
|
+
const summary = formatSummary(durationSeconds, pages.length, fileCount, outputBytes);
|
|
22
22
|
const entry = {
|
|
23
23
|
astroVersion: astroPackage.version,
|
|
24
24
|
durationSeconds,
|
|
25
|
+
fileCount,
|
|
25
26
|
nodeVersion: process.versions.node,
|
|
26
27
|
outputBytes,
|
|
27
28
|
pageCount: pages.length,
|
|
@@ -56,7 +57,7 @@ function formatBytes(bytes) {
|
|
|
56
57
|
value /= 1024;
|
|
57
58
|
unitIndex += 1;
|
|
58
59
|
}
|
|
59
|
-
const precision =
|
|
60
|
+
const precision = unitIndex === 0 || value >= 10 ? 0 : 1;
|
|
60
61
|
return `${value.toFixed(precision)} ${units[unitIndex] ?? "B"}`;
|
|
61
62
|
}
|
|
62
63
|
function formatDuration(totalSeconds) {
|
|
@@ -67,21 +68,29 @@ function formatDuration(totalSeconds) {
|
|
|
67
68
|
if (minutes > 0) return `${String(minutes)}m ${String(seconds)}s`;
|
|
68
69
|
return `${String(seconds)}s`;
|
|
69
70
|
}
|
|
70
|
-
function formatSummary(durationSeconds, pageCount, outputBytes) {
|
|
71
|
-
return `${formatDuration(durationSeconds)} (${String(pageCount)} pages, ${formatBytes(outputBytes)})`;
|
|
71
|
+
function formatSummary(durationSeconds, pageCount, fileCount, outputBytes) {
|
|
72
|
+
return `${formatDuration(durationSeconds)} (${String(pageCount)} pages, ${String(fileCount)} files, ${formatBytes(outputBytes)})`;
|
|
72
73
|
}
|
|
73
|
-
async function
|
|
74
|
+
async function measureDirectory(dir) {
|
|
74
75
|
const entries = await readdir(dir, { withFileTypes: true });
|
|
75
|
-
let
|
|
76
|
+
let fileCount = 0;
|
|
77
|
+
let outputBytes = 0;
|
|
76
78
|
for (const entry of entries) {
|
|
77
79
|
const child = new URL(entry.isDirectory() ? `${entry.name}/` : entry.name, dir);
|
|
78
|
-
if (entry.isDirectory())
|
|
79
|
-
|
|
80
|
+
if (entry.isDirectory()) {
|
|
81
|
+
const nested = await measureDirectory(child);
|
|
82
|
+
fileCount += nested.fileCount;
|
|
83
|
+
outputBytes += nested.outputBytes;
|
|
84
|
+
} else if (entry.isFile()) {
|
|
80
85
|
const stats = await stat(child);
|
|
81
|
-
|
|
86
|
+
fileCount += 1;
|
|
87
|
+
outputBytes += stats.size;
|
|
82
88
|
}
|
|
83
89
|
}
|
|
84
|
-
return
|
|
90
|
+
return {
|
|
91
|
+
fileCount,
|
|
92
|
+
outputBytes
|
|
93
|
+
};
|
|
85
94
|
}
|
|
86
95
|
//#endregion
|
|
87
96
|
export { buildLogger as default };
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { AstroIntegration } from 'astro';\n\nimport astroPackage from 'astro/package.json' with { type: 'json' };\nimport { appendFile, readdir, stat } from 'node:fs/promises';\nimport { z } from 'zod';\n\nconst optionsSchema = z\n\t.object({\n\t\t/**\n\t\t * Path to the JSONL log file\n\t\t *\n\t\t * @default `\"astro-build.jsonl\"`\n\t\t */\n\t\tlogFileName: z.string().optional(),\n\t})\n\t.optional();\n\ninterface BuildLogEntry {\n\tastroVersion: string;\n\tdurationSeconds: number;\n\tnodeVersion: string;\n\tnotes?: string;\n\toutputBytes: number;\n\tpageCount: number;\n\tsummary: string;\n\ttimestamp: string;\n}\n\ntype Options = z.input<typeof optionsSchema>;\n\nexport default function buildLogger(options?: Options): AstroIntegration {\n\tconst parsed = optionsSchema.parse(options);\n\tconst logFileName = parsed?.logFileName ?? 'astro-build.jsonl';\n\n\tlet buildStartTime: number;\n\n\treturn {\n\t\thooks: {\n\t\t\t'astro:build:done': async ({ dir, logger, pages }) => {\n\t\t\t\tconst buildEndTime = Date.now();\n\t\t\t\tconst durationSeconds = Number(((buildEndTime - buildStartTime) / 1000).toFixed(2));\n\t\t\t\tconst outputBytes = await
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import type { AstroIntegration } from 'astro';\n\nimport astroPackage from 'astro/package.json' with { type: 'json' };\nimport { appendFile, readdir, stat } from 'node:fs/promises';\nimport { z } from 'zod';\n\nconst optionsSchema = z\n\t.object({\n\t\t/**\n\t\t * Path to the JSONL log file\n\t\t *\n\t\t * @default `\"astro-build.jsonl\"`\n\t\t */\n\t\tlogFileName: z.string().optional(),\n\t})\n\t.optional();\n\ninterface BuildLogEntry {\n\tastroVersion: string;\n\tdurationSeconds: number;\n\tfileCount: number;\n\tnodeVersion: string;\n\tnotes?: string;\n\toutputBytes: number;\n\tpageCount: number;\n\tsummary: string;\n\ttimestamp: string;\n}\n\ninterface DirectoryMeasure {\n\tfileCount: number;\n\toutputBytes: number;\n}\n\ntype Options = z.input<typeof optionsSchema>;\n\nexport default function buildLogger(options?: Options): AstroIntegration {\n\tconst parsed = optionsSchema.parse(options);\n\tconst logFileName = parsed?.logFileName ?? 'astro-build.jsonl';\n\n\tlet buildStartTime: number;\n\n\treturn {\n\t\thooks: {\n\t\t\t'astro:build:done': async ({ dir, logger, pages }) => {\n\t\t\t\tconst buildEndTime = Date.now();\n\t\t\t\tconst durationSeconds = Number(((buildEndTime - buildStartTime) / 1000).toFixed(2));\n\t\t\t\tconst { fileCount, outputBytes } = await measureDirectory(dir);\n\t\t\t\tconst summary = formatSummary(durationSeconds, pages.length, fileCount, outputBytes);\n\n\t\t\t\tconst entry: BuildLogEntry = {\n\t\t\t\t\tastroVersion: astroPackage.version,\n\t\t\t\t\tdurationSeconds,\n\t\t\t\t\tfileCount,\n\t\t\t\t\tnodeVersion: process.versions.node,\n\t\t\t\t\toutputBytes,\n\t\t\t\t\tpageCount: pages.length,\n\t\t\t\t\tsummary,\n\t\t\t\t\ttimestamp: new Date(buildEndTime).toISOString(),\n\t\t\t\t};\n\n\t\t\t\ttry {\n\t\t\t\t\tawait appendFile(logFileName, JSON.stringify(entry) + '\\n');\n\t\t\t\t\tlogger.info(`Build time logged: ${summary}`);\n\t\t\t\t} catch (error) {\n\t\t\t\t\tlogger.error(\n\t\t\t\t\t\t`Failed to write build log: ${error instanceof Error ? error.message : 'unknown error'}`,\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t},\n\t\t\t'astro:build:start': ({ logger }) => {\n\t\t\t\tbuildStartTime = Date.now();\n\t\t\t\tlogger.info(`Build timing started at ${new Date(buildStartTime).toISOString()}`);\n\t\t\t},\n\t\t},\n\t\tname: '@xsynaptic/astro-build-logger',\n\t};\n}\n\nfunction formatBytes(bytes: number): string {\n\tconst units = ['B', 'KB', 'MB', 'GB'];\n\tlet value = bytes;\n\tlet unitIndex = 0;\n\n\twhile (value >= 1024 && unitIndex < units.length - 1) {\n\t\tvalue /= 1024;\n\t\tunitIndex += 1;\n\t}\n\n\tconst precision = unitIndex === 0 || value >= 10 ? 0 : 1;\n\n\treturn `${value.toFixed(precision)} ${units[unitIndex] ?? 'B'}`;\n}\n\nfunction formatDuration(totalSeconds: number): string {\n\tconst hours = Math.floor(totalSeconds / 3600);\n\tconst minutes = Math.floor((totalSeconds % 3600) / 60);\n\tconst seconds = Math.round(totalSeconds % 60);\n\n\tif (hours > 0) return `${String(hours)}h ${String(minutes)}m ${String(seconds)}s`;\n\tif (minutes > 0) return `${String(minutes)}m ${String(seconds)}s`;\n\n\treturn `${String(seconds)}s`;\n}\n\nfunction formatSummary(\n\tdurationSeconds: number,\n\tpageCount: number,\n\tfileCount: number,\n\toutputBytes: number,\n): string {\n\treturn `${formatDuration(durationSeconds)} (${String(pageCount)} pages, ${String(fileCount)} files, ${formatBytes(outputBytes)})`;\n}\n\nasync function measureDirectory(dir: URL): Promise<DirectoryMeasure> {\n\tconst entries = await readdir(dir, { withFileTypes: true });\n\tlet fileCount = 0;\n\tlet outputBytes = 0;\n\n\tfor (const entry of entries) {\n\t\tconst child = new URL(entry.isDirectory() ? `${entry.name}/` : entry.name, dir);\n\n\t\tif (entry.isDirectory()) {\n\t\t\tconst nested = await measureDirectory(child);\n\t\t\tfileCount += nested.fileCount;\n\t\t\toutputBytes += nested.outputBytes;\n\t\t} else if (entry.isFile()) {\n\t\t\tconst stats = await stat(child);\n\t\t\tfileCount += 1;\n\t\t\toutputBytes += stats.size;\n\t\t}\n\t}\n\treturn { fileCount, outputBytes };\n}\n"],"mappings":";;;;AAMA,MAAM,gBAAgB,EACpB,OAAO;;;;;;AAMP,aAAa,EAAE,OAAO,CAAC,CAAC,SAAS,EAClC,CAAC,CAAC,CACD,SAAS;AAqBX,SAAwB,YAAY,SAAqC;CAExE,MAAM,cADS,cAAc,MAAM,OACV,CAAC,EAAE,eAAe;CAE3C,IAAI;CAEJ,OAAO;EACN,OAAO;GACN,oBAAoB,OAAO,EAAE,KAAK,QAAQ,YAAY;IACrD,MAAM,eAAe,KAAK,IAAI;IAC9B,MAAM,kBAAkB,SAAS,eAAe,kBAAkB,IAAA,CAAM,QAAQ,CAAC,CAAC;IAClF,MAAM,EAAE,WAAW,gBAAgB,MAAM,iBAAiB,GAAG;IAC7D,MAAM,UAAU,cAAc,iBAAiB,MAAM,QAAQ,WAAW,WAAW;IAEnF,MAAM,QAAuB;KAC5B,cAAc,aAAa;KAC3B;KACA;KACA,aAAa,QAAQ,SAAS;KAC9B;KACA,WAAW,MAAM;KACjB;KACA,WAAW,IAAI,KAAK,YAAY,CAAC,CAAC,YAAY;IAC/C;IAEA,IAAI;KACH,MAAM,WAAW,aAAa,KAAK,UAAU,KAAK,IAAI,IAAI;KAC1D,OAAO,KAAK,sBAAsB,SAAS;IAC5C,SAAS,OAAO;KACf,OAAO,MACN,8BAA8B,iBAAiB,QAAQ,MAAM,UAAU,iBACxE;IACD;GACD;GACA,sBAAsB,EAAE,aAAa;IACpC,iBAAiB,KAAK,IAAI;IAC1B,OAAO,KAAK,2BAA2B,IAAI,KAAK,cAAc,CAAC,CAAC,YAAY,GAAG;GAChF;EACD;EACA,MAAM;CACP;AACD;AAEA,SAAS,YAAY,OAAuB;CAC3C,MAAM,QAAQ;EAAC;EAAK;EAAM;EAAM;CAAI;CACpC,IAAI,QAAQ;CACZ,IAAI,YAAY;CAEhB,OAAO,SAAS,QAAQ,YAAY,MAAM,SAAS,GAAG;EACrD,SAAS;EACT,aAAa;CACd;CAEA,MAAM,YAAY,cAAc,KAAK,SAAS,KAAK,IAAI;CAEvD,OAAO,GAAG,MAAM,QAAQ,SAAS,EAAE,GAAG,MAAM,cAAc;AAC3D;AAEA,SAAS,eAAe,cAA8B;CACrD,MAAM,QAAQ,KAAK,MAAM,eAAe,IAAI;CAC5C,MAAM,UAAU,KAAK,MAAO,eAAe,OAAQ,EAAE;CACrD,MAAM,UAAU,KAAK,MAAM,eAAe,EAAE;CAE5C,IAAI,QAAQ,GAAG,OAAO,GAAG,OAAO,KAAK,EAAE,IAAI,OAAO,OAAO,EAAE,IAAI,OAAO,OAAO,EAAE;CAC/E,IAAI,UAAU,GAAG,OAAO,GAAG,OAAO,OAAO,EAAE,IAAI,OAAO,OAAO,EAAE;CAE/D,OAAO,GAAG,OAAO,OAAO,EAAE;AAC3B;AAEA,SAAS,cACR,iBACA,WACA,WACA,aACS;CACT,OAAO,GAAG,eAAe,eAAe,EAAE,IAAI,OAAO,SAAS,EAAE,UAAU,OAAO,SAAS,EAAE,UAAU,YAAY,WAAW,EAAE;AAChI;AAEA,eAAe,iBAAiB,KAAqC;CACpE,MAAM,UAAU,MAAM,QAAQ,KAAK,EAAE,eAAe,KAAK,CAAC;CAC1D,IAAI,YAAY;CAChB,IAAI,cAAc;CAElB,KAAK,MAAM,SAAS,SAAS;EAC5B,MAAM,QAAQ,IAAI,IAAI,MAAM,YAAY,IAAI,GAAG,MAAM,KAAK,KAAK,MAAM,MAAM,GAAG;EAE9E,IAAI,MAAM,YAAY,GAAG;GACxB,MAAM,SAAS,MAAM,iBAAiB,KAAK;GAC3C,aAAa,OAAO;GACpB,eAAe,OAAO;EACvB,OAAO,IAAI,MAAM,OAAO,GAAG;GAC1B,MAAM,QAAQ,MAAM,KAAK,KAAK;GAC9B,aAAa;GACb,eAAe,MAAM;EACtB;CACD;CACA,OAAO;EAAE;EAAW;CAAY;AACjC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@xsynaptic/astro-build-logger",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Astro integration that appends build duration, page count, and output size to a JSONL log file",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -34,13 +34,13 @@
|
|
|
34
34
|
],
|
|
35
35
|
"sideEffects": false,
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"zod": "^4.4
|
|
37
|
+
"zod": "^4.5.4"
|
|
38
38
|
},
|
|
39
39
|
"peerDependencies": {
|
|
40
|
-
"astro": "^6.0.0 || ^7.0.0
|
|
40
|
+
"astro": "^6.0.0 || ^7.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"astro": "7.
|
|
43
|
+
"astro": "^7.2.10"
|
|
44
44
|
},
|
|
45
45
|
"scripts": {
|
|
46
46
|
"build": "tsdown",
|