nuxt-filer 0.0.14 → 0.0.15
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/module.json
CHANGED
|
@@ -1,4 +1,17 @@
|
|
|
1
1
|
import { randomUUID } from "node:crypto";
|
|
2
|
+
async function mapWithConcurrency(items, limit, fn) {
|
|
3
|
+
const results = new Array(items.length);
|
|
4
|
+
let next = 0;
|
|
5
|
+
const worker = async () => {
|
|
6
|
+
while (next < items.length) {
|
|
7
|
+
const index = next++;
|
|
8
|
+
results[index] = await fn(items[index], index);
|
|
9
|
+
}
|
|
10
|
+
};
|
|
11
|
+
const workers = Array.from({ length: Math.min(limit, items.length) || 1 }, worker);
|
|
12
|
+
await Promise.all(workers);
|
|
13
|
+
return results;
|
|
14
|
+
}
|
|
2
15
|
export function createS3Provider(options) {
|
|
3
16
|
const prefix = options.prefix ? options.prefix.replace(/\/+$/, "") + "/" : "";
|
|
4
17
|
let clientPromise;
|
|
@@ -67,11 +80,14 @@ export function createS3Provider(options) {
|
|
|
67
80
|
},
|
|
68
81
|
async list(groupId) {
|
|
69
82
|
const client = await getClient();
|
|
83
|
+
const keys = [];
|
|
84
|
+
for await (const key of client.listKeys(metaPrefix(groupId))) keys.push(key);
|
|
85
|
+
const metas = await mapWithConcurrency(keys, 32, (key) => readMeta(client, key));
|
|
70
86
|
const files = [];
|
|
71
|
-
for
|
|
72
|
-
const meta =
|
|
87
|
+
for (let i = 0; i < keys.length; i++) {
|
|
88
|
+
const meta = metas[i];
|
|
73
89
|
if (!meta) continue;
|
|
74
|
-
files.push(toStoredFile(idFromKey(
|
|
90
|
+
files.push(toStoredFile(idFromKey(keys[i]), groupId, meta));
|
|
75
91
|
}
|
|
76
92
|
return files;
|
|
77
93
|
},
|
package/package.json
CHANGED
|
@@ -38,6 +38,31 @@ export interface S3ProviderOptions {
|
|
|
38
38
|
|
|
39
39
|
type InternalMeta = FileMeta & { _createdAt?: string; _updatedAt?: string };
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Map over `items` with at most `limit` promises in flight, preserving order.
|
|
43
|
+
* Used to read many meta objects concurrently instead of one-at-a-time — on a
|
|
44
|
+
* remote store (R2/S3) the per-object round-trip latency dominates, so a
|
|
45
|
+
* sequential `for await` over N files is ~N × RTT. Bounded so a huge group
|
|
46
|
+
* doesn't open thousands of sockets at once.
|
|
47
|
+
*/
|
|
48
|
+
async function mapWithConcurrency<T, R>(
|
|
49
|
+
items: T[],
|
|
50
|
+
limit: number,
|
|
51
|
+
fn: (item: T, index: number) => Promise<R>,
|
|
52
|
+
): Promise<R[]> {
|
|
53
|
+
const results = new Array<R>(items.length);
|
|
54
|
+
let next = 0;
|
|
55
|
+
const worker = async () => {
|
|
56
|
+
while (next < items.length) {
|
|
57
|
+
const index = next++;
|
|
58
|
+
results[index] = await fn(items[index], index);
|
|
59
|
+
}
|
|
60
|
+
};
|
|
61
|
+
const workers = Array.from({ length: Math.min(limit, items.length) || 1 }, worker);
|
|
62
|
+
await Promise.all(workers);
|
|
63
|
+
return results;
|
|
64
|
+
}
|
|
65
|
+
|
|
41
66
|
/**
|
|
42
67
|
* S3-backed {@link FileStorageProvider}. Binary data and a JSON metadata
|
|
43
68
|
* sidecar are stored as separate objects per file, mirroring the built-in
|
|
@@ -143,11 +168,17 @@ export function createS3Provider(options: S3ProviderOptions): FileStorageProvide
|
|
|
143
168
|
|
|
144
169
|
async list(groupId) {
|
|
145
170
|
const client = await getClient();
|
|
171
|
+
// Enumerate the group's meta keys (cheap paginated LIST), then read every
|
|
172
|
+
// meta object in parallel. The previous sequential read was one blocking
|
|
173
|
+
// GET per file, so listing a group cost ~N round-trips to the store.
|
|
174
|
+
const keys: string[] = [];
|
|
175
|
+
for await (const key of client.listKeys(metaPrefix(groupId))) keys.push(key);
|
|
176
|
+
const metas = await mapWithConcurrency(keys, 32, (key) => readMeta(client, key));
|
|
146
177
|
const files: StoredFile[] = [];
|
|
147
|
-
for
|
|
148
|
-
const meta =
|
|
178
|
+
for (let i = 0; i < keys.length; i++) {
|
|
179
|
+
const meta = metas[i];
|
|
149
180
|
if (!meta) continue;
|
|
150
|
-
files.push(toStoredFile(idFromKey(
|
|
181
|
+
files.push(toStoredFile(idFromKey(keys[i]), groupId, meta));
|
|
151
182
|
}
|
|
152
183
|
return files;
|
|
153
184
|
},
|