New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@curium.rocks/json-chronicler

Package Overview
Dependencies
Maintainers
1
Versions
135
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@curium.rocks/json-chronicler - npm Package Compare versions

Comparing version 0.1.1-1 to 0.1.1-2

build/src/jsonChroniclerFactory.d.ts

3

build/src/index.d.ts

@@ -1,1 +0,2 @@

export { JsonChronicler, JsonChroniclerOptions, getMsFromRotationOptions, RotationOptions } from './jsonChronicler';
export { JsonChronicler, JsonChroniclerOptions, getMsFromRotationOptions, RotationOptions, isRotationOptions } from './jsonChronicler';
export { JsonChroniclerFactory } from './jsonChroniclerFactory';
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.getMsFromRotationOptions = exports.JsonChronicler = void 0;
exports.JsonChroniclerFactory = exports.isRotationOptions = exports.getMsFromRotationOptions = exports.JsonChronicler = void 0;
var jsonChronicler_1 = require("./jsonChronicler");
Object.defineProperty(exports, "JsonChronicler", { enumerable: true, get: function () { return jsonChronicler_1.JsonChronicler; } });
Object.defineProperty(exports, "getMsFromRotationOptions", { enumerable: true, get: function () { return jsonChronicler_1.getMsFromRotationOptions; } });
Object.defineProperty(exports, "isRotationOptions", { enumerable: true, get: function () { return jsonChronicler_1.isRotationOptions; } });
var jsonChroniclerFactory_1 = require("./jsonChroniclerFactory");
Object.defineProperty(exports, "JsonChroniclerFactory", { enumerable: true, get: function () { return jsonChroniclerFactory_1.JsonChroniclerFactory; } });
//# sourceMappingURL=index.js.map

@@ -1,7 +0,7 @@

