@travetto/model-file 8.0.0-alpha.22 → 8.0.0-alpha.23
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/README.md +2 -2
- package/__index__.ts +1 -1
- package/package.json +7 -7
- package/src/service.ts +48 -26
package/README.md
CHANGED
|
@@ -14,6 +14,6 @@ yarn add @travetto/model-file
|
|
|
14
14
|
```
|
|
15
15
|
|
|
16
16
|
This module provides an file-based implementation for the [Data Modeling Support](https://github.com/travetto/travetto/tree/main/module/model#readme "Datastore abstraction for core operations."). Supported features:
|
|
17
|
-
* [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L11)
|
|
18
|
-
* [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
|
|
19
17
|
* [Blob](https://github.com/travetto/travetto/tree/main/module/model/src/types/blob.ts#L8)
|
|
18
|
+
* [CRUD](https://github.com/travetto/travetto/tree/main/module/model/src/types/crud.ts#L10)
|
|
19
|
+
* [Expiry](https://github.com/travetto/travetto/tree/main/module/model/src/types/expiry.ts#L10)
|
package/__index__.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './src/service.ts';
|
|
1
|
+
export * from './src/service.ts';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@travetto/model-file",
|
|
3
|
-
"version": "8.0.0-alpha.
|
|
3
|
+
"version": "8.0.0-alpha.23",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "File system backing for the travetto model module.",
|
|
6
6
|
"keywords": [
|
|
@@ -26,14 +26,14 @@
|
|
|
26
26
|
"directory": "module/model-file"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@travetto/config": "^8.0.0-alpha.
|
|
30
|
-
"@travetto/di": "^8.0.0-alpha.
|
|
31
|
-
"@travetto/model": "^8.0.0-alpha.
|
|
32
|
-
"@travetto/schema": "^8.0.0-alpha.
|
|
29
|
+
"@travetto/config": "^8.0.0-alpha.22",
|
|
30
|
+
"@travetto/di": "^8.0.0-alpha.20",
|
|
31
|
+
"@travetto/model": "^8.0.0-alpha.23",
|
|
32
|
+
"@travetto/schema": "^8.0.0-alpha.22"
|
|
33
33
|
},
|
|
34
34
|
"peerDependencies": {
|
|
35
|
-
"@travetto/cli": "^8.0.0-alpha.
|
|
36
|
-
"@travetto/test": "^8.0.0-alpha.
|
|
35
|
+
"@travetto/cli": "^8.0.0-alpha.28",
|
|
36
|
+
"@travetto/test": "^8.0.0-alpha.21"
|
|
37
37
|
},
|
|
38
38
|
"peerDependenciesMeta": {
|
|
39
39
|
"@travetto/cli": {
|
package/src/service.ts
CHANGED
|
@@ -1,20 +1,36 @@
|
|
|
1
|
-
import fs from 'node:fs/promises';
|
|
2
1
|
import { createReadStream, createWriteStream } from 'node:fs';
|
|
2
|
+
import fs from 'node:fs/promises';
|
|
3
3
|
import os from 'node:os';
|
|
4
4
|
import path from 'node:path';
|
|
5
5
|
|
|
6
|
-
import {
|
|
7
|
-
type Class, type TimeSpan, Runtime, type BinaryMetadata, type ByteRange, type BinaryType,
|
|
8
|
-
BinaryUtil, JSONUtil, BinaryMetadataUtil
|
|
9
|
-
} from '@travetto/runtime';
|
|
10
|
-
import { Injectable, PostConstruct } from '@travetto/di';
|
|
11
6
|
import { Config } from '@travetto/config';
|
|
12
|
-
import {
|
|
7
|
+
import { Injectable, PostConstruct } from '@travetto/di';
|
|
13
8
|
import {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
type
|
|
9
|
+
ExistsError,
|
|
10
|
+
type ModelBlobSupport,
|
|
11
|
+
type ModelCrudSupport,
|
|
12
|
+
ModelCrudUtil,
|
|
13
|
+
type ModelExpirySupport,
|
|
14
|
+
ModelExpiryUtil,
|
|
15
|
+
type ModelListOptions,
|
|
16
|
+
ModelRegistryIndex,
|
|
17
|
+
type ModelStorageSupport,
|
|
18
|
+
type ModelType,
|
|
19
|
+
NotFoundError,
|
|
20
|
+
type OptionalId
|
|
17
21
|
} from '@travetto/model';
|
|
22
|
+
import {
|
|
23
|
+
type BinaryMetadata,
|
|
24
|
+
BinaryMetadataUtil,
|
|
25
|
+
type BinaryType,
|
|
26
|
+
BinaryUtil,
|
|
27
|
+
type ByteRange,
|
|
28
|
+
type Class,
|
|
29
|
+
JSONUtil,
|
|
30
|
+
Runtime,
|
|
31
|
+
type TimeSpan
|
|
32
|
+
} from '@travetto/runtime';
|
|
33
|
+
import { Required } from '@travetto/schema';
|
|
18
34
|
|
|
19
35
|
type Suffix = '.bin' | '.meta' | '.json' | '.expires';
|
|
20
36
|
|
|
@@ -33,20 +49,23 @@ export class FileModelConfig {
|
|
|
33
49
|
|
|
34
50
|
@PostConstruct()
|
|
35
51
|
async finalizeConfig(): Promise<void> {
|
|
36
|
-
this.folder ??= path.resolve(os.tmpdir(), `trv_file_${Runtime.main.name.replace(/[^a-z]/
|
|
52
|
+
this.folder ??= path.resolve(os.tmpdir(), `trv_file_${Runtime.main.name.replace(/[^a-z]/gi, '_')}`);
|
|
37
53
|
}
|
|
38
54
|
}
|
|
39
55
|
|
|
40
|
-
const exists = (file: string): Promise<boolean> =>
|
|
56
|
+
const exists = (file: string): Promise<boolean> =>
|
|
57
|
+
fs.stat(file).then(
|
|
58
|
+
() => true,
|
|
59
|
+
() => false
|
|
60
|
+
);
|
|
41
61
|
|
|
42
62
|
/**
|
|
43
63
|
* Standard file support
|
|
44
64
|
*/
|
|
45
65
|
@Injectable()
|
|
46
66
|
export class FileModelService implements ModelCrudSupport, ModelBlobSupport, ModelExpirySupport, ModelStorageSupport {
|
|
47
|
-
|
|
48
67
|
/** @private */
|
|
49
|
-
static async *
|
|
68
|
+
static async *scanFolder(folder: string, suffix: string, options?: ModelListOptions): AsyncGenerator<[id: string, field: string][]> {
|
|
50
69
|
const found: [id: string, field: string][] = [];
|
|
51
70
|
const batchSize = options?.batchSizeHint ?? 100;
|
|
52
71
|
const maxCount = options?.limit ?? Number.MAX_SAFE_INTEGER;
|
|
@@ -79,7 +98,9 @@ export class FileModelService implements ModelCrudSupport, ModelBlobSupport, Mod
|
|
|
79
98
|
idSource = ModelCrudUtil.uuidSource();
|
|
80
99
|
config: FileModelConfig;
|
|
81
100
|
|
|
82
|
-
constructor(config: FileModelConfig) {
|
|
101
|
+
constructor(config: FileModelConfig) {
|
|
102
|
+
this.config = config;
|
|
103
|
+
}
|
|
83
104
|
|
|
84
105
|
/**
|
|
85
106
|
* The root location for all activity
|
|
@@ -181,7 +202,7 @@ export class FileModelService implements ModelCrudSupport, ModelBlobSupport, Mod
|
|
|
181
202
|
await fs.unlink(file);
|
|
182
203
|
}
|
|
183
204
|
|
|
184
|
-
async *
|
|
205
|
+
async *list<T extends ModelType>(cls: Class<T>, options?: ModelListOptions): AsyncIterable<T[]> {
|
|
185
206
|
for await (const batch of FileModelService.scanFolder(await this.#resolveName(cls, '.json'), '.json', options)) {
|
|
186
207
|
yield ModelCrudUtil.filterOutNotFound(batch.map(([id]) => this.get(cls, id)));
|
|
187
208
|
}
|
|
@@ -189,16 +210,20 @@ export class FileModelService implements ModelCrudSupport, ModelBlobSupport, Mod
|
|
|
189
210
|
|
|
190
211
|
// Blob
|
|
191
212
|
async upsertBlob(location: string, input: BinaryType, metadata?: BinaryMetadata, overwrite = true): Promise<void> {
|
|
192
|
-
if (
|
|
213
|
+
if (
|
|
214
|
+
!overwrite &&
|
|
215
|
+
(await this.getBlobMetadata(location).then(
|
|
216
|
+
() => true,
|
|
217
|
+
() => false
|
|
218
|
+
))
|
|
219
|
+
) {
|
|
193
220
|
return;
|
|
194
221
|
}
|
|
195
222
|
const resolved = await BinaryMetadataUtil.compute(input, metadata);
|
|
196
223
|
const file = await this.#resolveName(ModelBlobNamespace, BIN, location);
|
|
197
224
|
await Promise.all([
|
|
198
225
|
BinaryUtil.pipeline(input, createWriteStream(file)),
|
|
199
|
-
BinaryUtil.pipeline(
|
|
200
|
-
JSONUtil.toBinaryArray(resolved),
|
|
201
|
-
createWriteStream(file.replace(BIN, META)))
|
|
226
|
+
BinaryUtil.pipeline(JSONUtil.toBinaryArray(resolved), createWriteStream(file.replace(BIN, META)))
|
|
202
227
|
]);
|
|
203
228
|
}
|
|
204
229
|
|
|
@@ -219,10 +244,7 @@ export class FileModelService implements ModelCrudSupport, ModelBlobSupport, Mod
|
|
|
219
244
|
async deleteBlob(location: string): Promise<void> {
|
|
220
245
|
const file = await this.#resolveName(ModelBlobNamespace, BIN, location);
|
|
221
246
|
if (await exists(file)) {
|
|
222
|
-
await Promise.all([
|
|
223
|
-
fs.unlink(file),
|
|
224
|
-
fs.unlink(file.replace('.bin', META))
|
|
225
|
-
]);
|
|
247
|
+
await Promise.all([fs.unlink(file), fs.unlink(file.replace('.bin', META))]);
|
|
226
248
|
} else {
|
|
227
249
|
throw new NotFoundError(ModelBlobNamespace, location);
|
|
228
250
|
}
|
|
@@ -244,7 +266,7 @@ export class FileModelService implements ModelCrudSupport, ModelBlobSupport, Mod
|
|
|
244
266
|
await fs.rm(file, { force: true });
|
|
245
267
|
deleted += 1;
|
|
246
268
|
}
|
|
247
|
-
} catch {
|
|
269
|
+
} catch {} // Don't let a single failure stop the process
|
|
248
270
|
}
|
|
249
271
|
}
|
|
250
272
|
return deleted;
|
|
@@ -267,4 +289,4 @@ export class FileModelService implements ModelCrudSupport, ModelBlobSupport, Mod
|
|
|
267
289
|
async truncateBlob(): Promise<void> {
|
|
268
290
|
await fs.rm(await this.#resolveName(ModelBlobNamespace), { recursive: true, force: true });
|
|
269
291
|
}
|
|
270
|
-
}
|
|
292
|
+
}
|