Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Socket
Sign inDemoInstall

@furystack/core

Package Overview
Dependencies
Maintainers
1
Versions
214
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@furystack/core - npm Package Compare versions

Comparing version 2.0.0 to 4.0.0

dist/InjectorExtension.d.ts

30

dist/FileStore.d.ts
/// <reference types="node" />
import { Constructable } from '@furystack/inject';
import { ILogger } from '@furystack/logging';
import { readFile as nodeReadFile, writeFile as nodeWriteFile } from 'fs';
import { LoggerCollection } from './Loggers';
import { IPhysicalStore } from './Models/IPhysicalStore';
import { DefaultFilter, IPhysicalStore } from './Models/IPhysicalStore';
/**
* Store implementation that stores info in a simple JSON file
*/
export declare class FileStore<T, K extends keyof T = keyof T> implements IPhysicalStore<T, K> {
private readonly fileName;
readonly primaryKey: K;
readonly tickMs: number;
private readFile;
private writeFile;
logger: LoggerCollection;
export declare class FileStore<T> implements IPhysicalStore<T, DefaultFilter<T>> {
private readonly options;
private readonly watcher?;
readonly model: Constructable<T>;
readonly primaryKey: keyof T;
remove(key: T[this['primaryKey']]): Promise<void>;

@@ -23,3 +21,3 @@ readonly logScope: string;

add(data: T): Promise<T>;
filter: (filter: Partial<T>) => Promise<T[]>;
filter: (filter: DefaultFilter<T>) => Promise<T[]>;
count(): Promise<number>;

@@ -31,4 +29,14 @@ private fileLock;

update(id: T[this['primaryKey']], data: T): Promise<void>;
constructor(fileName: string, primaryKey: K, tickMs?: number, readFile?: typeof nodeReadFile, writeFile?: typeof nodeWriteFile, logger?: LoggerCollection);
private readFile;
private writeFile;
constructor(options: {
fileName: string;
primaryKey: keyof T;
tickMs?: number;
logger: ILogger;
model: Constructable<T>;
readFile?: typeof nodeReadFile;
writeFile?: typeof nodeWriteFile;
});
}
//# sourceMappingURL=FileStore.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const tslib_1 = require("tslib");
const fs_1 = require("fs");
const semaphore_async_await_1 = require("semaphore-async-await");
const Loggers_1 = require("./Loggers");
const semaphore_async_await_1 = tslib_1.__importDefault(require("semaphore-async-await"));
/**

@@ -10,12 +10,7 @@ * Store implementation that stores info in a simple JSON file

class FileStore {
constructor(fileName, primaryKey, tickMs = 10000, readFile = fs_1.readFile, writeFile = fs_1.writeFile, logger = new Loggers_1.LoggerCollection()) {
this.fileName = fileName;
this.primaryKey = primaryKey;
this.tickMs = tickMs;
this.readFile = readFile;
this.writeFile = writeFile;
this.logger = logger;
constructor(options) {
this.options = options;
this.logScope = '@furystack/core/' + this.constructor.name;
this.cache = new Map();
this.tick = setInterval(() => this.saveChanges(), this.tickMs);
this.tick = setInterval(() => this.saveChanges(), this.options.tickMs || 5000);
this.hasChanges = false;

@@ -28,16 +23,24 @@ this.get = async (key) => {

this.filter = async (filter) => {
return await this.fileLock.execute(async () => {
return [...this.cache.values()].filter(item => {
for (const key in filter) {
if (filter[key] !== item[key]) {
return false;
}
return [...this.cache.values()].filter(item => {
for (const key in filter.filter) {
if (filter.filter[key] !== item[key]) {
return false;
}
return true;
});
}
return true;
});
};
this.fileLock = new semaphore_async_await_1.default(1);
this.readFile = fs_1.readFile;
this.writeFile = fs_1.writeFile;
this.primaryKey = options.primaryKey;
this.model = options.model;
options.readFile && (this.readFile = options.readFile);
options.writeFile && (this.writeFile = options.writeFile);
try {
this.watcher = fs_1.watch(this.fileName, { encoding: 'buffer' }, () => {
this.watcher = fs_1.watch(this.options.fileName, { encoding: 'buffer' }, () => {
this.options.logger.verbose({
scope: this.logScope,
message: `The file '${this.options.fileName}' has been changed, reloading data...`,
});
this.reloadData();

@@ -47,7 +50,3 @@ });

catch (error) {
this.logger.warning({
scope: this.logScope,
data: error,
message: `Error registering file watcher for store. External updates won't be updated.`,
});
// Error registering file watcher for store. External updates won't be updated.
}

@@ -84,3 +83,3 @@ }

await new Promise((resolve, reject) => {
this.writeFile(this.fileName, JSON.stringify(values), error => {
this.writeFile(this.options.fileName, JSON.stringify(values), error => {
if (!error) {

@@ -90,7 +89,2 @@ resolve();

else {
this.logger.error({
scope: this.logScope,
message: 'Error when saving store data to file:',
data: { error },
});
reject(error);

@@ -101,3 +95,15 @@ }

this.hasChanges = false;
this.options.logger.information({
scope: this.logScope,
message: `Store '${this.options.fileName}' has been updated with the latest changes.`,
data: { values },
});
}
catch (e) {
this.options.logger.error({
scope: this.logScope,
message: `Error saving changed data to '${this.options.fileName}'.`,
data: { error: e },
});
}
finally {

@@ -108,2 +114,6 @@ this.fileLock.release();

async dispose() {
this.options.logger.information({
scope: this.logScope,
message: `Disposing FileStore: '${this.options.fileName}'`,
});
await this.saveChanges();

@@ -117,9 +127,4 @@ this.watcher && this.watcher.close();

await new Promise((resolve, reject) => {
this.readFile(this.fileName, (error, data) => {
this.readFile(this.options.fileName, (error, data) => {
if (error) {
this.logger.error({
scope: this.logScope,
message: 'Error when loading store data from file:',
data: { error },
});
reject(error);

@@ -138,2 +143,9 @@ }

}
catch (e) {
this.options.logger.error({
scope: this.logScope,
message: `Error loading data into store from '${this.options.fileName}'.`,
data: e,
});
}
finally {

@@ -140,0 +152,0 @@ this.fileLock.release();

export * from './SystemRoles';
export * from './Loggers';
export * from './Models/IActivateable';
export * from './Models/IApi';
export * from './Models/IFuryStackOptions';
export * from './Models/ILogEntries';
export * from './Models/ILogger';
export * from './InjectorExtension';
export * from './ServerManager';
export * from './Models/IPhysicalStore';
export * from './Models/IRole';
export * from './Models/IUser';
export * from './Models/User';
export * from './FileStore';
export * from './FuryStack';
export * from './InMemoryStore';
export * from './UserContext';
export * from './StoreManager';
import './InjectorExtension';
//# sourceMappingURL=index.d.ts.map
"use strict";
function __export(m) {
for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p];
}
Object.defineProperty(exports, "__esModule", { value: true });
__export(require("./SystemRoles"));
__export(require("./Loggers"));
__export(require("./Models/ILogEntries"));
__export(require("./Models/IUser"));
__export(require("./FileStore"));
__export(require("./FuryStack"));
__export(require("./InMemoryStore"));
__export(require("./UserContext"));
const tslib_1 = require("tslib");
tslib_1.__exportStar(require("./SystemRoles"), exports);
tslib_1.__exportStar(require("./ServerManager"), exports);
tslib_1.__exportStar(require("./Models/User"), exports);
tslib_1.__exportStar(require("./FileStore"), exports);
tslib_1.__exportStar(require("./InMemoryStore"), exports);
tslib_1.__exportStar(require("./StoreManager"), exports);
require("./InjectorExtension");
//# sourceMappingURL=index.js.map

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

import { LoggerCollection } from './Loggers';
import { IPhysicalStore } from './Models/IPhysicalStore';
import { Constructable } from '@furystack/inject';
import { DefaultFilter, IPhysicalStore } from './Models/IPhysicalStore';
/**
* Store implementation that stores data in an in-memory cache
*/
export declare class InMemoryStore<T, K extends keyof T = keyof T> implements IPhysicalStore<T, K> {
readonly primaryKey: K;
readonly tickMs: number;
logger: LoggerCollection;
export declare class InMemoryStore<T> implements IPhysicalStore<T, Partial<T>> {
remove(key: T[this['primaryKey']]): Promise<void>;

@@ -14,8 +11,15 @@ add(data: T): Promise<T>;

get: (key: T[this["primaryKey"]]) => Promise<T | undefined>;
filter: (filter: Partial<T>) => Promise<T[]>;
filter: (filter: DefaultFilter<T>) => Promise<T[]>;
count(): Promise<number>;
update(id: T[this['primaryKey']], data: T): Promise<void>;
dispose(): void;
constructor(primaryKey: K, tickMs?: number, logger?: LoggerCollection);
readonly primaryKey: keyof T;
tickMs: number;
readonly model: Constructable<T>;
constructor(options: {
primaryKey: keyof T;
tickMs?: number;
model: Constructable<T>;
});
}
//# sourceMappingURL=InMemoryStore.d.ts.map
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const Loggers_1 = require("./Loggers");
/**

@@ -8,16 +7,19 @@ * Store implementation that stores data in an in-memory cache

class InMemoryStore {
constructor(primaryKey, tickMs = 10000, logger = new Loggers_1.LoggerCollection()) {
this.primaryKey = primaryKey;
this.tickMs = tickMs;
this.logger = logger;
constructor(options) {
this.cache = new Map();
this.get = async (key) => this.cache.get(key);
this.filter = async (filter) => [...this.cache.values()].filter(item => {
for (const key in filter) {
if (filter[key] !== item[key]) {
return false;
this.filter = async (filter) => {
return [...this.cache.values()].filter(item => {
for (const key in filter.filter) {
if (filter.filter[key] !== item[key]) {
return false;
}
}
}
return true;
});
return true;
});
};
this.tickMs = 10000;
this.primaryKey = options.primaryKey;
options.tickMs && (this.tickMs = options.tickMs);
this.model = options.model;
}

@@ -24,0 +26,0 @@ async remove(key) {

@@ -0,12 +1,21 @@

import { Constructable } from '@furystack/inject';
import { Disposable } from '@sensenet/client-utils';
import { ILogger } from './ILogger';
/**
* Interface that defines a physical store implementation
* Type for default filtering model
*/
export interface IPhysicalStore<T, K extends keyof T = keyof T, TFilter = Partial<T> & {
export interface DefaultFilter<T> {
top?: number;
skip?: number;
}> extends Disposable {
readonly primaryKey: K;
logger: ILogger;
order?: {
[P in keyof T]?: 'ASC' | 'DESC';
};
select?: Array<keyof T>;
filter?: Partial<T>;
}
/**
* Interface that defines a physical store implementation
*/
export interface IPhysicalStore<T, TFilter = DefaultFilter<T>> extends Disposable {
readonly primaryKey: keyof T;
readonly model: Constructable<T>;
add(data: T): Promise<T>;

@@ -13,0 +22,0 @@ update(id: T[this['primaryKey']], data: T): Promise<void>;

{
"name": "@furystack/core",
"version": "2.0.0",
"version": "4.0.0",
"description": "Core FuryStack package",

@@ -58,13 +58,14 @@ "main": "dist/index.js",

"dependencies": {
"@furystack/inject": "^2.0.0",
"@sensenet/client-utils": "^1.2.1",
"semaphore-async-await": "^1.5.1"
"@furystack/inject": "^3.0.1",
"@furystack/logging": "^1.0.0",
"@sensenet/client-utils": "^1.5.1",
"semaphore-async-await": "1.5.1"
},
"devDependencies": {
"@types/jest": "^23.3.11",
"jest": "^23.6.0",
"rimraf": "^2.6.1",
"ts-jest": "^23.10.4",
"tslint": "^5.11.0",
"typescript": "^3.1.6"
"@types/jest": "24.0.9",
"jest": "24.1.0",
"rimraf": "2.6.3",
"ts-jest": "24.0.0",
"tslint": "5.13.0",
"typescript": "^3.4.3"
},

@@ -77,3 +78,3 @@ "config": {

"typings": "./dist/index.d.ts",
"gitHead": "d0452632dfb2b8de2dcb1c47d88fff62997c738d"
"gitHead": "2fa8429190fca702d037ea9da26cdc9ded16a8de"
}

@@ -0,5 +1,6 @@

import { Constructable } from '@furystack/inject'
import { ILogger } from '@furystack/logging'
import { FSWatcher, readFile as nodeReadFile, watch, writeFile as nodeWriteFile } from 'fs'
import Semaphore from 'semaphore-async-await'
import { LoggerCollection } from './Loggers'
import { IPhysicalStore } from './Models/IPhysicalStore'
import { DefaultFilter, IPhysicalStore } from './Models/IPhysicalStore'

@@ -9,4 +10,8 @@ /**

*/
export class FileStore<T, K extends keyof T = keyof T> implements IPhysicalStore<T, K> {
export class FileStore<T> implements IPhysicalStore<T, DefaultFilter<T>> {
private readonly watcher?: FSWatcher
public readonly model: Constructable<T>
public readonly primaryKey: keyof T
public async remove(key: T[this['primaryKey']]): Promise<void> {

@@ -18,3 +23,3 @@ this.cache.delete(key)

private cache: Map<T[this['primaryKey']], T> = new Map()
public tick = setInterval(() => this.saveChanges(), this.tickMs)
public tick = setInterval(() => this.saveChanges(), this.options.tickMs || 5000)
private hasChanges: boolean = false

@@ -37,12 +42,10 @@ public get = async (key: T[this['primaryKey']]) => {

public filter = async (filter: Partial<T>) => {
return await this.fileLock.execute(async () => {
return [...this.cache.values()].filter(item => {
for (const key in filter) {
if (filter[key] !== (item as any)[key]) {
return false
}
public filter = async (filter: DefaultFilter<T>) => {
return [...this.cache.values()].filter(item => {
for (const key in filter.filter) {
if ((filter.filter as any)[key] !== (item as any)[key]) {
return false
}
return true
})
}
return true
})

@@ -69,11 +72,6 @@ }

await new Promise((resolve, reject) => {
this.writeFile(this.fileName, JSON.stringify(values), error => {
this.writeFile(this.options.fileName, JSON.stringify(values), error => {
if (!error) {
resolve()
} else {
this.logger.error({
scope: this.logScope,
message: 'Error when saving store data to file:',
data: { error },
})
reject(error)

@@ -84,2 +82,13 @@ }

this.hasChanges = false
this.options.logger.information({
scope: this.logScope,
message: `Store '${this.options.fileName}' has been updated with the latest changes.`,
data: { values },
})
} catch (e) {
this.options.logger.error({
scope: this.logScope,
message: `Error saving changed data to '${this.options.fileName}'.`,
data: { error: e },
})
} finally {

@@ -91,2 +100,6 @@ this.fileLock.release()

public async dispose() {
this.options.logger.information({
scope: this.logScope,
message: `Disposing FileStore: '${this.options.fileName}'`,
})
await this.saveChanges()

@@ -101,9 +114,4 @@ this.watcher && this.watcher.close()

await new Promise((resolve, reject) => {
this.readFile(this.fileName, (error, data) => {
this.readFile(this.options.fileName, (error, data) => {
if (error) {
this.logger.error({
scope: this.logScope,
message: 'Error when loading store data from file:',
data: { error },
})
reject(error)

@@ -120,2 +128,8 @@ } else {

})
} catch (e) {
this.options.logger.error({
scope: this.logScope,
message: `Error loading data into store from '${this.options.fileName}'.`,
data: e,
})
} finally {

@@ -131,22 +145,33 @@ this.fileLock.release()

private readFile = nodeReadFile
private writeFile = nodeWriteFile
constructor(
private readonly fileName: string,
public readonly primaryKey: K,
public readonly tickMs = 10000,
private readFile = nodeReadFile,
private writeFile = nodeWriteFile,
public logger = new LoggerCollection(),
private readonly options: {
fileName: string
primaryKey: keyof T
tickMs?: number
logger: ILogger
model: Constructable<T>
readFile?: typeof nodeReadFile
writeFile?: typeof nodeWriteFile
},
) {
this.primaryKey = options.primaryKey
this.model = options.model
options.readFile && (this.readFile = options.readFile)
options.writeFile && (this.writeFile = options.writeFile)
try {
this.watcher = watch(this.fileName, { encoding: 'buffer' }, () => {
this.watcher = watch(this.options.fileName, { encoding: 'buffer' }, () => {
this.options.logger.verbose({
scope: this.logScope,
message: `The file '${this.options.fileName}' has been changed, reloading data...`,
})
this.reloadData()
})
} catch (error) {
this.logger.warning({
scope: this.logScope,
data: error,
message: `Error registering file watcher for store. External updates won't be updated.`,
})
// Error registering file watcher for store. External updates won't be updated.
}
}
}
export * from './SystemRoles'
export * from './Loggers'
export * from './Models/IActivateable'
export * from './Models/IApi'
export * from './Models/IFuryStackOptions'
export * from './Models/ILogEntries'
export * from './Models/ILogger'
export * from './InjectorExtension'
export * from './ServerManager'
export * from './Models/IPhysicalStore'
export * from './Models/IRole'
export * from './Models/IUser'
export * from './Models/User'
export * from './FileStore'
export * from './FuryStack'
export * from './InMemoryStore'
export * from './UserContext'
export * from './StoreManager'
import './InjectorExtension'

@@ -1,3 +0,3 @@

import { LoggerCollection } from './Loggers'
import { IPhysicalStore } from './Models/IPhysicalStore'
import { Constructable } from '@furystack/inject'
import { DefaultFilter, IPhysicalStore } from './Models/IPhysicalStore'

@@ -7,3 +7,3 @@ /**

*/
export class InMemoryStore<T, K extends keyof T = keyof T> implements IPhysicalStore<T, K> {
export class InMemoryStore<T> implements IPhysicalStore<T, Partial<T>> {
public async remove(key: T[this['primaryKey']]): Promise<void> {

@@ -24,6 +24,6 @@ this.cache.delete(key)

public filter = async (filter: Partial<T>) =>
[...this.cache.values()].filter(item => {
for (const key in filter) {
if (filter[key] !== (item as any)[key]) {
public filter = async (filter: DefaultFilter<T>) => {
return [...this.cache.values()].filter(item => {
for (const key in filter.filter) {
if ((filter.filter as any)[key] !== (item as any)[key]) {
return false

@@ -34,2 +34,3 @@ }

})
}

@@ -48,3 +49,11 @@ public async count() {

constructor(public readonly primaryKey: K, public readonly tickMs = 10000, public logger = new LoggerCollection()) {}
public readonly primaryKey: keyof T
public tickMs = 10000
public readonly model: Constructable<T>
constructor(options: { primaryKey: keyof T; tickMs?: number; model: Constructable<T> }) {
this.primaryKey = options.primaryKey
options.tickMs && (this.tickMs = options.tickMs)
this.model = options.model
}
}

@@ -0,11 +1,21 @@

import { Constructable } from '@furystack/inject'
import { Disposable } from '@sensenet/client-utils'
import { ILogger } from './ILogger'
/**
* Type for default filtering model
*/
export interface DefaultFilter<T> {
top?: number
skip?: number
order?: { [P in keyof T]?: 'ASC' | 'DESC' }
select?: Array<keyof T>
filter?: Partial<T>
}
/**
* Interface that defines a physical store implementation
*/
export interface IPhysicalStore<T, K extends keyof T = keyof T, TFilter = Partial<T> & { top?: number; skip?: number }>
extends Disposable {
readonly primaryKey: K
logger: ILogger
export interface IPhysicalStore<T, TFilter = DefaultFilter<T>> extends Disposable {
readonly primaryKey: keyof T
readonly model: Constructable<T>
add(data: T): Promise<T>

@@ -12,0 +22,0 @@ update(id: T[this['primaryKey']], data: T): Promise<void>

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

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