jopi-toolkit 3.1.25 → 3.1.34
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/jk_app/common.d.ts +1 -0
- package/dist/jk_app/common.js +9 -2
- package/dist/jk_app/common.js.map +1 -1
- package/dist/jk_data/browserActions.d.ts +8 -0
- package/dist/jk_data/browserActions.js +9 -0
- package/dist/jk_data/browserActions.js.map +1 -0
- package/dist/jk_data/bundler_ifServer.d.ts +2 -0
- package/dist/jk_data/bundler_ifServer.js +2 -0
- package/dist/jk_data/bundler_ifServer.js.map +1 -0
- package/dist/jk_data/common.d.ts +8 -0
- package/dist/jk_data/common.js +2 -0
- package/dist/jk_data/common.js.map +1 -0
- package/dist/jk_data/core.d.ts +13 -0
- package/dist/jk_data/core.js +85 -0
- package/dist/jk_data/core.js.map +1 -0
- package/dist/jk_data/dataTableProxy.d.ts +21 -0
- package/dist/jk_data/dataTableProxy.js +49 -0
- package/dist/jk_data/dataTableProxy.js.map +1 -0
- package/dist/jk_data/ifServerSide.d.ts +0 -0
- package/dist/jk_data/ifServerSide.js +2 -0
- package/dist/jk_data/ifServerSide.js.map +1 -0
- package/dist/jk_data/index.d.ts +3 -55
- package/dist/jk_data/index.js +3 -105
- package/dist/jk_data/index.js.map +1 -1
- package/dist/jk_data/interfaces.d.ts +107 -0
- package/dist/jk_data/interfaces.js +2 -0
- package/dist/jk_data/interfaces.js.map +1 -0
- package/dist/jk_data/jBundler_common.d.ts +12 -0
- package/dist/jk_data/jBundler_common.js +2 -0
- package/dist/jk_data/jBundler_common.js.map +1 -0
- package/dist/jk_data/jBundler_ifBrowser.d.ts +2 -0
- package/dist/jk_data/jBundler_ifBrowser.js +2 -0
- package/dist/jk_data/jBundler_ifBrowser.js.map +1 -0
- package/dist/jk_data/jBundler_ifServer.1.d.ts +2 -0
- package/dist/jk_data/jBundler_ifServer.1.js +2 -0
- package/dist/jk_data/jBundler_ifServer.1.js.map +1 -0
- package/dist/jk_data/jBundler_ifServer.d.ts +2 -0
- package/dist/jk_data/jBundler_ifServer.js +2 -0
- package/dist/jk_data/jBundler_ifServer.js.map +1 -0
- package/dist/jk_data/proxy.d.ts +24 -0
- package/dist/jk_data/proxy.js +82 -0
- package/dist/jk_data/proxy.js.map +1 -0
- package/dist/jk_fs/jBundler_ifServer.d.ts +2 -1
- package/dist/jk_fs/jBundler_ifServer.js +1 -0
- package/dist/jk_fs/jBundler_ifServer.js.map +1 -1
- package/dist/jk_logs/index.js +2 -2
- package/dist/jk_logs/index.js.map +1 -1
- package/dist/jk_memcache/_logs.d.ts +1 -0
- package/dist/jk_memcache/_logs.js +3 -0
- package/dist/jk_memcache/_logs.js.map +1 -0
- package/dist/jk_memcache/index.d.ts +128 -0
- package/dist/jk_memcache/index.js +411 -0
- package/dist/jk_memcache/index.js.map +1 -0
- package/dist/jk_schemas/index.d.ts +20 -16
- package/dist/jk_schemas/index.js +13 -15
- package/dist/jk_schemas/index.js.map +1 -1
- package/dist/jk_tools/common.d.ts +6 -0
- package/dist/jk_tools/common.js +6 -0
- package/dist/jk_tools/common.js.map +1 -1
- package/dist/jk_tools/index.d.ts +1 -0
- package/package.json +8 -4
- package/src/jk_app/common.ts +12 -2
- package/src/jk_data/core.ts +92 -0
- package/src/jk_data/index.ts +3 -166
- package/src/jk_data/interfaces.ts +140 -0
- package/src/jk_data/proxy.ts +102 -0
- package/src/jk_fs/jBundler_ifServer.ts +1 -0
- package/src/jk_logs/index.ts +2 -2
- package/src/jk_memcache/README.md +66 -0
- package/src/jk_memcache/_logs.ts +3 -0
- package/src/jk_memcache/index.ts +494 -0
- package/src/jk_schemas/index.ts +29 -27
- package/src/jk_tools/common.ts +6 -0
- package/src/jk_tools/index.ts +3 -1
- package/src/jk_compress/index.js +0 -1
- package/src/jk_compress/jBundler_ifServer.js +0 -10
- package/src/jk_data/index.js +0 -155
- package/src/jk_schemas/index.js +0 -330
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/jk_tools/common.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/jk_tools/common.ts"],"names":[],"mappings":"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"}
|
package/dist/jk_tools/index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "3.1.
|
|
2
|
+
"version": "3.1.34",
|
|
3
3
|
"name": "jopi-toolkit",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"homepage": "https://github.com/johanpiquet/jopi-toolkit",
|
|
@@ -18,7 +18,6 @@
|
|
|
18
18
|
],
|
|
19
19
|
"scripts": {
|
|
20
20
|
"jopiLink": "npx jopi-mono link-add",
|
|
21
|
-
"bunLink": "bun link",
|
|
22
21
|
"dev:build": "tsc",
|
|
23
22
|
"dev:tsc-watch": "tsc --watch",
|
|
24
23
|
"dev:tsc-check": "tsc --noEmit"
|
|
@@ -33,8 +32,8 @@
|
|
|
33
32
|
"mime-types": "^3.0.1",
|
|
34
33
|
"ws": "^8.18.3"
|
|
35
34
|
},
|
|
36
|
-
"publishedDate": "1/
|
|
37
|
-
"publicPublishedDate": "1/
|
|
35
|
+
"publishedDate": "1/29/2026",
|
|
36
|
+
"publicPublishedDate": "1/29/2026",
|
|
38
37
|
"exports": {
|
|
39
38
|
"./jk_schema": {
|
|
40
39
|
"types": "./src/jk_schemas/index.ts",
|
|
@@ -115,6 +114,11 @@
|
|
|
115
114
|
"types": "./src/jk_logs/index.ts",
|
|
116
115
|
"bun": "./src/jk_logs/index.ts",
|
|
117
116
|
"default": "./dist/jk_logs/index.js"
|
|
117
|
+
},
|
|
118
|
+
"./jk_memcache": {
|
|
119
|
+
"types": "./src/jk_memcache/index.ts",
|
|
120
|
+
"bun": "./src/jk_memcache/index.ts",
|
|
121
|
+
"default": "./dist/jk_memcache/index.js"
|
|
118
122
|
}
|
|
119
123
|
}
|
|
120
124
|
}
|
package/src/jk_app/common.ts
CHANGED
|
@@ -291,12 +291,22 @@ export function getCompiledCodeDir(): string {
|
|
|
291
291
|
return rootDir;
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
export function toSourceCodeDir(itemPath: string): string {
|
|
295
|
+
const compiledDir = getCompiledCodeDir();
|
|
296
|
+
|
|
297
|
+
if (itemPath.startsWith(compiledDir)) {
|
|
298
|
+
return getSourceCodeDir() + itemPath.substring(compiledDir.length);
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return itemPath;
|
|
302
|
+
}
|
|
303
|
+
|
|
294
304
|
export function getCompiledFilePathFor(sourceFilePath: string, replaceExtension = true): string {
|
|
295
305
|
const compiledCodeDir = getCompiledCodeDir();
|
|
296
306
|
const sourceCodeDir = getSourceCodeDir();
|
|
297
307
|
|
|
298
308
|
if (!sourceFilePath.startsWith(sourceCodeDir)) {
|
|
299
|
-
|
|
309
|
+
return sourceFilePath;
|
|
300
310
|
}
|
|
301
311
|
|
|
302
312
|
let filePath = sourceFilePath.substring(sourceCodeDir.length);
|
|
@@ -321,7 +331,7 @@ export function getSourcesCodePathFor(compiledFilePath: string): string {
|
|
|
321
331
|
const sourceCodeDir = getSourceCodeDir();
|
|
322
332
|
|
|
323
333
|
if (!compiledFilePath.startsWith(compiledCodeDir)) {
|
|
324
|
-
|
|
334
|
+
return compiledCodeDir;
|
|
325
335
|
}
|
|
326
336
|
|
|
327
337
|
let filePath = jk_fs.join(sourceCodeDir, compiledFilePath.substring(compiledCodeDir.length));
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import {type Schema} from "jopi-toolkit/jk_schema";
|
|
2
|
+
import type { JopiDataTable, JDataReadParams, JDataReadResult, JRowArrayFilter } from "./interfaces.ts";
|
|
3
|
+
export * from "./interfaces.ts";
|
|
4
|
+
|
|
5
|
+
//region Rows Arrays
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Filter the row content according to rules.
|
|
9
|
+
*/
|
|
10
|
+
export function simpleRowArrayFilter(rows: any[], params: JRowArrayFilter): JDataReadResult {
|
|
11
|
+
// > Apply filter.
|
|
12
|
+
|
|
13
|
+
if (params.filter) {
|
|
14
|
+
const f = params.filter;
|
|
15
|
+
|
|
16
|
+
rows = rows.filter(r => {
|
|
17
|
+
if (f.field) {
|
|
18
|
+
let v = r[f.field];
|
|
19
|
+
if (v===undefined) return false;
|
|
20
|
+
return String(v).includes(f.value);
|
|
21
|
+
} else {
|
|
22
|
+
for (let v of Object.values(r)) {
|
|
23
|
+
if (v===undefined) continue;
|
|
24
|
+
if (String(v).includes(f.value)) return true;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// > Apply sorting.
|
|
33
|
+
|
|
34
|
+
if (params.sorting && params.sorting.length) {
|
|
35
|
+
const sorting = params.sorting[0];
|
|
36
|
+
const sortField = sorting.id;
|
|
37
|
+
const sortDesc = sorting.desc;
|
|
38
|
+
|
|
39
|
+
rows = rows.sort((a, b) => {
|
|
40
|
+
let av = a[sortField];
|
|
41
|
+
let bv = b[sortField];
|
|
42
|
+
|
|
43
|
+
if (av === undefined) av = "";
|
|
44
|
+
if (bv === undefined) bv = "";
|
|
45
|
+
|
|
46
|
+
const avIsNumber = typeof av === "number";
|
|
47
|
+
const bvIsNumber = typeof bv === "number";
|
|
48
|
+
|
|
49
|
+
if (avIsNumber && bvIsNumber) {
|
|
50
|
+
if (sortDesc) {
|
|
51
|
+
return bv - av;
|
|
52
|
+
} else {
|
|
53
|
+
return av - bv;
|
|
54
|
+
}
|
|
55
|
+
} else {
|
|
56
|
+
const avStr = String(av);
|
|
57
|
+
const bvStr = String(bv);
|
|
58
|
+
|
|
59
|
+
if (sortDesc) {
|
|
60
|
+
return bvStr.localeCompare(avStr);
|
|
61
|
+
} else {
|
|
62
|
+
return avStr.localeCompare(bvStr);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const totalWithoutPagination = rows.length;
|
|
69
|
+
let offset = 0;
|
|
70
|
+
|
|
71
|
+
if (params.page) {
|
|
72
|
+
offset = params.page.pageIndex * params.page.pageSize;
|
|
73
|
+
rows = rows.slice(offset, offset + params.page.pageSize);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return {rows, total: totalWithoutPagination, offset};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
//endregion
|
|
80
|
+
|
|
81
|
+
//region JDataBinding
|
|
82
|
+
|
|
83
|
+
export class JDataBinding_UseArray implements JopiDataTable {
|
|
84
|
+
public constructor(public readonly schema: Schema, private readonly rows: any[]) {
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
async read(params: JDataReadParams): Promise<JDataReadResult> {
|
|
88
|
+
return simpleRowArrayFilter(this.rows, params);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
//endregion
|
package/src/jk_data/index.ts
CHANGED
|
@@ -1,166 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export interface JFieldSorting {
|
|
6
|
-
id: string;
|
|
7
|
-
desc: boolean;
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
export interface JFieldFilter {
|
|
11
|
-
value?: string | number | boolean;
|
|
12
|
-
constraint: JFieldConstraintType;
|
|
13
|
-
caseSensitive?: boolean;
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export type JFieldConstraintType =
|
|
17
|
-
| "$eq" // Equals
|
|
18
|
-
| "$ne" // Not equals
|
|
19
|
-
| "$gt" // Greater than
|
|
20
|
-
| "$gte" // Greater than or equals
|
|
21
|
-
| "$lt" // Less than
|
|
22
|
-
| "$lte" // Less than or equals
|
|
23
|
-
| "$in" // In an array of values
|
|
24
|
-
| "$nin" // Not in an array of values
|
|
25
|
-
| "$like" // Like search %endsWith or startsWith%
|
|
26
|
-
|
|
27
|
-
export interface JRowsFilter {
|
|
28
|
-
field?: string;
|
|
29
|
-
value: string;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
export interface JPageExtraction {
|
|
33
|
-
pageIndex: number;
|
|
34
|
-
pageSize: number;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface JRowArrayFilter {
|
|
38
|
-
page?: JPageExtraction;
|
|
39
|
-
filter?: JRowsFilter;
|
|
40
|
-
sorting?: JFieldSorting[];
|
|
41
|
-
fieldFilters?: Record<string, JFieldFilter[]>;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Filter the row content according to rules.
|
|
46
|
-
*/
|
|
47
|
-
export function simpleRowArrayFilter(rows: any[], params: JRowArrayFilter): JTableDs_ReadResult {
|
|
48
|
-
// > Apply filter.
|
|
49
|
-
|
|
50
|
-
if (params.filter) {
|
|
51
|
-
const f = params.filter;
|
|
52
|
-
|
|
53
|
-
rows = rows.filter(r => {
|
|
54
|
-
if (f.field) {
|
|
55
|
-
let v = r[f.field];
|
|
56
|
-
if (v===undefined) return false;
|
|
57
|
-
return String(v).includes(f.value);
|
|
58
|
-
} else {
|
|
59
|
-
for (let v of Object.values(r)) {
|
|
60
|
-
if (v===undefined) continue;
|
|
61
|
-
if (String(v).includes(f.value)) return true;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// > Apply sorting.
|
|
70
|
-
|
|
71
|
-
if (params.sorting && params.sorting.length) {
|
|
72
|
-
const sorting = params.sorting[0];
|
|
73
|
-
const sortField = sorting.id;
|
|
74
|
-
const sortDesc = sorting.desc;
|
|
75
|
-
|
|
76
|
-
rows = rows.sort((a, b) => {
|
|
77
|
-
let av = a[sortField];
|
|
78
|
-
let bv = b[sortField];
|
|
79
|
-
|
|
80
|
-
if (av === undefined) av = "";
|
|
81
|
-
if (bv === undefined) bv = "";
|
|
82
|
-
|
|
83
|
-
const avIsNumber = typeof av === "number";
|
|
84
|
-
const bvIsNumber = typeof bv === "number";
|
|
85
|
-
|
|
86
|
-
if (avIsNumber && bvIsNumber) {
|
|
87
|
-
if (sortDesc) {
|
|
88
|
-
return bv - av;
|
|
89
|
-
} else {
|
|
90
|
-
return av - bv;
|
|
91
|
-
}
|
|
92
|
-
} else {
|
|
93
|
-
const avStr = String(av);
|
|
94
|
-
const bvStr = String(bv);
|
|
95
|
-
|
|
96
|
-
if (sortDesc) {
|
|
97
|
-
return bvStr.localeCompare(avStr);
|
|
98
|
-
} else {
|
|
99
|
-
return avStr.localeCompare(bvStr);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
const totalWithoutPagination = rows.length;
|
|
106
|
-
let offset = 0;
|
|
107
|
-
|
|
108
|
-
if (params.page) {
|
|
109
|
-
offset = params.page.pageIndex * params.page.pageSize;
|
|
110
|
-
rows = rows.slice(offset, offset + params.page.pageSize);
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
return {rows, total: totalWithoutPagination, offset};
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
//endregion
|
|
117
|
-
|
|
118
|
-
//region JTableDs
|
|
119
|
-
|
|
120
|
-
export interface JTableDs_ReadParams extends JRowArrayFilter {
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
export interface JTableDs_ReadResult {
|
|
124
|
-
rows: any[];
|
|
125
|
-
total?: number;
|
|
126
|
-
offset?: number;
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export interface JTableDs {
|
|
130
|
-
get name(): string;
|
|
131
|
-
get schema(): Schema;
|
|
132
|
-
read(params: JTableDs_ReadParams): Promise<JTableDs_ReadResult>;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
export class JTableDs_UseArray implements JTableDs {
|
|
136
|
-
public constructor(public readonly name: string, public readonly schema: Schema, private readonly rows: any[]) {
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
async read(params: JTableDs_ReadParams): Promise<JTableDs_ReadResult> {
|
|
140
|
-
return simpleRowArrayFilter(this.rows, params);
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
export class JTableDs_HttpProxy implements JTableDs {
|
|
145
|
-
public constructor(public readonly name: string, private readonly url: string, public readonly schema: Schema) {
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
async read(params: JTableDs_ReadParams): Promise<JTableDs_ReadResult> {
|
|
149
|
-
let toSend = {dsName: this.name, read: params};
|
|
150
|
-
|
|
151
|
-
let res = await fetch(this.url, {
|
|
152
|
-
method: "POST",
|
|
153
|
-
headers: {"Content-Type": "application/json"},
|
|
154
|
-
body: JSON.stringify(toSend)
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
if (res.status !== 200) {
|
|
158
|
-
throw new Error(`Error while reading data source "${this.name}"`);
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
let asJson = await res.json();
|
|
162
|
-
return asJson as JTableDs_ReadResult;
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
//endregion
|
|
1
|
+
export * from "./core.ts";
|
|
2
|
+
export * from "./proxy.ts";
|
|
3
|
+
export * from "./interfaces.ts";
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { type Schema } from "jopi-toolkit/jk_schema";
|
|
2
|
+
import type {Translatable} from "../jk_tools";
|
|
3
|
+
|
|
4
|
+
export interface JFieldSorting {
|
|
5
|
+
id: string;
|
|
6
|
+
desc: boolean;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface IActionContext {
|
|
10
|
+
refresh: () => void;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface JFieldFilter {
|
|
14
|
+
value?: string | number | boolean;
|
|
15
|
+
constraint: JFieldConstraintType;
|
|
16
|
+
caseSensitive?: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type JFieldConstraintType =
|
|
20
|
+
| "$eq" // Equals
|
|
21
|
+
| "$ne" // Not equals
|
|
22
|
+
| "$gt" // Greater than
|
|
23
|
+
| "$gte" // Greater than or equals
|
|
24
|
+
| "$lt" // Less than
|
|
25
|
+
| "$lte" // Less than or equals
|
|
26
|
+
| "$in" // In an array of values
|
|
27
|
+
| "$nin" // Not in an array of values
|
|
28
|
+
| "$like" // Like search %endsWith or startsWith%
|
|
29
|
+
;
|
|
30
|
+
|
|
31
|
+
export interface JGlobalFilter {
|
|
32
|
+
field?: string;
|
|
33
|
+
value: string;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export interface JPageExtraction {
|
|
37
|
+
pageIndex: number;
|
|
38
|
+
pageSize: number;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export interface JRowArrayFilter {
|
|
42
|
+
page?: JPageExtraction;
|
|
43
|
+
filter?: JGlobalFilter;
|
|
44
|
+
sorting?: JFieldSorting[];
|
|
45
|
+
fieldFilters?: Record<string, JFieldFilter[]>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface JDataReadParams extends JRowArrayFilter {
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export interface JDataReadResult {
|
|
52
|
+
rows: any[];
|
|
53
|
+
total?: number;
|
|
54
|
+
offset?: number;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export interface JActionDef {
|
|
58
|
+
id: string;
|
|
59
|
+
title?: Translatable;
|
|
60
|
+
separator?: boolean;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export interface JopiDataTable {
|
|
64
|
+
readonly schema: Schema;
|
|
65
|
+
readonly actions?: JActionDef[];
|
|
66
|
+
read(params: JDataReadParams): Promise<JDataReadResult>;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface JDataTable extends JopiDataTable {
|
|
70
|
+
readonly name: string;
|
|
71
|
+
executeAction?: (rows: any[], actionName: string, context?: IActionContext) => Promise<JActionResult | void>
|
|
72
|
+
isActionEnabled?: (actionName: string, rows: any[], context?: IActionContext) => boolean;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export interface JActionPreProcessParams {
|
|
76
|
+
rows: any[];
|
|
77
|
+
context?: IActionContext;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
export interface JActionResult {
|
|
81
|
+
isOk?: boolean;
|
|
82
|
+
errorCode?: string;
|
|
83
|
+
errorMessage?: string;
|
|
84
|
+
userMessage?: string;
|
|
85
|
+
data?: any;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export interface JActionPreProcessResult extends JActionResult {
|
|
89
|
+
rows?: any[];
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export interface JActionPostProcessParams {
|
|
93
|
+
rows: any[];
|
|
94
|
+
context?: IActionContext;
|
|
95
|
+
|
|
96
|
+
data?: any[];
|
|
97
|
+
userMessage?: string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Defines the behavior of a custom action in the browser for a Jopi table.
|
|
102
|
+
* allowing to hook into the action lifecycle (pre-process, server call, post-process).
|
|
103
|
+
*/
|
|
104
|
+
export interface JopiTableBrowserActionItem {
|
|
105
|
+
/**
|
|
106
|
+
* Callback invoked when an error occurs during the action execution.
|
|
107
|
+
* This can be triggered by a failure in the `action` handler or a server-side error.
|
|
108
|
+
*/
|
|
109
|
+
onError?: (params: JActionResult) => Promise<void>,
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* The main client-side action handler.
|
|
113
|
+
* - Can be used to perform checks or data transformation before sending to the server.
|
|
114
|
+
* - Can be used as a standalone action if `disableServerCall` is true.
|
|
115
|
+
* - Return `void` to proceed with the default flow.
|
|
116
|
+
* - Return a `JActionPreProcessResult` to control flow (e.g., stop execution if `isOk` is false) or modify data sent to server.
|
|
117
|
+
*/
|
|
118
|
+
action?: (params: JActionPreProcessParams) => Promise<JActionPreProcessResult|void>,
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Callback invoked after the server-side action has successfully completed.
|
|
122
|
+
* Useful for showing notifications, refreshing data, or triggering other UI updates.
|
|
123
|
+
*/
|
|
124
|
+
afterServerCall?: (params: JActionPostProcessParams) => Promise<void>;
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Function to determine if the action should be enabled/clickable.
|
|
128
|
+
* Based on the currently selected rows and the current action context.
|
|
129
|
+
* If not provided, the action is assumed to be always enabled.
|
|
130
|
+
*/
|
|
131
|
+
canEnable?: (rows: any[], context?: IActionContext) => boolean;
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* If set to true, the framework will NOT assume there is a corresponding server-side action to call.
|
|
135
|
+
* Use this for actions that are purely client-side (e.g., "Copy to clipboard").
|
|
136
|
+
*/
|
|
137
|
+
disableServerCall?: boolean;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export type JopiTableBrowserActions = Record<string, JopiTableBrowserActionItem>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import type { IActionContext, JopiTableBrowserActions, JDataReadParams, JDataReadResult, JDataTable, JActionDef, JActionResult } from "./interfaces.ts";
|
|
2
|
+
import { schema, type Schema } from "jopi-toolkit/jk_schema";
|
|
3
|
+
|
|
4
|
+
export interface ProxyParams {
|
|
5
|
+
name: string;
|
|
6
|
+
apiUrl: string;
|
|
7
|
+
actions?: JActionDef[];
|
|
8
|
+
schema: { meta: any; desc: any; };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class Proxy implements JDataTable {
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly schema: Schema;
|
|
14
|
+
readonly actions?: JActionDef[];
|
|
15
|
+
private readonly url: string;
|
|
16
|
+
|
|
17
|
+
readonly browserActions: JopiTableBrowserActions;
|
|
18
|
+
|
|
19
|
+
constructor(params: ProxyParams, browserActions: JopiTableBrowserActions) {
|
|
20
|
+
this.name = params.name;
|
|
21
|
+
this.url = params.apiUrl;
|
|
22
|
+
this.actions = params.actions;
|
|
23
|
+
this.schema = schema(params.schema.desc, params.schema.meta);
|
|
24
|
+
this.browserActions = browserActions;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
async read(params: JDataReadParams): Promise<JDataReadResult> {
|
|
28
|
+
const asJson = await this.callServer({ dsName: this.name, read: params });
|
|
29
|
+
return asJson as JDataReadResult;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
isActionEnabled(actionName: string, rows: any[], context?: IActionContext): boolean {
|
|
33
|
+
let actionEntry = this.browserActions[actionName];
|
|
34
|
+
if (!actionEntry) return false;
|
|
35
|
+
if (!actionEntry.canEnable) return true;
|
|
36
|
+
return actionEntry.canEnable(rows, context);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async executeAction(rows: any[], actionName: string, context?: IActionContext): Promise<JActionResult|void> {
|
|
40
|
+
async function processError(res: JActionResult | undefined) {
|
|
41
|
+
if (!res) return true;
|
|
42
|
+
|
|
43
|
+
if (res.isOk===false||res.errorCode||res.errorMessage) {
|
|
44
|
+
if (actionEntry.onError) {
|
|
45
|
+
await actionEntry.onError(res);
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
return true;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
let actionEntry = this.browserActions[actionName];
|
|
54
|
+
if (!actionEntry) return;
|
|
55
|
+
|
|
56
|
+
if (actionEntry.action) {
|
|
57
|
+
let res = await actionEntry.action({ rows, context });
|
|
58
|
+
|
|
59
|
+
if (res) {
|
|
60
|
+
if (!processError(res)) return;
|
|
61
|
+
|
|
62
|
+
if (res.rows !== undefined) {
|
|
63
|
+
rows = res.rows;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
if (actionEntry.disableServerCall === true) {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let serverRes = await this.callServer({ action: actionName, rows });
|
|
73
|
+
if (!processError(serverRes)) return;
|
|
74
|
+
|
|
75
|
+
if (actionEntry.afterServerCall) {
|
|
76
|
+
await actionEntry.afterServerCall({
|
|
77
|
+
rows,
|
|
78
|
+
context,
|
|
79
|
+
data: serverRes?.data,
|
|
80
|
+
userMessage: serverRes?.userMessage
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
async callServer(data: any): Promise<any> {
|
|
86
|
+
let res = await fetch(this.url, {
|
|
87
|
+
method: "POST",
|
|
88
|
+
headers: {"Content-Type": "application/json"},
|
|
89
|
+
body: JSON.stringify(data)
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
if (res.status !== 200) {
|
|
93
|
+
throw new Error(`Error while calling data source "${this.name}"`);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return await res.json();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
export function toDataTableProxy(params: ProxyParams, browserActions?: JopiTableBrowserActions): JDataTable {
|
|
101
|
+
return new Proxy(params, browserActions || {});
|
|
102
|
+
}
|
|
@@ -516,6 +516,7 @@ export const join = path.join;
|
|
|
516
516
|
export const resolve = path.resolve;
|
|
517
517
|
export const dirname = path.dirname;
|
|
518
518
|
export const extname = path.extname;
|
|
519
|
+
export const relative = path.relative;
|
|
519
520
|
|
|
520
521
|
export const sep = path.sep;
|
|
521
522
|
export const isAbsolute = path.isAbsolute;
|
package/src/jk_logs/index.ts
CHANGED
|
@@ -51,7 +51,7 @@ export const formater_dateTypeTitleSourceData: LogEntryFormater = (entry: LogEnt
|
|
|
51
51
|
const date = formatDate1(entry.date);
|
|
52
52
|
|
|
53
53
|
let json = entry.data ? JSON.stringify(entry.data) : "";
|
|
54
|
-
const title = (entry.title || "").padEnd(50, " ");
|
|
54
|
+
const title = String(entry.title || "").padEnd(50, " ");
|
|
55
55
|
|
|
56
56
|
json = entry.logger + " |>" + json;
|
|
57
57
|
|
|
@@ -71,7 +71,7 @@ export const formater_dateTypeTitleSourceData: LogEntryFormater = (entry: LogEnt
|
|
|
71
71
|
|
|
72
72
|
export const formater_typeTitleSourceData_colored: LogEntryFormater = (entry: LogEntry) => {
|
|
73
73
|
let json = entry.data ? JSON.stringify(entry.data) : "";
|
|
74
|
-
const title = (entry.title || "").padEnd(50, " ");
|
|
74
|
+
const title = String(entry.title || "").padEnd(50, " ");
|
|
75
75
|
|
|
76
76
|
json = entry.timeDif === undefined
|
|
77
77
|
? `${entry.logger} ${json}` : `${entry.logger} (${entry.timeDif} ms) ${json}`;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
|
|
2
|
+
# JkMemCache (`jk_memcache`)
|
|
3
|
+
|
|
4
|
+
A robust, in-memory caching system, designed with optimization and memory management in mind.
|
|
5
|
+
|
|
6
|
+
## Features
|
|
7
|
+
|
|
8
|
+
- **Store Anything**: Supports `string`, `ArrayBuffer`, and `Object` (automatically serialized).
|
|
9
|
+
- **Memory Management**:
|
|
10
|
+
- **Memory Limit**: Define a maximum size in bytes.
|
|
11
|
+
- **Count Limit**: Define a maximum number of entries.
|
|
12
|
+
- **Garbage Collection (GC)**: Automatic cleanup of expired items and intelligent eviction when full.
|
|
13
|
+
- **Smart Eviction**:
|
|
14
|
+
- **Importance Levels**: Mark entries as critical to prevent them from being discarded easily.
|
|
15
|
+
- **Access Tracking**: Tracks how often items are used to prioritize keeping frequently accessed data.
|
|
16
|
+
- **Expiration**: Support for TTL (Time To Live) and absolute expiration dates.
|
|
17
|
+
|
|
18
|
+
## Usage
|
|
19
|
+
|
|
20
|
+
### basic
|
|
21
|
+
|
|
22
|
+
```typescript
|
|
23
|
+
import { JkMemCache } from '@jopi-toolkit/jk_memcache';
|
|
24
|
+
|
|
25
|
+
// Create a cache with limits
|
|
26
|
+
const cache = new JkMemCache({
|
|
27
|
+
maxCount: 1000, // Max 1000 items
|
|
28
|
+
maxSize: 5 * 1024 * 1024, // Max 5MB
|
|
29
|
+
cleanupInterval: 30000 // Cleanup every 30s
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
// Store data
|
|
33
|
+
cache.set('user:123', { name: 'John', role: 'admin' }, {
|
|
34
|
+
ttl: 60000, // Expires in 1 minute
|
|
35
|
+
importance: 5 // High importance (default is 1)
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// Retrieve data
|
|
39
|
+
const user = cache.get('user:123'); // { name: 'John', ... }
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
### Options
|
|
43
|
+
|
|
44
|
+
#### Constructor Options
|
|
45
|
+
|
|
46
|
+
| Option | Type | Default | Description |
|
|
47
|
+
|yyy|yyy|yyy|yyy|
|
|
48
|
+
| `maxCount` | `number` | `Infinity` | Maximum number of items allowed in the cache. |
|
|
49
|
+
| `maxSize` | `number` | `50MB` | Maximum estimated memory size in bytes. |
|
|
50
|
+
| `cleanupInterval` | `number` | `60000` | Interval (ms) for running the background cleanup (removes expired items). |
|
|
51
|
+
|
|
52
|
+
#### `set(key, value, options)` Options
|
|
53
|
+
|
|
54
|
+
| Option | Type | Default | Description |
|
|
55
|
+
|yyy|yyy|yyy|yyy|
|
|
56
|
+
| `importance` | `number` | `1` | Importance level. Higher values protect the item from eviction when memory is full. |
|
|
57
|
+
| `ttl` | `number` | - | Time To Live in milliseconds. |
|
|
58
|
+
| `expiresAt` | `Date` \| `number` | - | Absolute date when the item expires. |
|
|
59
|
+
|
|
60
|
+
## Eviction Strategy
|
|
61
|
+
|
|
62
|
+
When the cache reaches its memory or count limit, the Garbage Collector runs immediately upon the next `set` operation. It selects victims based on a scoring system:
|
|
63
|
+
|
|
64
|
+
1. **Low Importance**: Items with lower importance are targeted first.
|
|
65
|
+
2. **Low Usage**: Least frequently accessed items are targeted next.
|
|
66
|
+
3. **Age**: Older items are targeted last if importance and usage are equal.
|