rads-db 0.1.101 → 0.1.103
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/features/cache.cjs +25 -10
- package/features/cache.d.ts +5 -3
- package/features/cache.mjs +25 -10
- package/integrations/restEndpointsDev.cjs +15 -0
- package/integrations/restEndpointsDev.mjs +13 -0
- package/package.json +1 -1
package/features/cache.cjs
CHANGED
|
@@ -14,7 +14,7 @@ var _default = options => {
|
|
|
14
14
|
return {
|
|
15
15
|
name: "cache",
|
|
16
16
|
init(db, context) {
|
|
17
|
-
const entitiesToCache = Object.keys(normalizedOptions
|
|
17
|
+
const entitiesToCache = Object.keys(normalizedOptions);
|
|
18
18
|
const {
|
|
19
19
|
schema,
|
|
20
20
|
drivers
|
|
@@ -25,7 +25,8 @@ var _default = options => {
|
|
|
25
25
|
where,
|
|
26
26
|
revalidateInterval
|
|
27
27
|
} = entitiesToPreload[typeName];
|
|
28
|
-
const handle = schema[typeName]
|
|
28
|
+
const handle = schema[typeName]?.handle;
|
|
29
|
+
if (!handle) throw new Error(`Entity ${typeName} was not found`);
|
|
29
30
|
cacheStatus[handle].preloadStatus = "loading";
|
|
30
31
|
try {
|
|
31
32
|
const allData = await db[handle].getAll({
|
|
@@ -47,6 +48,7 @@ var _default = options => {
|
|
|
47
48
|
}
|
|
48
49
|
for (const typeName of entitiesToCache) {
|
|
49
50
|
const handle = schema[typeName].handle;
|
|
51
|
+
if (!handle) throw new Error(`Entity ${typeName} was not found`);
|
|
50
52
|
const cacheEntityName = `Cache_${typeName}`;
|
|
51
53
|
schema[cacheEntityName] = {
|
|
52
54
|
...schema[typeName],
|
|
@@ -54,9 +56,9 @@ var _default = options => {
|
|
|
54
56
|
handle: cacheEntityName,
|
|
55
57
|
handlePlural: `${cacheEntityName}s`
|
|
56
58
|
};
|
|
57
|
-
cacheDrivers[handle] = (0, _radsDb.getDriverInstance)(schema, cacheEntityName, normalizedOptions.driver, drivers);
|
|
59
|
+
cacheDrivers[handle] = (0, _radsDb.getDriverInstance)(schema, cacheEntityName, normalizedOptions[typeName].driver, drivers);
|
|
58
60
|
cacheStatus[handle] = {
|
|
59
|
-
preloadStatus: normalizedOptions.preload ? "neverLoaded" : void 0
|
|
61
|
+
preloadStatus: normalizedOptions[typeName].preload ? "neverLoaded" : void 0
|
|
60
62
|
};
|
|
61
63
|
}
|
|
62
64
|
db.cache = {
|
|
@@ -84,7 +86,8 @@ var _default = options => {
|
|
|
84
86
|
async beforeGet(args, ctx, context) {
|
|
85
87
|
if (ctx.noCache) return;
|
|
86
88
|
const {
|
|
87
|
-
handle
|
|
89
|
+
handle,
|
|
90
|
+
typeName
|
|
88
91
|
} = context;
|
|
89
92
|
const d = cacheDrivers[handle];
|
|
90
93
|
if (!d) return;
|
|
@@ -92,8 +95,8 @@ var _default = options => {
|
|
|
92
95
|
const result2 = await d[ctx.method](args, ctx);
|
|
93
96
|
if (!result2) return;
|
|
94
97
|
const ageMs = Date.now() - result2._cacheUpdatedAt;
|
|
95
|
-
const maxAge = ctx.maxAge ?? normalizedOptions.maxAge;
|
|
96
|
-
const staleWhileRevalidate = ctx.staleWhileRevalidate ?? normalizedOptions.staleWhileRevalidate;
|
|
98
|
+
const maxAge = ctx.maxAge ?? normalizedOptions[typeName].maxAge;
|
|
99
|
+
const staleWhileRevalidate = ctx.staleWhileRevalidate ?? normalizedOptions[typeName].staleWhileRevalidate;
|
|
97
100
|
if (maxAge !== -1 && (maxAge === 0 || ageMs > maxAge * 1e3)) {
|
|
98
101
|
if (staleWhileRevalidate !== 0 && (staleWhileRevalidate === -1 || ageMs <= staleWhileRevalidate * 1e3)) {
|
|
99
102
|
const db = context.db;
|
|
@@ -140,11 +143,23 @@ var _default = options => {
|
|
|
140
143
|
};
|
|
141
144
|
module.exports = _default;
|
|
142
145
|
function normalizeOptions(options) {
|
|
143
|
-
|
|
146
|
+
const {
|
|
147
|
+
entities,
|
|
148
|
+
...optionsDefaults
|
|
149
|
+
} = options;
|
|
150
|
+
const defaults = {
|
|
144
151
|
driver: (0, _memory.default)(),
|
|
145
152
|
maxAge: 300,
|
|
146
153
|
staleWhileRevalidate: 0,
|
|
147
|
-
|
|
148
|
-
...options
|
|
154
|
+
...optionsDefaults
|
|
149
155
|
};
|
|
156
|
+
const result = {};
|
|
157
|
+
for (const entity in entities) {
|
|
158
|
+
const v = entities[entity];
|
|
159
|
+
if (!v) continue;else if (v === true) result[entity] = defaults;else result[entity] = {
|
|
160
|
+
...defaults,
|
|
161
|
+
...v
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
return result;
|
|
150
165
|
}
|
package/features/cache.d.ts
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { DriverConstructor } from '@/types';
|
|
2
|
-
declare const _default: (options
|
|
2
|
+
declare const _default: (options: CacheOptions) => RadsFeature;
|
|
3
3
|
export default _default;
|
|
4
|
-
export interface
|
|
5
|
-
entities: Record<string, boolean>;
|
|
4
|
+
export interface EntityCacheOptions {
|
|
6
5
|
driver?: DriverConstructor;
|
|
7
6
|
/**
|
|
8
7
|
* Number in seconds. If document was stored in cache more than maxAge seconds ago, cache is ignored.
|
|
@@ -28,6 +27,9 @@ export interface CacheOptions {
|
|
|
28
27
|
*/
|
|
29
28
|
preload?: boolean;
|
|
30
29
|
}
|
|
30
|
+
export interface CacheOptions extends EntityCacheOptions {
|
|
31
|
+
entities: Record<string, boolean | EntityCacheOptions>;
|
|
32
|
+
}
|
|
31
33
|
export interface CacheStatus {
|
|
32
34
|
preloadStatus?: 'upToDate' | 'updating' | 'loading' | 'error' | 'neverLoaded';
|
|
33
35
|
updatedAt?: string;
|
package/features/cache.mjs
CHANGED
|
@@ -7,12 +7,14 @@ export default (options) => {
|
|
|
7
7
|
return {
|
|
8
8
|
name: "cache",
|
|
9
9
|
init(db, context) {
|
|
10
|
-
const entitiesToCache = Object.keys(normalizedOptions
|
|
10
|
+
const entitiesToCache = Object.keys(normalizedOptions);
|
|
11
11
|
const { schema, drivers } = context;
|
|
12
12
|
async function preloadEntities(entitiesToPreload) {
|
|
13
13
|
for (const typeName in entitiesToPreload) {
|
|
14
14
|
const { where, revalidateInterval } = entitiesToPreload[typeName];
|
|
15
|
-
const handle = schema[typeName]
|
|
15
|
+
const handle = schema[typeName]?.handle;
|
|
16
|
+
if (!handle)
|
|
17
|
+
throw new Error(`Entity ${typeName} was not found`);
|
|
16
18
|
cacheStatus[handle].preloadStatus = "loading";
|
|
17
19
|
try {
|
|
18
20
|
const allData = await db[handle].getAll({ where }, { noCache: true });
|
|
@@ -27,6 +29,8 @@ export default (options) => {
|
|
|
27
29
|
}
|
|
28
30
|
for (const typeName of entitiesToCache) {
|
|
29
31
|
const handle = schema[typeName].handle;
|
|
32
|
+
if (!handle)
|
|
33
|
+
throw new Error(`Entity ${typeName} was not found`);
|
|
30
34
|
const cacheEntityName = `Cache_${typeName}`;
|
|
31
35
|
schema[cacheEntityName] = {
|
|
32
36
|
...schema[typeName],
|
|
@@ -34,8 +38,8 @@ export default (options) => {
|
|
|
34
38
|
handle: cacheEntityName,
|
|
35
39
|
handlePlural: `${cacheEntityName}s`
|
|
36
40
|
};
|
|
37
|
-
cacheDrivers[handle] = getDriverInstance(schema, cacheEntityName, normalizedOptions.driver, drivers);
|
|
38
|
-
cacheStatus[handle] = { preloadStatus: normalizedOptions.preload ? "neverLoaded" : void 0 };
|
|
41
|
+
cacheDrivers[handle] = getDriverInstance(schema, cacheEntityName, normalizedOptions[typeName].driver, drivers);
|
|
42
|
+
cacheStatus[handle] = { preloadStatus: normalizedOptions[typeName].preload ? "neverLoaded" : void 0 };
|
|
39
43
|
}
|
|
40
44
|
db.cache = {
|
|
41
45
|
drivers: cacheDrivers,
|
|
@@ -66,7 +70,7 @@ export default (options) => {
|
|
|
66
70
|
async beforeGet(args, ctx, context) {
|
|
67
71
|
if (ctx.noCache)
|
|
68
72
|
return;
|
|
69
|
-
const { handle } = context;
|
|
73
|
+
const { handle, typeName } = context;
|
|
70
74
|
const d = cacheDrivers[handle];
|
|
71
75
|
if (!d)
|
|
72
76
|
return;
|
|
@@ -75,8 +79,8 @@ export default (options) => {
|
|
|
75
79
|
if (!result2)
|
|
76
80
|
return;
|
|
77
81
|
const ageMs = Date.now() - result2._cacheUpdatedAt;
|
|
78
|
-
const maxAge = ctx.maxAge ?? normalizedOptions.maxAge;
|
|
79
|
-
const staleWhileRevalidate = ctx.staleWhileRevalidate ?? normalizedOptions.staleWhileRevalidate;
|
|
82
|
+
const maxAge = ctx.maxAge ?? normalizedOptions[typeName].maxAge;
|
|
83
|
+
const staleWhileRevalidate = ctx.staleWhileRevalidate ?? normalizedOptions[typeName].staleWhileRevalidate;
|
|
80
84
|
if (maxAge !== -1 && (maxAge === 0 || ageMs > maxAge * 1e3)) {
|
|
81
85
|
if (staleWhileRevalidate !== 0 && (staleWhileRevalidate === -1 || ageMs <= staleWhileRevalidate * 1e3)) {
|
|
82
86
|
const db = context.db;
|
|
@@ -116,11 +120,22 @@ export default (options) => {
|
|
|
116
120
|
};
|
|
117
121
|
};
|
|
118
122
|
function normalizeOptions(options) {
|
|
119
|
-
|
|
123
|
+
const { entities, ...optionsDefaults } = options;
|
|
124
|
+
const defaults = {
|
|
120
125
|
driver: memory(),
|
|
121
126
|
maxAge: 300,
|
|
122
127
|
staleWhileRevalidate: 0,
|
|
123
|
-
|
|
124
|
-
...options
|
|
128
|
+
...optionsDefaults
|
|
125
129
|
};
|
|
130
|
+
const result = {};
|
|
131
|
+
for (const entity in entities) {
|
|
132
|
+
const v = entities[entity];
|
|
133
|
+
if (!v)
|
|
134
|
+
continue;
|
|
135
|
+
else if (v === true)
|
|
136
|
+
result[entity] = defaults;
|
|
137
|
+
else
|
|
138
|
+
result[entity] = { ...defaults, ...v };
|
|
139
|
+
}
|
|
140
|
+
return result;
|
|
126
141
|
}
|
|
@@ -43,6 +43,13 @@ var _default = {
|
|
|
43
43
|
});
|
|
44
44
|
if (result?.text) data = result.text;
|
|
45
45
|
}
|
|
46
|
+
const dirname = _nodePath.default.dirname(filepath);
|
|
47
|
+
const isExistingDir = await dirExists(dirname);
|
|
48
|
+
if (!isExistingDir) {
|
|
49
|
+
await _promises.default.mkdir(dirname, {
|
|
50
|
+
recursive: true
|
|
51
|
+
});
|
|
52
|
+
}
|
|
46
53
|
await _promises.default.writeFile(filepath, data, options);
|
|
47
54
|
return result;
|
|
48
55
|
},
|
|
@@ -71,6 +78,14 @@ var _default = {
|
|
|
71
78
|
}
|
|
72
79
|
};
|
|
73
80
|
module.exports = _default;
|
|
81
|
+
async function dirExists(path2) {
|
|
82
|
+
try {
|
|
83
|
+
await _promises.default.access(path2);
|
|
84
|
+
return true;
|
|
85
|
+
} catch {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
74
89
|
function sanitizeFilepath(filepath) {
|
|
75
90
|
const result = _nodePath.default.resolve(filepath);
|
|
76
91
|
if (!result.startsWith(root)) throw new Error("Invalid path");
|
|
@@ -35,6 +35,11 @@ export default {
|
|
|
35
35
|
if (result?.text)
|
|
36
36
|
data = result.text;
|
|
37
37
|
}
|
|
38
|
+
const dirname = path.dirname(filepath);
|
|
39
|
+
const isExistingDir = await dirExists(dirname);
|
|
40
|
+
if (!isExistingDir) {
|
|
41
|
+
await fs.mkdir(dirname, { recursive: true });
|
|
42
|
+
}
|
|
38
43
|
await fs.writeFile(filepath, data, options);
|
|
39
44
|
return result;
|
|
40
45
|
},
|
|
@@ -64,6 +69,14 @@ export default {
|
|
|
64
69
|
return await fs.unlink(filepath);
|
|
65
70
|
}
|
|
66
71
|
};
|
|
72
|
+
async function dirExists(path2) {
|
|
73
|
+
try {
|
|
74
|
+
await fs.access(path2);
|
|
75
|
+
return true;
|
|
76
|
+
} catch {
|
|
77
|
+
return false;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
67
80
|
function sanitizeFilepath(filepath) {
|
|
68
81
|
const result = path.resolve(filepath);
|
|
69
82
|
if (!result.startsWith(root))
|