fix(build): migrate project config to .smartconfig.json and replace smartfile usage with native fs

This commit is contained in:
2026-04-07 15:58:41 +00:00
parent d2f38be0af
commit 54caa7ae8c
15 changed files with 2050 additions and 3311 deletions

View File

@@ -1,7 +1,7 @@
{
"json.schemas": [
{
"fileMatch": ["/npmextra.json"],
"fileMatch": ["/.smartconfig.json"],
"schema": {
"type": "object",
"properties": {

View File

@@ -1,5 +1,13 @@
# Changelog
## 2026-04-07 - 3.2.2 - fix(build)
migrate project config to .smartconfig.json and replace smartfile usage with native fs
- rename npmextra.json to .smartconfig.json for updated tooling compatibility
- remove the @push.rocks/smartfile dependency by using native fs for file destination setup
- update tsconfig for newer tsbuild and TypeScript versions by explicitly including node types
- fix edge cases in buffer timestamp filtering and initialize internal fields for stricter TypeScript compatibility
## 2026-02-20 - 3.2.1 - fix(destination-buffer)
return entries in chronological order (oldest-first) and adjust pagination semantics

View File

@@ -1,4 +1,4 @@
Copyright (c) 2018 Lossless GmbH (hello@lossless.com)
Copyright (c) 2018 Task Venture Capital GmbH (hello@task.vc)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@@ -34,7 +34,7 @@
"./destination-receiver": "./dist_ts_destination_receiver/index.js",
"./receiver": "./dist_ts_receiver/index.js"
},
"author": "Lossless GmbH",
"author": "Task Venture Capital GmbH",
"license": "MIT",
"scripts": {
"test": "(tstest test/**/*.ts --verbose)",
@@ -43,23 +43,22 @@
"buildDocs": "tsdoc"
},
"devDependencies": {
"@git.zone/tsbuild": "^4.1.2",
"@git.zone/tsbundle": "^2.8.3",
"@git.zone/tsrun": "^2.0.1",
"@git.zone/tstest": "^3.1.8",
"@types/node": "^22.15.20"
"@git.zone/tsbuild": "^4.4.0",
"@git.zone/tsbundle": "^2.10.0",
"@git.zone/tsrun": "^2.0.2",
"@git.zone/tstest": "^3.6.3",
"@types/node": "^25.5.2"
},
"dependencies": {
"@api.global/typedrequest-interfaces": "^3.0.19",
"@push.rocks/consolecolor": "^2.0.3",
"@push.rocks/isounique": "^1.0.5",
"@push.rocks/smartclickhouse": "^2.0.17",
"@push.rocks/smartfile": "^11.2.7",
"@push.rocks/smartclickhouse": "^2.2.0",
"@push.rocks/smarthash": "^3.2.6",
"@push.rocks/smartpromise": "^4.2.3",
"@push.rocks/smarttime": "^4.1.1",
"@push.rocks/webrequest": "^4.0.1",
"@tsclass/tsclass": "^9.3.0"
"@push.rocks/smarttime": "^4.2.3",
"@push.rocks/webrequest": "^4.0.5",
"@tsclass/tsclass": "^9.5.0"
},
"files": [
"ts/**/*",
@@ -70,7 +69,7 @@
"dist_ts_web/**/*",
"assets/**/*",
"cli.js",
"npmextra.json",
".smartconfig.json",
"readme.md"
],
"browserslist": [

5234
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -33,11 +33,18 @@ The library uses feature detection to adapt to different environments:
## Available Destinations
- Console (built-in)
- File (ts_destination_file)
- File (ts_destination_file) — uses native Node `fs` (no longer depends on @push.rocks/smartfile)
- Local (ts_destination_local)
- Clickhouse (ts_destination_clickhouse)
- Developer Tools (ts_destination_devtools)
- Receiver (ts_destination_receiver)
- Buffer (ts_destination_buffer) — in-memory circular buffer with query/filter/pagination
## Build & TS Config Notes
- `tsconfig.json` requires `"types": ["node"]` for Node globals (Buffer, process, NodeJS namespace) to be picked up by tsbuild 4.4+ / TypeScript 6.x. Without it, transitive deps like @tsclass/tsclass and @push.rocks/smartrx fail to compile because they reference Node types in their public `.d.ts`.
- Do NOT add `baseUrl` or `paths: {}``baseUrl` is deprecated in TS 6.x and triggers TS5101.
- Configuration is now in `.smartconfig.json` (renamed from `npmextra.json` in tsbuild 4.4).
## Advanced Features

View File

@@ -254,6 +254,48 @@ logger.addLogDestination(receiver);
Logs are sent as authenticated JSON payloads with SHA-256 hashed passphrases.
#### 🧠 In-Memory Buffer
Keep a rolling, queryable window of recent log entries in memory — perfect for diagnostics dashboards, post-mortems, or exposing recent logs through a debug endpoint without writing them to disk:
```typescript
import { SmartlogDestinationBuffer } from '@push.rocks/smartlog/destination-buffer';
// Default buffer holds 2000 entries (circular: oldest entries are evicted)
const buffer = new SmartlogDestinationBuffer({ maxEntries: 5000 });
logger.addLogDestination(buffer);
// Query recent entries (chronological order, oldest-first)
const recent = buffer.getEntries({ limit: 100 });
// Filter by level (single or multiple)
const errorsOnly = buffer.getEntries({ level: 'error' });
const warningsAndErrors = buffer.getEntries({ level: ['warn', 'error'] });
// Filter by message content (case-insensitive search)
const dbErrors = buffer.getEntries({ search: 'database' });
// Filter by timestamp (entries since a given moment)
const sinceLastMinute = buffer.getEntries({ since: Date.now() - 60_000 });
// Pagination — limit + offset (offset counts back from the newest entry)
const page = buffer.getEntries({ limit: 50, offset: 100 });
// Inspect or clear the buffer
console.log(buffer.getEntryCount()); // current number of stored entries
buffer.clear();
```
Use it together with an HTTP endpoint to surface live, in-process logs for debugging:
```typescript
app.get('/_debug/logs', (req, res) => {
const level = req.query.level as any;
const search = req.query.search as string;
res.json(buffer.getEntries({ level, search, limit: 200 }));
});
```
### 🛠️ Custom Destinations
Build your own destination for any logging backend by implementing the `ILogDestination` interface:
@@ -684,7 +726,7 @@ interface ILogPackage<T = unknown> {
## License and Legal Information
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [license](./license) file.
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.

View File

@@ -3,6 +3,6 @@
*/
export const commitinfo = {
name: '@push.rocks/smartlog',
version: '3.2.1',
version: '3.2.2',
description: 'A minimalistic, distributed, and extensible logging tool supporting centralized log management.'
}

View File

@@ -26,7 +26,7 @@ export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
public uniInstanceId: string = plugins.isounique.uni();
private consoleEnabled: boolean;
private consoleEnabled: boolean = false;
private logRouter = new LogRouter();
@@ -52,11 +52,11 @@ export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
const originalStdoutWrite = process.stdout.write.bind(process.stdout);
const originalStderrWrite = process.stderr.write.bind(process.stderr);
process.stdout.write = (...args: any) => {
process.stdout.write = ((...args: any[]) => {
const logString: string = args[0];
if (!logString || typeof logString !== 'string') {
// continue as planned
return originalStdoutWrite(...args);
return (originalStdoutWrite as any)(...args);
}
if (!logString.startsWith('LOG')) {
@@ -68,17 +68,17 @@ export class Smartlog implements plugins.smartlogInterfaces.ILogDestination {
return true;
}
return originalStdoutWrite(...args);
};
return (originalStdoutWrite as any)(...args);
}) as typeof process.stdout.write;
process.stderr.write = (...args: any) => {
process.stderr.write = ((...args: any[]) => {
const logString: string = args[0];
if (!logString || typeof logString !== 'string' || !logString.startsWith('LOG')) {
this.log('error', logString);
return true;
}
return originalStderrWrite(...args);
};
return (originalStderrWrite as any)(...args);
}) as typeof process.stderr.write;
}
this.consoleEnabled = true;
}

View File

@@ -46,8 +46,9 @@ export class SmartlogDestinationBuffer implements ILogDestination {
}
// Filter by timestamp
if (options?.since) {
results = results.filter((pkg) => pkg.timestamp >= options.since);
if (options?.since !== undefined) {
const since = options.since;
results = results.filter((pkg) => pkg.timestamp >= since);
}
// Return most recent `limit` entries in chronological order (oldest-first)

View File

@@ -12,7 +12,7 @@ export class SmartlogDestinationClickhouse implements plugins.smartlogInterfaces
// INSTANCE
private smartclickhouseDb: plugins.smartclickhouse.SmartClickHouseDb;
private logTable: plugins.smartclickhouse.TimeDataTable;
private logTable!: plugins.smartclickhouse.TimeDataTable;
constructor(options: plugins.smartclickhouse.IClickhouseConstructorOptions) {
this.smartclickhouseDb = new plugins.smartclickhouse.SmartClickHouseDb(options);
}

View File

@@ -1,4 +1,4 @@
import * as plugins from './smartfile-destination-file.plugins.js';
import * as plugins from './plugins.js';
export class SmartlogDestinationFile implements plugins.smartlogInterfaces.ILogDestination {
public fileWriteStream: plugins.fs.WriteStream;
@@ -12,7 +12,10 @@ export class SmartlogDestinationFile implements plugins.smartlogInterfaces.ILogD
if (!plugins.path.isAbsolute(filePathArg)) {
throw new Error(`filePath needs to be absolute but is not: "${filePathArg}"`);
}
plugins.smartfile.fs.ensureFileSync(filePathArg, `# Smartlogfile. Created at ${extendedDate.toISOString()}\n`);
if (!plugins.fs.existsSync(filePathArg)) {
plugins.fs.mkdirSync(plugins.path.dirname(filePathArg), { recursive: true });
plugins.fs.writeFileSync(filePathArg, `# Smartlogfile. Created at ${extendedDate.toISOString()}\n`);
}
this.fileWriteStream = plugins.fs.createWriteStream(
filePathArg,
{

View File

@@ -8,12 +8,10 @@ export {
};
// pushrocks scope
import * as smartfile from '@push.rocks/smartfile';
import * as smartlogInterfaces from '../dist_ts_interfaces/index.js';
import * as smarttime from '@push.rocks/smarttime';
export {
smartfile,
smartlogInterfaces,
smarttime
};

View File

@@ -7,8 +7,7 @@
"moduleResolution": "NodeNext",
"esModuleInterop": true,
"verbatimModuleSyntax": true,
"baseUrl": ".",
"paths": {}
"types": ["node"]
},
"exclude": [
"dist_*/**/*.d.ts"