@wxn0brp/db-core 0.11.0-alpha.0 → 0.11.0-alpha.2
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/dist/base/actions.d.ts +1 -0
- package/dist/base/actions.js +1 -0
- package/dist/customFileCpu.js +15 -22
- package/dist/db/memory.d.ts +1 -0
- package/dist/db/memory.js +1 -0
- package/dist/db/valthera.d.ts +4 -4
- package/dist/db/valthera.js +3 -3
- package/dist/helpers/executor.d.ts +20 -3
- package/dist/helpers/executor.js +47 -6
- package/dist/types/arg.d.ts +3 -2
- package/dist/utils/process.d.ts +5 -0
- package/dist/utils/process.js +30 -0
- package/dist/utils/updateObject.js +5 -9
- package/dist/version.js +1 -1
- package/package.json +1 -1
package/dist/base/actions.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { VQueryT } from "../types/query.js";
|
|
|
4
4
|
export declare abstract class ActionsBase implements ActionsBaseInterface {
|
|
5
5
|
_inited: boolean;
|
|
6
6
|
numberId: boolean;
|
|
7
|
+
smartExecutor: boolean;
|
|
7
8
|
init(...args: any[]): Promise<void>;
|
|
8
9
|
abstract getCollections(): Promise<string[]>;
|
|
9
10
|
abstract ensureCollection(collection: string): Promise<boolean>;
|
package/dist/base/actions.js
CHANGED
|
@@ -2,6 +2,7 @@ import { setDataForToggleOne, setDataForUpdateOneOrAdd } from "../helpers/assign
|
|
|
2
2
|
export class ActionsBase {
|
|
3
3
|
_inited = true;
|
|
4
4
|
numberId = false;
|
|
5
|
+
smartExecutor = false;
|
|
5
6
|
async init(...args) { }
|
|
6
7
|
async updateOneOrAdd(config) {
|
|
7
8
|
const res = await this.updateOne(config);
|
package/dist/customFileCpu.js
CHANGED
|
@@ -1,6 +1,4 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { updateFindObject } from "./utils/updateFindObject.js";
|
|
3
|
-
import { updateObjectAdvanced } from "./utils/updateObject.js";
|
|
1
|
+
import { match, findProcessLine, update } from "./utils/process.js";
|
|
4
2
|
export function pathRepair(path) {
|
|
5
3
|
return path.replaceAll("//", "/");
|
|
6
4
|
}
|
|
@@ -20,31 +18,28 @@ export class CustomFileCpu {
|
|
|
20
18
|
async find(file, config) {
|
|
21
19
|
file = pathRepair(file);
|
|
22
20
|
const entries = await this._readFile(file);
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
results.map(res => updateFindObject(res, findOpts)) :
|
|
27
|
-
[];
|
|
21
|
+
return entries
|
|
22
|
+
.map((entry) => findProcessLine(config, entry))
|
|
23
|
+
.filter(Boolean);
|
|
28
24
|
}
|
|
29
25
|
async findOne(file, config) {
|
|
30
26
|
file = pathRepair(file);
|
|
31
27
|
const entries = await this._readFile(file);
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
28
|
+
for (const entry of entries) {
|
|
29
|
+
const result = findProcessLine(config, entry);
|
|
30
|
+
if (result)
|
|
31
|
+
return result;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
37
34
|
}
|
|
38
35
|
async remove(file, config, one) {
|
|
39
36
|
file = pathRepair(file);
|
|
40
37
|
let entries = await this._readFile(file);
|
|
41
38
|
const removed = [];
|
|
42
|
-
|
|
43
|
-
entries = entries.filter(entry => {
|
|
39
|
+
entries = entries.filter((entry) => {
|
|
44
40
|
if (removed.length && one)
|
|
45
41
|
return true;
|
|
46
|
-
|
|
47
|
-
if (match) {
|
|
42
|
+
if (match(config, entry)) {
|
|
48
43
|
removed.push(entry);
|
|
49
44
|
return false;
|
|
50
45
|
}
|
|
@@ -58,13 +53,11 @@ export class CustomFileCpu {
|
|
|
58
53
|
file = pathRepair(file);
|
|
59
54
|
let entries = await this._readFile(file);
|
|
60
55
|
const updated = [];
|
|
61
|
-
|
|
62
|
-
entries = entries.map(entry => {
|
|
56
|
+
entries = entries.map((entry) => {
|
|
63
57
|
if (updated.length && one)
|
|
64
58
|
return entry;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
const updatedEntry = typeof updater === "function" ? updater(entry, context) : updateObjectAdvanced(entry, updater);
|
|
59
|
+
if (match(config, entry)) {
|
|
60
|
+
const updatedEntry = update(config, entry);
|
|
68
61
|
updated.push(updatedEntry);
|
|
69
62
|
return updatedEntry;
|
|
70
63
|
}
|
package/dist/db/memory.d.ts
CHANGED
|
@@ -4,6 +4,7 @@ import { Data } from "../types/data.js";
|
|
|
4
4
|
import { ValtheraClass } from "./valthera.js";
|
|
5
5
|
export declare class MemoryAction extends CustomActionsBase {
|
|
6
6
|
memory: Map<string, any[]>;
|
|
7
|
+
smartExecutor: boolean;
|
|
7
8
|
constructor();
|
|
8
9
|
_readMemory(key: string): any[];
|
|
9
10
|
_writeMemory(key: string, data: any[]): void;
|
package/dist/db/memory.js
CHANGED
|
@@ -4,6 +4,7 @@ import { forgeValthera } from "../helpers/forge.js";
|
|
|
4
4
|
import { ValtheraClass } from "./valthera.js";
|
|
5
5
|
export class MemoryAction extends CustomActionsBase {
|
|
6
6
|
memory;
|
|
7
|
+
smartExecutor = true;
|
|
7
8
|
constructor() {
|
|
8
9
|
super();
|
|
9
10
|
this.fileCpu = new CustomFileCpu(this._readMemory.bind(this), this._writeMemory.bind(this));
|
package/dist/db/valthera.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { VEE } from "@wxn0brp/event-emitter";
|
|
2
2
|
import { ActionsBase } from "../base/actions.js";
|
|
3
3
|
import { Collection } from "../helpers/collection.js";
|
|
4
|
-
import {
|
|
4
|
+
import { ExecutorInterface } from "../helpers/executor.js";
|
|
5
5
|
import { Data } from "../types/data.js";
|
|
6
6
|
import { DbOpts } from "../types/options.js";
|
|
7
|
-
import {
|
|
7
|
+
import { VQuery, VQueryT } from "../types/query.js";
|
|
8
8
|
import { ValtheraCompatible } from "../types/valthera.js";
|
|
9
9
|
/**
|
|
10
10
|
* Represents a database management class for performing CRUD operations.
|
|
@@ -12,7 +12,7 @@ import { ValtheraCompatible } from "../types/valthera.js";
|
|
|
12
12
|
*/
|
|
13
13
|
export declare class ValtheraClass implements ValtheraCompatible {
|
|
14
14
|
dbAction: ActionsBase;
|
|
15
|
-
executor:
|
|
15
|
+
executor: ExecutorInterface;
|
|
16
16
|
emiter: VEE<{
|
|
17
17
|
[K in keyof ValtheraCompatible]: (query: VQuery, result: Awaited<ReturnType<ValtheraCompatible[K]>>) => void;
|
|
18
18
|
} & {
|
|
@@ -20,7 +20,7 @@ export declare class ValtheraClass implements ValtheraCompatible {
|
|
|
20
20
|
}>;
|
|
21
21
|
version: string;
|
|
22
22
|
constructor(options: DbOpts);
|
|
23
|
-
init(...args: any[]): Promise<
|
|
23
|
+
init(...args: any[]): Promise<any>;
|
|
24
24
|
execute<T>(name: keyof ValtheraCompatible, query: VQuery<any> | string): Promise<T>;
|
|
25
25
|
/**
|
|
26
26
|
* Create a new instance of a Collection class.
|
package/dist/db/valthera.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VEE } from "@wxn0brp/event-emitter";
|
|
2
2
|
import { Collection } from "../helpers/collection.js";
|
|
3
|
-
import { Executor } from "../helpers/executor.js";
|
|
3
|
+
import { Executor, SmartExecutor } from "../helpers/executor.js";
|
|
4
4
|
import { version } from "../version.js";
|
|
5
5
|
/**
|
|
6
6
|
* Represents a database management class for performing CRUD operations.
|
|
@@ -13,7 +13,7 @@ export class ValtheraClass {
|
|
|
13
13
|
version = version;
|
|
14
14
|
constructor(options) {
|
|
15
15
|
this.dbAction = options.dbAction;
|
|
16
|
-
this.executor = options.executor || new Executor();
|
|
16
|
+
this.executor = options.executor || new (this.dbAction.smartExecutor ? SmartExecutor : Executor)();
|
|
17
17
|
if (options.numberId)
|
|
18
18
|
this.dbAction.numberId = true;
|
|
19
19
|
}
|
|
@@ -30,7 +30,7 @@ export class ValtheraClass {
|
|
|
30
30
|
}
|
|
31
31
|
async execute(name, query) {
|
|
32
32
|
await this.init();
|
|
33
|
-
const result = await this.executor.addOp(this.dbAction[name].bind(this.dbAction), query);
|
|
33
|
+
const result = await this.executor.addOp(this.dbAction[name].bind(this.dbAction), query, typeof query === "string" ? query : query.collection);
|
|
34
34
|
this.emiter.emit(name, query, result);
|
|
35
35
|
return result;
|
|
36
36
|
}
|
|
@@ -4,18 +4,35 @@ export interface Task {
|
|
|
4
4
|
resolve: Function;
|
|
5
5
|
reject: Function;
|
|
6
6
|
}
|
|
7
|
+
export interface ExecutorInterface {
|
|
8
|
+
addOp(func: Function, query?: any, collection?: string): Promise<any>;
|
|
9
|
+
}
|
|
10
|
+
export interface SmartExecutorEntry {
|
|
11
|
+
executor: Executor;
|
|
12
|
+
interval: ReturnType<typeof setTimeout> | null;
|
|
13
|
+
}
|
|
7
14
|
/**
|
|
8
15
|
* A simple executor for queuing and executing asynchronous operations sequentially.
|
|
9
16
|
*/
|
|
10
|
-
export declare class Executor {
|
|
11
|
-
|
|
17
|
+
export declare class Executor implements ExecutorInterface {
|
|
18
|
+
queue: Task[];
|
|
12
19
|
isExecuting: boolean;
|
|
13
20
|
/**
|
|
14
21
|
* Add an asynchronous operation to the execution queue.
|
|
15
22
|
*/
|
|
16
|
-
addOp(func: Function,
|
|
23
|
+
addOp(func: Function, query: any): Promise<any>;
|
|
17
24
|
/**
|
|
18
25
|
* Execute the queued asynchronous operations sequentially.
|
|
19
26
|
*/
|
|
20
27
|
execute(): Promise<void>;
|
|
21
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* A smart executor for queuing and executing asynchronous operations with a TTL.
|
|
31
|
+
*/
|
|
32
|
+
export declare class SmartExecutor implements ExecutorInterface {
|
|
33
|
+
ttl: number;
|
|
34
|
+
collections: Map<string, SmartExecutorEntry>;
|
|
35
|
+
constructor(ttl?: number);
|
|
36
|
+
addOp(func: Function, query: any, collection: string): Promise<any>;
|
|
37
|
+
scheduleCleanup(key: string, entry: SmartExecutorEntry): number;
|
|
38
|
+
}
|
package/dist/helpers/executor.js
CHANGED
|
@@ -2,16 +2,16 @@
|
|
|
2
2
|
* A simple executor for queuing and executing asynchronous operations sequentially.
|
|
3
3
|
*/
|
|
4
4
|
export class Executor {
|
|
5
|
-
|
|
5
|
+
queue = [];
|
|
6
6
|
isExecuting = false;
|
|
7
7
|
/**
|
|
8
8
|
* Add an asynchronous operation to the execution queue.
|
|
9
9
|
*/
|
|
10
|
-
async addOp(func,
|
|
10
|
+
async addOp(func, query) {
|
|
11
11
|
return await new Promise((resolve, reject) => {
|
|
12
|
-
this.
|
|
12
|
+
this.queue.push({
|
|
13
13
|
func,
|
|
14
|
-
param,
|
|
14
|
+
param: [query],
|
|
15
15
|
resolve,
|
|
16
16
|
reject
|
|
17
17
|
});
|
|
@@ -25,11 +25,52 @@ export class Executor {
|
|
|
25
25
|
if (this.isExecuting)
|
|
26
26
|
return;
|
|
27
27
|
this.isExecuting = true;
|
|
28
|
-
while (this.
|
|
29
|
-
let q = this.
|
|
28
|
+
while (this.queue.length > 0) {
|
|
29
|
+
let q = this.queue.shift();
|
|
30
30
|
let res = await q.func(...q.param);
|
|
31
31
|
q.resolve(res);
|
|
32
32
|
}
|
|
33
33
|
this.isExecuting = false;
|
|
34
34
|
}
|
|
35
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* A smart executor for queuing and executing asynchronous operations with a TTL.
|
|
38
|
+
*/
|
|
39
|
+
export class SmartExecutor {
|
|
40
|
+
ttl;
|
|
41
|
+
collections = new Map();
|
|
42
|
+
constructor(ttl = 5 * 60 * 1000) {
|
|
43
|
+
this.ttl = ttl;
|
|
44
|
+
}
|
|
45
|
+
async addOp(func, query, collection) {
|
|
46
|
+
const key = collection ?? "__default__";
|
|
47
|
+
let entry = this.collections.get(key);
|
|
48
|
+
if (!entry) {
|
|
49
|
+
entry = {
|
|
50
|
+
executor: new Executor(),
|
|
51
|
+
interval: null
|
|
52
|
+
};
|
|
53
|
+
this.collections.set(key, entry);
|
|
54
|
+
}
|
|
55
|
+
else if (entry.interval)
|
|
56
|
+
clearTimeout(entry.interval);
|
|
57
|
+
entry.interval = this.scheduleCleanup(key, entry);
|
|
58
|
+
return entry.executor.addOp(func, query);
|
|
59
|
+
}
|
|
60
|
+
scheduleCleanup(key, entry) {
|
|
61
|
+
const interval = setTimeout(() => {
|
|
62
|
+
const current = this.collections.get(key);
|
|
63
|
+
if (!current || current !== entry)
|
|
64
|
+
return;
|
|
65
|
+
if (current.executor.isExecuting) {
|
|
66
|
+
current.interval = this.scheduleCleanup(key, current);
|
|
67
|
+
}
|
|
68
|
+
else {
|
|
69
|
+
this.collections.delete(key);
|
|
70
|
+
}
|
|
71
|
+
}, this.ttl);
|
|
72
|
+
if (typeof interval === "object" && "unref" in interval)
|
|
73
|
+
interval.unref();
|
|
74
|
+
return interval;
|
|
75
|
+
}
|
|
76
|
+
}
|
package/dist/types/arg.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { Data } from "./data.js";
|
|
1
2
|
import { SearchOptions } from "./searchOpts.js";
|
|
2
3
|
import { VContext } from "./types.js";
|
|
3
4
|
import { UpdaterArg } from "./updater.js";
|
|
@@ -5,6 +6,6 @@ export type Arg<T = any> = {
|
|
|
5
6
|
[K in keyof T]?: any;
|
|
6
7
|
} & Record<string, any>;
|
|
7
8
|
export type SearchFunc<T = any> = (data: T, context: VContext) => boolean;
|
|
8
|
-
export type UpdaterFunc<T = any> = (data: T, context: VContext) =>
|
|
9
|
+
export type UpdaterFunc<T = any> = (data: T, context: VContext) => Data | void;
|
|
9
10
|
export type Search<T = any> = SearchOptions<T> | SearchFunc<T>;
|
|
10
|
-
export type Updater<T = any> = UpdaterArg<T> |
|
|
11
|
+
export type Updater<T = any> = UpdaterArg<T> | UpdaterFunc<T>;
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { Data } from "../types/data.js";
|
|
2
|
+
import { VQuery, VQueryT } from "../types/query.js";
|
|
3
|
+
export declare function findProcessLine(config: VQueryT.Find | VQueryT.FindOne, obj: Data): Object;
|
|
4
|
+
export declare function match(config: VQuery, obj: Data): boolean;
|
|
5
|
+
export declare function update(config: VQueryT.Update, obj: Data): Data;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { hasFieldsAdvanced } from "./hasFieldsAdvanced.js";
|
|
2
|
+
import { updateFindObject } from "./updateFindObject.js";
|
|
3
|
+
import { updateObjectAdvanced } from "./updateObject.js";
|
|
4
|
+
export function findProcessLine(config, obj) {
|
|
5
|
+
if (match(config, obj))
|
|
6
|
+
return updateFindObject(obj, config.findOpts || {});
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
export function match(config, obj) {
|
|
10
|
+
const { search, context } = config;
|
|
11
|
+
if (search === undefined || search === null)
|
|
12
|
+
return true;
|
|
13
|
+
if (typeof search === "function" && search(obj, context))
|
|
14
|
+
return true;
|
|
15
|
+
if (typeof search === "object" && !Array.isArray(search) && hasFieldsAdvanced(obj, search))
|
|
16
|
+
return true;
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
export function update(config, obj) {
|
|
20
|
+
const { updater, context } = config;
|
|
21
|
+
if (typeof updater === "object" && !Array.isArray(updater))
|
|
22
|
+
return updateObjectAdvanced(obj, updater);
|
|
23
|
+
if (typeof updater === "function") {
|
|
24
|
+
const updateObjValue = updater(obj, context);
|
|
25
|
+
if (updateObjValue)
|
|
26
|
+
return updateObjValue;
|
|
27
|
+
return obj;
|
|
28
|
+
}
|
|
29
|
+
return obj;
|
|
30
|
+
}
|
|
@@ -5,12 +5,10 @@ import { _deepMerge } from "./merge.js";
|
|
|
5
5
|
* @param field - An object containing new values to update in the target object.
|
|
6
6
|
*/
|
|
7
7
|
export function updateObjectAdvanced(obj, field) {
|
|
8
|
-
if (typeof field !== "object" || field === null)
|
|
9
|
-
throw new Error("Fields must be an object
|
|
10
|
-
|
|
11
|
-
if (Object.keys(field).length === 0) {
|
|
8
|
+
if (typeof field !== "object" || Array.isArray(field) || field === null)
|
|
9
|
+
throw new Error("Fields must be an object");
|
|
10
|
+
if (Object.keys(field).length === 0)
|
|
12
11
|
return obj;
|
|
13
|
-
}
|
|
14
12
|
const newObj = structuredClone(obj);
|
|
15
13
|
const $fields = {};
|
|
16
14
|
const subsetFields = {};
|
|
@@ -106,11 +104,9 @@ function mainUpdate(obj, fields) {
|
|
|
106
104
|
* @param newVal - An object containing new values to update in the target object.
|
|
107
105
|
*/
|
|
108
106
|
function updateObject(obj, newVal) {
|
|
109
|
-
for (let key in newVal)
|
|
110
|
-
if (newVal.hasOwnProperty(key))
|
|
107
|
+
for (let key in newVal)
|
|
108
|
+
if (newVal.hasOwnProperty(key))
|
|
111
109
|
obj[key] = newVal[key];
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
110
|
return obj;
|
|
115
111
|
}
|
|
116
112
|
function _for(fields, obj, opts) {
|
package/dist/version.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = "0.11.0-alpha.
|
|
1
|
+
export const version = "0.11.0-alpha.2";
|