import { LoggerFacade, IRotatingFileChronicler, IJsonSerializable } from '@curium.rocks/data-emitter-base';
export interface JsonChroniclerOptions {
import { LoggerFacade, IRotatingFileChronicler, IJsonSerializable, IClassifier } from '@curium.rocks/data-emitter-base';
export interface JsonChroniclerOptions extends IClassifier {
logger?: LoggerFacade;
rotationSettings: RotationOptions;
logDirectory: string;
name: string;
logName: string;
}

@@ -24,5 +24,12 @@ export interface RotationOptions {

/**
* Check if an object conforms to the RotationOptions interface
* @param {unknown} options
* @return {boolean}
*/
export declare function isRotationOptions(options: unknown): boolean;
/**
* Persist events to a rolling JSON file
*/
export declare class JsonChronicler implements IRotatingFileChronicler {
static readonly TYPE: string;
private firstWrite;

@@ -38,4 +45,19 @@ private fileHandle;

private disposed;
private _id;
private _name;
private _description;
/**
*
*/
get id(): string;
/**
*
*/
get description(): string;
/**
*
*/
get name(): string;
/**
*
* @param {JsonChroniclerOptions} options

@@ -42,0 +64,0 @@ */

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __generator = (this && this.__generator) || function (thisArg, body) {
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
function verb(n) { return function (v) { return step([n, v]); }; }
function step(op) {
if (f) throw new TypeError("Generator is already executing.");
while (_) try {
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
if (y = 0, t) op = [op[0] & 2, t.value];
switch (op[0]) {
case 0: case 1: t = op; break;
case 4: _.label++; return { value: op[1], done: false };
case 5: _.label++; y = op[1]; op = [0]; continue;
case 7: op = _.ops.pop(); _.trys.pop(); continue;
default:
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
if (t[2]) _.ops.pop();
_.trys.pop(); continue;
}
op = body.call(thisArg, _);
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
}
};
var __importDefault = (this && this.__importDefault) || function (mod) {

@@ -42,8 +6,8 @@ return (mod && mod.__esModule) ? mod : { "default": mod };

Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonChronicler = exports.getMsFromRotationOptions = void 0;
var promises_1 = __importDefault(require("fs/promises"));
var promises_2 = require("stream/promises");
var fs_1 = require("fs");
var zlib_1 = __importDefault(require("zlib"));
var path_1 = __importDefault(require("path"));
exports.JsonChronicler = exports.isRotationOptions = exports.getMsFromRotationOptions = void 0;
const promises_1 = __importDefault(require("fs/promises"));
const promises_2 = require("stream/promises");
const fs_1 = require("fs");
const zlib_1 = __importDefault(require("zlib"));
const path_1 = __importDefault(require("path"));
/**

@@ -55,3 +19,3 @@ *

function getMsFromRotationOptions(options) {
var total = 0;
let total = 0;
if (options.days)

@@ -71,5 +35,20 @@ total += options.days * 86400000;

/**
* Check if an object conforms to the RotationOptions interface
* @param {unknown} options
* @return {boolean}
*/
function isRotationOptions(options) {
if (options == null)
return false;
if (typeof options != "object")
return false;
// all properties for rotation options are nullable soooo as long as it's an object and not null
// it conforms to the contract for now.
return true;
}
exports.isRotationOptions = isRotationOptions;
/**
* Persist events to a rolling JSON file
*/
var JsonChronicler = /** @class */ (function () {
class JsonChronicler {
/**

@@ -79,3 +58,3 @@ *

*/
function JsonChronicler(options) {
constructor(options) {
this.firstWrite = true;

@@ -86,12 +65,33 @@ this.disposed = false;

this.logDirectory = options.logDirectory;
this.logName = options.name;
this.logName = options.logName;
this.rotationIntervalMs = getMsFromRotationOptions(options.rotationSettings);
this._name = options.name;
this._description = options.description;
this._id = options.id;
}
/**
*
*/
get id() {
return this._id;
}
/**
*
*/
get description() {
return this._description;
}
/**
*
*/
get name() {
return this._name;
}
/**
* @return {string} filename for next archive
* @private
*/
JsonChronicler.prototype.generateFilename = function () {
return this.logName + "." + new Date().getTime() + ".json";
};
generateFilename() {
return `${this.logName}.${new Date().getTime()}.json`;
}
/**

@@ -102,37 +102,17 @@ *

*/
JsonChronicler.prototype.saveRecord = function (record) {
var _a;
return __awaiter(this, void 0, void 0, function () {
var string, fileName, _b;
return __generator(this, function (_c) {
switch (_c.label) {
case 0:
if (this.disposed)
throw new Error("Object Disposed!");
string = JSON.stringify(record);
return [4 /*yield*/, this.shouldCreateFile()];
case 1:
if (!_c.sent()) return [3 /*break*/, 3];
fileName = this.generateFilename();
_b = this;
return [4 /*yield*/, this.createLogFile(fileName)];
case 2:
_b.fileHandle = _c.sent();
this.currentFile = fileName;
this.lastRotationMs = new Date().getTime();
_c.label = 3;
case 3:
if (!this.shouldRotate()) return [3 /*break*/, 5];
return [4 /*yield*/, this.rotateLog()];
case 4:
_c.sent();
_c.label = 5;
case 5: return [4 /*yield*/, ((_a = this.fileHandle) === null || _a === void 0 ? void 0 : _a.write("" + (!this.firstWrite ? ',\n' : '') + string))];
case 6:
_c.sent();
return [2 /*return*/];
}
});
});
};
async saveRecord(record) {
if (this.disposed)
throw new Error("Object Disposed!");
const string = JSON.stringify(record);
if (await this.shouldCreateFile()) {
const fileName = this.generateFilename();
this.fileHandle = await this.createLogFile(fileName);
this.currentFile = fileName;
this.lastRotationMs = new Date().getTime();
}
if (this.shouldRotate()) {
await this.rotateLog();
}
await this.fileHandle?.write(`${!this.firstWrite ? ',\n' : ''}${string}`);
}
/**

@@ -142,25 +122,11 @@ * @param {string} fileName of new log file

*/
JsonChronicler.prototype.createLogFile = function (fileName) {
return __awaiter(this, void 0, void 0, function () {
var filePath, fileHandle;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
filePath = path_1.default.join(this.logDirectory, fileName);
return [4 /*yield*/, promises_1.default.mkdir(this.logDirectory, {
recursive: true
})];
case 1:
_a.sent();
return [4 /*yield*/, promises_1.default.open(filePath, 'w')];
case 2:
fileHandle = _a.sent();
return [4 /*yield*/, fileHandle.write('[')];
case 3:
_a.sent();
return [2 /*return*/, fileHandle];
}
});
async createLogFile(fileName) {
const filePath = path_1.default.join(this.logDirectory, fileName);
await promises_1.default.mkdir(this.logDirectory, {
recursive: true
});
};
const fileHandle = await promises_1.default.open(filePath, 'w');
await fileHandle.write('[');
return fileHandle;
}
/**

@@ -170,21 +136,11 @@ *

*/
JsonChronicler.prototype.shouldCreateFile = function () {
return __awaiter(this, void 0, void 0, function () {
var _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
_b.trys.push([0, 2, , 3]);
return [4 /*yield*/, promises_1.default.access(path_1.default.join(this.logDirectory, this.getCurrentFilename()))];
case 1:
_b.sent();
return [2 /*return*/, false];
case 2:
_a = _b.sent();
return [2 /*return*/, true];
case 3: return [2 /*return*/];
}
});
});
};
async shouldCreateFile() {
try {
await promises_1.default.access(path_1.default.join(this.logDirectory, this.getCurrentFilename()));
return false;
}
catch {
return true;
}
}
/**

@@ -195,7 +151,7 @@ *

*/
JsonChronicler.prototype.shouldRotate = function () {
shouldRotate() {
// check the data extracted from the current file name and compare against
// rotation rules
return this.timeTillRotation() < 0;
};
}
/**

@@ -205,11 +161,11 @@ * Gets the time since the last log file rotation in seconds

*/
JsonChronicler.prototype.timeSinceRotation = function () {
var now = new Date().getTime();
timeSinceRotation() {
const now = new Date().getTime();
if (this.lastRotationMs == null)
return now / 1000;
var timeSinceMs = now - this.lastRotationMs;
const timeSinceMs = now - this.lastRotationMs;
if (timeSinceMs == 0)
return 0;
return Math.floor(timeSinceMs / 1000);
};
}
/**

@@ -219,12 +175,12 @@ * Gets the time till the next log file rotation in seconds

*/
JsonChronicler.prototype.timeTillRotation = function () {
timeTillRotation() {
if (this.lastRotationMs == null)
return Math.floor(this.rotationIntervalMs / 1000);
var now = new Date().getTime();
var rotationTime = this.lastRotationMs + this.rotationIntervalMs;
var timeTillRotation = rotationTime - now;
const now = new Date().getTime();
const rotationTime = this.lastRotationMs + this.rotationIntervalMs;
const timeTillRotation = rotationTime - now;
if (timeTillRotation == 0)
return 0;
return Math.floor(timeTillRotation / 1000);
};
}
/**

@@ -234,32 +190,16 @@ * Rotates the logs and returns the new file name

*/
JsonChronicler.prototype.rotateLog = function () {
return __awaiter(this, void 0, void 0, function () {
var oldHandle, name, _a;
return __generator(this, function (_b) {
switch (_b.label) {
case 0:
oldHandle = this.fileHandle;
name = this.generateFilename();
_a = this;
return [4 /*yield*/, this.createLogFile(name)];
case 1:
_a.fileHandle = _b.sent();
this.currentFile = name;
return [4 /*yield*/, (oldHandle === null || oldHandle === void 0 ? void 0 : oldHandle.write(']'))];
case 2:
_b.sent();
// close the old file handle
return [4 /*yield*/, (oldHandle === null || oldHandle === void 0 ? void 0 : oldHandle.close())];
case 3:
// close the old file handle
_b.sent();
return [4 /*yield*/, this.compactLogs()];
case 4:
_b.sent();
this.lastRotationMs = new Date().getTime();
return [2 /*return*/, name];
}
});
});
};
async rotateLog() {
// create a new file
// swap the file handles
const oldHandle = this.fileHandle;
const name = this.generateFilename();
this.fileHandle = await this.createLogFile(name);
this.currentFile = name;
await oldHandle?.write(']');
// close the old file handle
await oldHandle?.close();
await this.compactLogs();
this.lastRotationMs = new Date().getTime();
return name;
}
/**

@@ -271,90 +211,54 @@ *

*/
JsonChronicler.prototype.compressLog = function (logName) {
return __awaiter(this, void 0, void 0, function () {
var gzip, source, destination;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
gzip = zlib_1.default.createGzip();
source = fs_1.createReadStream(path_1.default.join(this.logDirectory, logName));
destination = fs_1.createWriteStream(path_1.default.join(this.logDirectory, logName + ".gz"));
_a.label = 1;
case 1:
_a.trys.push([1, , 4, 5]);
return [4 /*yield*/, promises_2.pipeline(source, gzip, destination)];
case 2:
_a.sent();
return [4 /*yield*/, promises_1.default.unlink(path_1.default.join(this.logDirectory, logName))];
case 3:
_a.sent();
return [3 /*break*/, 5];
case 4:
source.close();
gzip.close();
destination.close();
return [7 /*endfinally*/];
case 5: return [2 /*return*/];
}
});
});
};
async compressLog(logName) {
const gzip = zlib_1.default.createGzip();
const source = fs_1.createReadStream(path_1.default.join(this.logDirectory, logName));
const destination = fs_1.createWriteStream(path_1.default.join(this.logDirectory, `${logName}.gz`));
try {
await promises_2.pipeline(source, gzip, destination);
await promises_1.default.unlink(path_1.default.join(this.logDirectory, logName));
}
finally {
source.close();
gzip.close();
destination.close();
}
}
/**
* @return {Promise<void>}
*/
JsonChronicler.prototype.compactLogs = function () {
return __awaiter(this, void 0, void 0, function () {
var logMatch, compressMatch, files, _i, files_1, fileName;
var _this = this;
return __generator(this, function (_a) {
switch (_a.label) {
case 0:
logMatch = new RegExp(this.logName + ".*\\.json");
compressMatch = new RegExp('.*\\.json.gz');
return [4 /*yield*/, promises_1.default.readdir(this.logDirectory)];
case 1:
files = (_a.sent())
// filter that list by the regex of matching names
.filter(function (fileName) { return fileName.match(logMatch); })
.filter(function (fileName) { return !fileName.match(compressMatch); })
// exclude the current log from that list
.filter(function (fileName) { return fileName != _this.currentFile; });
_i = 0, files_1 = files;
_a.label = 2;
case 2:
if (!(_i < files_1.length)) return [3 /*break*/, 5];
fileName = files_1[_i];
return [4 /*yield*/, this.compressLog(fileName)];
case 3:
_a.sent();
_a.label = 4;
case 4:
_i++;
return [3 /*break*/, 2];
case 5: return [2 /*return*/];
}
});
});
};
async compactLogs() {
const logMatch = `${this.logName}.*\\.json`;
const compressMatch = '.*\\.json.gz';
// get the list of files in the log directory without .gz
const files = (await promises_1.default.readdir(this.logDirectory))
// filter that list by the regex of matching names
.filter((fileName) => fileName.match(logMatch))
.filter((fileName) => !fileName.match(compressMatch))
// exclude the current log from that list
.filter((fileName) => fileName != this.currentFile);
// call compressLog on each one of the uncompressed files that match this loggers scheme
for (const fileName of files) {
await this.compressLog(fileName);
}
}
/**
* @return {string}
*/
JsonChronicler.prototype.getCurrentFilename = function () {
getCurrentFilename() {
return this.currentFile || "N/A";
};
}
/**
*
*/
JsonChronicler.prototype.dispose = function () {
var _this = this;
dispose() {
this.disposed = true;
if (this.fileHandle) {
this.fileHandle.write(']').then(function () {
var _a;
return (_a = _this.fileHandle) === null || _a === void 0 ? void 0 : _a.close();
this.fileHandle.write(']').then(() => {
return this.fileHandle?.close();
});
}
};
return JsonChronicler;
}());
}
}
exports.JsonChronicler = JsonChronicler;
JsonChronicler.TYPE = "JSON-CHRONICLER";
//# sourceMappingURL=jsonChronicler.js.map
{
"name": "@curium.rocks/json-chronicler",
"version": "0.1.1-1",
"version": "0.1.1-2",
"description": "Persists objects in JSON format to rolling archive files",

@@ -29,4 +29,2 @@ "main": "build/src/index.js",

"devDependencies": {
"@curium.rocks/data-emitter-base": "^0.1.1-alpha.20",
"@curium.rocks/ping-pong-emitter": "^0.1.1-4",
"@types/chai": "^4.2.21",

@@ -55,6 +53,10 @@ "@types/mocha": "^9.0.0",

"exclude": [
"**/*.d.ts"
"**/*.d.ts",
".eslintrc.js",
"coverage/**/*",
"test/**/*"
],
"reporter": [
"lcov"
"lcov",
"text"
],

@@ -70,4 +72,4 @@ "all": true

"dependencies": {
"@curium.rocks/data-emitter-base": "^0.1.1-alpha.20"
"@curium.rocks/data-emitter-base": "^0.1.1-alpha.31"
}
}

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc