@ghom/orm 1.9.1 → 1.10.0
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/app/backup.js +12 -3
- package/dist/app/orm.d.ts +40 -7
- package/dist/app/orm.js +53 -3
- package/dist/app/table.d.ts +5 -4
- package/dist/app/table.js +11 -6
- package/dist/app/util.js +2 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +0 -1
- package/package.json +2 -1
- package/readme.md +19 -0
- package/tests/test.js +24 -0
- package/dist/app/caching.d.ts +0 -18
- package/dist/app/caching.js +0 -36
package/dist/app/backup.js
CHANGED
|
@@ -3,13 +3,19 @@ import path from "node:path";
|
|
|
3
3
|
import csv from "json-2-csv";
|
|
4
4
|
import csvParser from "csv-parser";
|
|
5
5
|
import { DEFAULT_BACKUP_CHUNK_SIZE, DEFAULT_BACKUP_LOCATION, styled, } from "./util.js";
|
|
6
|
+
function getConfig(orm) {
|
|
7
|
+
if (orm.config === false)
|
|
8
|
+
throw new Error("ORM config is not available");
|
|
9
|
+
return orm.config;
|
|
10
|
+
}
|
|
6
11
|
export async function backupTable(table, dirname) {
|
|
7
12
|
if (!table.orm)
|
|
8
13
|
throw new Error("missing ORM");
|
|
14
|
+
const config = getConfig(table.orm);
|
|
9
15
|
let offset = 0;
|
|
10
16
|
let processedRows = 0;
|
|
11
17
|
let chunkIndex = 0;
|
|
12
|
-
const chunkDir = path.join(
|
|
18
|
+
const chunkDir = path.join(config.backups?.location ?? DEFAULT_BACKUP_LOCATION, dirname ?? "");
|
|
13
19
|
if (!fs.existsSync(chunkDir)) {
|
|
14
20
|
fs.mkdirSync(chunkDir, { recursive: true });
|
|
15
21
|
console.log(`Backup directory ${styled(table.orm, path.relative(process.cwd(), chunkDir), "highlight")} created.`);
|
|
@@ -28,7 +34,7 @@ export async function backupTable(table, dirname) {
|
|
|
28
34
|
// Si aucun fichier n'est créé ou qu'on a dépassé la taille max du chunk, on crée un nouveau fichier CSV
|
|
29
35
|
if (!writeStream ||
|
|
30
36
|
writeStream.bytesWritten + Buffer.byteLength(csvData, "utf8") >
|
|
31
|
-
(
|
|
37
|
+
(config.backups?.chunkSize ?? DEFAULT_BACKUP_CHUNK_SIZE)) {
|
|
32
38
|
if (writeStream) {
|
|
33
39
|
closePromises.push(new Promise((resolve) => writeStream.end(resolve))); // Ajouter la promesse de fermeture
|
|
34
40
|
}
|
|
@@ -58,7 +64,8 @@ export async function backupTable(table, dirname) {
|
|
|
58
64
|
export async function restoreBackup(table, trx, dirname) {
|
|
59
65
|
if (!table.orm)
|
|
60
66
|
throw new Error("missing ORM");
|
|
61
|
-
const
|
|
67
|
+
const config = getConfig(table.orm);
|
|
68
|
+
const chunkDir = path.join(config.backups?.location ?? DEFAULT_BACKUP_LOCATION, dirname ?? "");
|
|
62
69
|
const chunkFiles = fs
|
|
63
70
|
.readdirSync(chunkDir)
|
|
64
71
|
.filter((file) => file.split("_chunk_")[0] === table.options.name);
|
|
@@ -112,6 +119,8 @@ export async function enableForeignKeys(orm, trx) {
|
|
|
112
119
|
});
|
|
113
120
|
}
|
|
114
121
|
export async function disableForeignKeys(orm, run) {
|
|
122
|
+
if (!orm.client)
|
|
123
|
+
throw new Error("ORM client is not initialized");
|
|
115
124
|
const trx = orm.clientBasedOperation({
|
|
116
125
|
sqlite3: () => orm.client,
|
|
117
126
|
}) ?? (await orm.client.transaction());
|
package/dist/app/orm.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { Handler } from "@ghom/handler";
|
|
|
2
2
|
import { Knex } from "knex";
|
|
3
3
|
import { TextStyle } from "./util.js";
|
|
4
4
|
import { Table } from "./table.js";
|
|
5
|
-
import {
|
|
5
|
+
import { CachedQuery } from "@ghom/query";
|
|
6
6
|
export interface ILogger {
|
|
7
7
|
log: (message: string) => void;
|
|
8
8
|
error: (error: string | Error) => void;
|
|
@@ -44,13 +44,46 @@ export interface ORMConfig {
|
|
|
44
44
|
*/
|
|
45
45
|
caching?: number;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* The main ORM class that manages database connections, tables, and caching.
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* // With database connection
|
|
52
|
+
* const orm = new ORM({
|
|
53
|
+
* tableLocation: "./tables",
|
|
54
|
+
* database: { client: "sqlite3", connection: { filename: ":memory:" } }
|
|
55
|
+
* })
|
|
56
|
+
* await orm.init()
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* // Without database connection (for type exports only)
|
|
60
|
+
* const orm = new ORM(false)
|
|
61
|
+
* orm.isConnected // false
|
|
62
|
+
*/
|
|
47
63
|
export declare class ORM {
|
|
48
|
-
config: ORMConfig;
|
|
64
|
+
config: ORMConfig | false;
|
|
49
65
|
private _ready;
|
|
50
|
-
client
|
|
51
|
-
handler
|
|
52
|
-
_rawCache
|
|
53
|
-
|
|
66
|
+
client?: Knex;
|
|
67
|
+
handler?: Handler<Table<any>>;
|
|
68
|
+
_rawCache?: CachedQuery<[raw: string], Knex.Raw>;
|
|
69
|
+
/**
|
|
70
|
+
* Creates a new ORM instance.
|
|
71
|
+
*
|
|
72
|
+
* @param config - The ORM configuration, or `false` to create an unconnected instance.
|
|
73
|
+
*
|
|
74
|
+
* When `false` is passed, the ORM will not connect to any database.
|
|
75
|
+
* This is useful for scenarios where you only need to export types or
|
|
76
|
+
* use the ORM structure without an actual database connection.
|
|
77
|
+
*
|
|
78
|
+
* Methods that require a database connection will throw an error
|
|
79
|
+
* if called on an unconnected ORM instance.
|
|
80
|
+
*/
|
|
81
|
+
constructor(config: ORMConfig | false);
|
|
82
|
+
private requireClient;
|
|
83
|
+
/**
|
|
84
|
+
* Returns true if the ORM has a database client connected.
|
|
85
|
+
*/
|
|
86
|
+
get isConnected(): boolean;
|
|
54
87
|
get cachedTables(): Table<any>[];
|
|
55
88
|
get cachedTableNames(): string[];
|
|
56
89
|
hasCachedTable(name: string): boolean;
|
|
@@ -61,7 +94,7 @@ export declare class ORM {
|
|
|
61
94
|
init(): Promise<void>;
|
|
62
95
|
raw(sql: Knex.Value): Knex.Raw;
|
|
63
96
|
cache: {
|
|
64
|
-
raw: (sql: string, anyDataUpdated?: boolean) => Knex.Raw
|
|
97
|
+
raw: (sql: string, anyDataUpdated?: boolean) => Promise<Knex.Raw>;
|
|
65
98
|
invalidate: () => void;
|
|
66
99
|
};
|
|
67
100
|
clientBasedOperation<Return>(operation: Partial<Record<"pg" | "mysql2" | "sqlite3", () => Return>>): Return | undefined;
|
package/dist/app/orm.js
CHANGED
|
@@ -3,16 +3,46 @@ import { Handler } from "@ghom/handler";
|
|
|
3
3
|
import { default as knex } from "knex";
|
|
4
4
|
import { isCJS } from "./util.js";
|
|
5
5
|
import { Table } from "./table.js";
|
|
6
|
-
import {
|
|
6
|
+
import { CachedQuery } from "@ghom/query";
|
|
7
7
|
import { backupTable, restoreBackup, disableForeignKeys, enableForeignKeys, } from "./backup.js";
|
|
8
|
+
/**
|
|
9
|
+
* The main ORM class that manages database connections, tables, and caching.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // With database connection
|
|
13
|
+
* const orm = new ORM({
|
|
14
|
+
* tableLocation: "./tables",
|
|
15
|
+
* database: { client: "sqlite3", connection: { filename: ":memory:" } }
|
|
16
|
+
* })
|
|
17
|
+
* await orm.init()
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* // Without database connection (for type exports only)
|
|
21
|
+
* const orm = new ORM(false)
|
|
22
|
+
* orm.isConnected // false
|
|
23
|
+
*/
|
|
8
24
|
export class ORM {
|
|
9
25
|
config;
|
|
10
26
|
_ready = false;
|
|
11
27
|
client;
|
|
12
28
|
handler;
|
|
13
29
|
_rawCache;
|
|
30
|
+
/**
|
|
31
|
+
* Creates a new ORM instance.
|
|
32
|
+
*
|
|
33
|
+
* @param config - The ORM configuration, or `false` to create an unconnected instance.
|
|
34
|
+
*
|
|
35
|
+
* When `false` is passed, the ORM will not connect to any database.
|
|
36
|
+
* This is useful for scenarios where you only need to export types or
|
|
37
|
+
* use the ORM structure without an actual database connection.
|
|
38
|
+
*
|
|
39
|
+
* Methods that require a database connection will throw an error
|
|
40
|
+
* if called on an unconnected ORM instance.
|
|
41
|
+
*/
|
|
14
42
|
constructor(config) {
|
|
15
43
|
this.config = config;
|
|
44
|
+
if (config === false)
|
|
45
|
+
return;
|
|
16
46
|
this.client = knex(config.database ?? {
|
|
17
47
|
client: "sqlite3",
|
|
18
48
|
useNullAsDefault: true,
|
|
@@ -29,9 +59,21 @@ export class ORM {
|
|
|
29
59
|
throw new Error(`${filepath}: default export must be a Table instance`);
|
|
30
60
|
},
|
|
31
61
|
});
|
|
32
|
-
this._rawCache = new
|
|
62
|
+
this._rawCache = new CachedQuery(async (raw) => await this.raw(raw), config.caching ?? Infinity);
|
|
63
|
+
}
|
|
64
|
+
requireClient() {
|
|
65
|
+
if (!this.client)
|
|
66
|
+
throw new Error("ORM client is not initialized. Cannot use this method without a database connection.");
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Returns true if the ORM has a database client connected.
|
|
70
|
+
*/
|
|
71
|
+
get isConnected() {
|
|
72
|
+
return this.client !== undefined;
|
|
33
73
|
}
|
|
34
74
|
get cachedTables() {
|
|
75
|
+
if (!this.handler)
|
|
76
|
+
return [];
|
|
35
77
|
return [...this.handler.elements.values()];
|
|
36
78
|
}
|
|
37
79
|
get cachedTableNames() {
|
|
@@ -41,12 +83,14 @@ export class ORM {
|
|
|
41
83
|
return this.cachedTables.some((table) => table.options.name === name);
|
|
42
84
|
}
|
|
43
85
|
async hasTable(name) {
|
|
86
|
+
this.requireClient();
|
|
44
87
|
return this.client.schema.hasTable(name);
|
|
45
88
|
}
|
|
46
89
|
/**
|
|
47
90
|
* Handle the table files and create the tables in the database.
|
|
48
91
|
*/
|
|
49
92
|
async init() {
|
|
93
|
+
this.requireClient();
|
|
50
94
|
await this.handler.init();
|
|
51
95
|
try {
|
|
52
96
|
await enableForeignKeys(this);
|
|
@@ -67,22 +111,26 @@ export class ORM {
|
|
|
67
111
|
this._ready = true;
|
|
68
112
|
}
|
|
69
113
|
raw(sql) {
|
|
114
|
+
this.requireClient();
|
|
70
115
|
if (this._ready)
|
|
71
116
|
this.cache.invalidate();
|
|
72
117
|
return this.client.raw(sql);
|
|
73
118
|
}
|
|
74
119
|
cache = {
|
|
75
120
|
raw: (sql, anyDataUpdated) => {
|
|
121
|
+
this.requireClient();
|
|
76
122
|
if (anyDataUpdated)
|
|
77
123
|
this.cache.invalidate();
|
|
78
124
|
return this._rawCache.get(sql, sql);
|
|
79
125
|
},
|
|
80
126
|
invalidate: () => {
|
|
81
|
-
this._rawCache
|
|
127
|
+
this._rawCache?.invalidate();
|
|
82
128
|
this.cachedTables.forEach((table) => table.cache.invalidate());
|
|
83
129
|
},
|
|
84
130
|
};
|
|
85
131
|
clientBasedOperation(operation) {
|
|
132
|
+
if (this.config === false)
|
|
133
|
+
return undefined;
|
|
86
134
|
const client = (this.config.database?.client ?? "sqlite3");
|
|
87
135
|
return operation[client]?.();
|
|
88
136
|
}
|
|
@@ -91,6 +139,7 @@ export class ORM {
|
|
|
91
139
|
* The backup will be saved in the location specified in the config.
|
|
92
140
|
*/
|
|
93
141
|
async createBackup(dirname) {
|
|
142
|
+
this.requireClient();
|
|
94
143
|
for (let table of this.cachedTables) {
|
|
95
144
|
await backupTable(table, dirname);
|
|
96
145
|
}
|
|
@@ -101,6 +150,7 @@ export class ORM {
|
|
|
101
150
|
* @warning This will delete all the data in the tables.
|
|
102
151
|
*/
|
|
103
152
|
async restoreBackup(dirname) {
|
|
153
|
+
this.requireClient();
|
|
104
154
|
await disableForeignKeys(this, async (trx) => {
|
|
105
155
|
for (let table of this.cachedTables) {
|
|
106
156
|
await restoreBackup(table, trx, dirname);
|
package/dist/app/table.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Knex } from "knex";
|
|
2
2
|
import { ORM } from "./orm.js";
|
|
3
|
-
import {
|
|
3
|
+
import { CachedQuery } from "@ghom/query";
|
|
4
4
|
export interface MigrationData {
|
|
5
5
|
table: string;
|
|
6
6
|
version: number;
|
|
@@ -23,12 +23,13 @@ export interface TableOptions<Type extends object = object> {
|
|
|
23
23
|
export declare class Table<Type extends object = object> {
|
|
24
24
|
readonly options: TableOptions<Type>;
|
|
25
25
|
orm?: ORM;
|
|
26
|
-
_whereCache?:
|
|
26
|
+
_whereCache?: CachedQuery<[
|
|
27
27
|
cb: (query: Table<Type>["query"]) => unknown
|
|
28
28
|
], unknown>;
|
|
29
|
-
_countCache?:
|
|
29
|
+
_countCache?: CachedQuery<[where: string | null], number>;
|
|
30
30
|
constructor(options: TableOptions<Type>);
|
|
31
|
-
|
|
31
|
+
private requireOrm;
|
|
32
|
+
get db(): Knex;
|
|
32
33
|
get query(): Knex.QueryBuilder<Type, {
|
|
33
34
|
_base: Type;
|
|
34
35
|
_hasSelection: false;
|
package/dist/app/table.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { styled } from "./util.js";
|
|
2
|
-
import {
|
|
2
|
+
import { CachedQuery } from "@ghom/query";
|
|
3
3
|
export class Table {
|
|
4
4
|
options;
|
|
5
5
|
orm;
|
|
@@ -8,9 +8,14 @@ export class Table {
|
|
|
8
8
|
constructor(options) {
|
|
9
9
|
this.options = options;
|
|
10
10
|
}
|
|
11
|
-
|
|
11
|
+
requireOrm() {
|
|
12
12
|
if (!this.orm)
|
|
13
13
|
throw new Error("missing ORM");
|
|
14
|
+
if (!this.orm.client)
|
|
15
|
+
throw new Error("ORM client is not initialized");
|
|
16
|
+
}
|
|
17
|
+
get db() {
|
|
18
|
+
this.requireOrm();
|
|
14
19
|
return this.orm.client;
|
|
15
20
|
}
|
|
16
21
|
get query() {
|
|
@@ -19,8 +24,7 @@ export class Table {
|
|
|
19
24
|
get cache() {
|
|
20
25
|
if (!this._whereCache || !this._countCache)
|
|
21
26
|
throw new Error("missing cache");
|
|
22
|
-
|
|
23
|
-
throw new Error("missing ORM");
|
|
27
|
+
this.requireOrm();
|
|
24
28
|
return {
|
|
25
29
|
get: (id, cb) => {
|
|
26
30
|
return this._whereCache.get(id, cb);
|
|
@@ -63,8 +67,9 @@ export class Table {
|
|
|
63
67
|
}
|
|
64
68
|
async make(orm) {
|
|
65
69
|
this.orm = orm;
|
|
66
|
-
this.
|
|
67
|
-
this.
|
|
70
|
+
this.requireOrm();
|
|
71
|
+
this._whereCache = new CachedQuery((cb) => cb(this.query), this.options.caching ?? this.orm.config.caching ?? Infinity);
|
|
72
|
+
this._countCache = new CachedQuery((where) => this.count(where ?? undefined), this.options.caching ?? this.orm.config.caching ?? Infinity);
|
|
68
73
|
const tableNameLog = `table ${styled(this.orm, this.options.name, "highlight")}${this.options.description
|
|
69
74
|
? ` ${styled(this.orm, this.options.description, "description")}`
|
|
70
75
|
: ""}`;
|
package/dist/app/util.js
CHANGED
|
@@ -18,7 +18,8 @@ catch {
|
|
|
18
18
|
}
|
|
19
19
|
export { isCJS };
|
|
20
20
|
export function styled(orm, message, style) {
|
|
21
|
-
|
|
21
|
+
const config = orm.config !== false ? orm.config : undefined;
|
|
22
|
+
return util.styleText(config?.loggerStyles?.[style] ??
|
|
22
23
|
(style === "highlight"
|
|
23
24
|
? DEFAULT_LOGGER_HIGHLIGHT
|
|
24
25
|
: style === "rawValue"
|
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ghom/orm",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.10.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -32,6 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
34
|
"@ghom/handler": "^3.1.0",
|
|
35
|
+
"@ghom/query": "1.0.0",
|
|
35
36
|
"csv-parser": "^3.0.0",
|
|
36
37
|
"json-2-csv": "^5.5.6",
|
|
37
38
|
"knex": "^3.0.1"
|
package/readme.md
CHANGED
|
@@ -41,6 +41,25 @@ const orm = new ORM({
|
|
|
41
41
|
await orm.init()
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
+
### Unconnected ORM
|
|
45
|
+
|
|
46
|
+
You can also create an ORM instance without connecting to a database. This is useful when you only need to export types or prepare the ORM structure for a future database connection.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { ORM } from "@ghom/orm"
|
|
50
|
+
|
|
51
|
+
const orm = new ORM(false)
|
|
52
|
+
|
|
53
|
+
orm.isConnected // false
|
|
54
|
+
orm.cachedTables // []
|
|
55
|
+
orm.cachedTableNames // []
|
|
56
|
+
|
|
57
|
+
// Methods requiring a database connection will throw an error
|
|
58
|
+
orm.init() // throws Error
|
|
59
|
+
orm.hasTable("user") // throws Error
|
|
60
|
+
orm.raw("SELECT 1") // throws Error
|
|
61
|
+
```
|
|
62
|
+
|
|
44
63
|
## Add tables
|
|
45
64
|
|
|
46
65
|
The tables are automatically loaded from the `location` directory.
|
package/tests/test.js
CHANGED
|
@@ -16,6 +16,30 @@ import a from "./tables/a"
|
|
|
16
16
|
import b from "./tables/b"
|
|
17
17
|
import c from "./tables/c"
|
|
18
18
|
|
|
19
|
+
describe("unconnected ORM", () => {
|
|
20
|
+
test("can be initialized with false", () => {
|
|
21
|
+
const unconnectedOrm = new ORM(false)
|
|
22
|
+
|
|
23
|
+
expect(unconnectedOrm).toBeInstanceOf(ORM)
|
|
24
|
+
expect(unconnectedOrm.isConnected).toBe(false)
|
|
25
|
+
expect(unconnectedOrm.config).toBe(false)
|
|
26
|
+
expect(unconnectedOrm.client).toBeUndefined()
|
|
27
|
+
expect(unconnectedOrm.handler).toBeUndefined()
|
|
28
|
+
expect(unconnectedOrm.cachedTables).toEqual([])
|
|
29
|
+
expect(unconnectedOrm.cachedTableNames).toEqual([])
|
|
30
|
+
})
|
|
31
|
+
|
|
32
|
+
test("throws when calling methods requiring client", async () => {
|
|
33
|
+
const unconnectedOrm = new ORM(false)
|
|
34
|
+
|
|
35
|
+
await expect(unconnectedOrm.init()).rejects.toThrow()
|
|
36
|
+
await expect(unconnectedOrm.hasTable("test")).rejects.toThrow()
|
|
37
|
+
expect(() => unconnectedOrm.raw("SELECT 1")).toThrow()
|
|
38
|
+
await expect(unconnectedOrm.createBackup()).rejects.toThrow()
|
|
39
|
+
await expect(unconnectedOrm.restoreBackup()).rejects.toThrow()
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
19
43
|
const orm = new ORM({
|
|
20
44
|
tableLocation: path.join(process.cwd(), "tests", "tables"),
|
|
21
45
|
backups: {
|
package/dist/app/caching.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
export interface ResponseCacheData<Value> {
|
|
2
|
-
value: Value;
|
|
3
|
-
expires: number;
|
|
4
|
-
outdated?: boolean;
|
|
5
|
-
}
|
|
6
|
-
/**
|
|
7
|
-
* Advanced cache for async queries
|
|
8
|
-
*/
|
|
9
|
-
export declare class ResponseCache<Params extends any[], Value> {
|
|
10
|
-
private _request;
|
|
11
|
-
private _timeout;
|
|
12
|
-
private _cache;
|
|
13
|
-
constructor(_request: (...params: Params) => Value, _timeout: number);
|
|
14
|
-
get(id: string, ...params: Params): Value;
|
|
15
|
-
fetch(id: string, ...params: Params): Value;
|
|
16
|
-
invalidate(): void;
|
|
17
|
-
invalidate(id: string): void;
|
|
18
|
-
}
|
package/dist/app/caching.js
DELETED
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Advanced cache for async queries
|
|
3
|
-
*/
|
|
4
|
-
export class ResponseCache {
|
|
5
|
-
_request;
|
|
6
|
-
_timeout;
|
|
7
|
-
_cache = new Map();
|
|
8
|
-
constructor(_request, _timeout) {
|
|
9
|
-
this._request = _request;
|
|
10
|
-
this._timeout = _timeout;
|
|
11
|
-
}
|
|
12
|
-
get(id, ...params) {
|
|
13
|
-
const cached = this._cache.get(id);
|
|
14
|
-
if (!cached || cached.expires < Date.now()) {
|
|
15
|
-
this._cache.set(id, {
|
|
16
|
-
value: this._request(...params),
|
|
17
|
-
expires: Date.now() + this._timeout,
|
|
18
|
-
});
|
|
19
|
-
}
|
|
20
|
-
return this._cache.get(id).value;
|
|
21
|
-
}
|
|
22
|
-
fetch(id, ...params) {
|
|
23
|
-
this._cache.set(id, {
|
|
24
|
-
value: this._request(...params),
|
|
25
|
-
expires: Date.now() + this._timeout,
|
|
26
|
-
});
|
|
27
|
-
return this._cache.get(id).value;
|
|
28
|
-
}
|
|
29
|
-
invalidate(id) {
|
|
30
|
-
if (!id) {
|
|
31
|
-
this._cache.clear();
|
|
32
|
-
return;
|
|
33
|
-
}
|
|
34
|
-
this._cache.delete(id);
|
|
35
|
-
}
|
|
36
|
-
}
|