@2112-lab/central-plant 0.2.12 → 0.3.1
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/bundle/index.js +2095 -11
- package/dist/cjs/src/core/centralPlant.js +1 -1
- package/dist/cjs/src/index.js +36 -1
- package/dist/cjs/src/managers/cache/CacheManager.js +1089 -0
- package/dist/cjs/src/managers/cache/S3CacheService.js +1473 -0
- package/dist/cjs/src/managers/cache/S3MetadataCacheService.js +502 -0
- package/dist/cjs/src/managers/cache/s3Timing.js +124 -0
- package/dist/esm/src/core/centralPlant.js +1 -1
- package/dist/esm/src/index.js +4 -1
- package/dist/esm/src/managers/cache/CacheManager.js +1081 -0
- package/dist/esm/src/managers/cache/S3CacheService.js +1441 -0
- package/dist/esm/src/managers/cache/S3MetadataCacheService.js +497 -0
- package/dist/esm/src/managers/cache/s3Timing.js +120 -0
- package/dist/index.d.ts +119 -0
- package/package.json +2 -1
|
@@ -0,0 +1,497 @@
|
|
|
1
|
+
import { createClass as _createClass, classCallCheck as _classCallCheck, asyncToGenerator as _asyncToGenerator, regenerator as _regenerator, toConsumableArray as _toConsumableArray, objectSpread2 as _objectSpread2 } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import { getCachedJsonData, cacheJsonData, removeCachedJsonData } from './S3CacheService.js';
|
|
3
|
+
|
|
4
|
+
var CACHE_KEY = 's3-component-metadata';
|
|
5
|
+
var CACHE_VERSION = 1;
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Simple mutex implementation for preventing concurrent read-modify-write operations
|
|
9
|
+
*/
|
|
10
|
+
var SimpleMutex = /*#__PURE__*/function () {
|
|
11
|
+
function SimpleMutex() {
|
|
12
|
+
_classCallCheck(this, SimpleMutex);
|
|
13
|
+
this._locked = false;
|
|
14
|
+
this._queue = [];
|
|
15
|
+
}
|
|
16
|
+
return _createClass(SimpleMutex, [{
|
|
17
|
+
key: "acquire",
|
|
18
|
+
value: function () {
|
|
19
|
+
var _acquire = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
20
|
+
var _this = this;
|
|
21
|
+
return _regenerator().w(function (_context) {
|
|
22
|
+
while (1) switch (_context.n) {
|
|
23
|
+
case 0:
|
|
24
|
+
return _context.a(2, new Promise(function (resolve) {
|
|
25
|
+
if (!_this._locked) {
|
|
26
|
+
_this._locked = true;
|
|
27
|
+
resolve();
|
|
28
|
+
} else {
|
|
29
|
+
_this._queue.push(resolve);
|
|
30
|
+
}
|
|
31
|
+
}));
|
|
32
|
+
}
|
|
33
|
+
}, _callee);
|
|
34
|
+
}));
|
|
35
|
+
function acquire() {
|
|
36
|
+
return _acquire.apply(this, arguments);
|
|
37
|
+
}
|
|
38
|
+
return acquire;
|
|
39
|
+
}()
|
|
40
|
+
}, {
|
|
41
|
+
key: "release",
|
|
42
|
+
value: function release() {
|
|
43
|
+
if (this._queue.length > 0) {
|
|
44
|
+
var next = this._queue.shift();
|
|
45
|
+
next();
|
|
46
|
+
} else {
|
|
47
|
+
this._locked = false;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}]);
|
|
51
|
+
}();
|
|
52
|
+
var S3MetadataCacheService = /*#__PURE__*/function () {
|
|
53
|
+
function S3MetadataCacheService() {
|
|
54
|
+
_classCallCheck(this, S3MetadataCacheService);
|
|
55
|
+
this._mutex = new SimpleMutex();
|
|
56
|
+
this._memoryCache = null;
|
|
57
|
+
this._memoryCacheTime = 0;
|
|
58
|
+
this._memoryCacheTTL = 5000; // 5 seconds in-memory cache
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Create empty metadata structure
|
|
63
|
+
*/
|
|
64
|
+
return _createClass(S3MetadataCacheService, [{
|
|
65
|
+
key: "_createEmptyMetadata",
|
|
66
|
+
value: function _createEmptyMetadata() {
|
|
67
|
+
return {
|
|
68
|
+
version: CACHE_VERSION,
|
|
69
|
+
components: [],
|
|
70
|
+
timestamp: Date.now()
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Validate and migrate metadata if needed
|
|
76
|
+
*/
|
|
77
|
+
}, {
|
|
78
|
+
key: "_validateMetadata",
|
|
79
|
+
value: function _validateMetadata(metadata) {
|
|
80
|
+
if (!metadata) {
|
|
81
|
+
return this._createEmptyMetadata();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
// Ensure components array exists
|
|
85
|
+
if (!Array.isArray(metadata.components)) {
|
|
86
|
+
metadata.components = [];
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Add version if missing (for legacy cache)
|
|
90
|
+
if (metadata.version === undefined) {
|
|
91
|
+
metadata.version = CACHE_VERSION;
|
|
92
|
+
}
|
|
93
|
+
return metadata;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Check if memory cache is still valid
|
|
98
|
+
*/
|
|
99
|
+
}, {
|
|
100
|
+
key: "_isMemoryCacheValid",
|
|
101
|
+
value: function _isMemoryCacheValid() {
|
|
102
|
+
return this._memoryCache !== null && Date.now() - this._memoryCacheTime < this._memoryCacheTTL;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Invalidate the memory cache
|
|
107
|
+
*/
|
|
108
|
+
}, {
|
|
109
|
+
key: "_invalidateMemoryCache",
|
|
110
|
+
value: function _invalidateMemoryCache() {
|
|
111
|
+
this._memoryCache = null;
|
|
112
|
+
this._memoryCacheTime = 0;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* Get all cached components
|
|
117
|
+
* @returns {Promise<Array>} Array of cached component metadata
|
|
118
|
+
*/
|
|
119
|
+
}, {
|
|
120
|
+
key: "getAll",
|
|
121
|
+
value: (function () {
|
|
122
|
+
var _getAll = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2() {
|
|
123
|
+
var metadata, validated, _t;
|
|
124
|
+
return _regenerator().w(function (_context2) {
|
|
125
|
+
while (1) switch (_context2.n) {
|
|
126
|
+
case 0:
|
|
127
|
+
if (!this._isMemoryCacheValid()) {
|
|
128
|
+
_context2.n = 1;
|
|
129
|
+
break;
|
|
130
|
+
}
|
|
131
|
+
return _context2.a(2, _toConsumableArray(this._memoryCache.components));
|
|
132
|
+
case 1:
|
|
133
|
+
_context2.p = 1;
|
|
134
|
+
_context2.n = 2;
|
|
135
|
+
return getCachedJsonData(CACHE_KEY);
|
|
136
|
+
case 2:
|
|
137
|
+
metadata = _context2.v;
|
|
138
|
+
validated = this._validateMetadata(metadata); // Update memory cache
|
|
139
|
+
this._memoryCache = validated;
|
|
140
|
+
this._memoryCacheTime = Date.now();
|
|
141
|
+
return _context2.a(2, _toConsumableArray(validated.components));
|
|
142
|
+
case 3:
|
|
143
|
+
_context2.p = 3;
|
|
144
|
+
_t = _context2.v;
|
|
145
|
+
console.warn('⚠️ S3MetadataCacheService: Failed to get components:', _t);
|
|
146
|
+
return _context2.a(2, []);
|
|
147
|
+
}
|
|
148
|
+
}, _callee2, this, [[1, 3]]);
|
|
149
|
+
}));
|
|
150
|
+
function getAll() {
|
|
151
|
+
return _getAll.apply(this, arguments);
|
|
152
|
+
}
|
|
153
|
+
return getAll;
|
|
154
|
+
}()
|
|
155
|
+
/**
|
|
156
|
+
* Get the full metadata object (for advanced use cases)
|
|
157
|
+
* @returns {Promise<Object>} Full metadata object with version, components, timestamp
|
|
158
|
+
*/
|
|
159
|
+
)
|
|
160
|
+
}, {
|
|
161
|
+
key: "getMetadata",
|
|
162
|
+
value: (function () {
|
|
163
|
+
var _getMetadata = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee3() {
|
|
164
|
+
var metadata, validated, _t2;
|
|
165
|
+
return _regenerator().w(function (_context3) {
|
|
166
|
+
while (1) switch (_context3.n) {
|
|
167
|
+
case 0:
|
|
168
|
+
if (!this._isMemoryCacheValid()) {
|
|
169
|
+
_context3.n = 1;
|
|
170
|
+
break;
|
|
171
|
+
}
|
|
172
|
+
return _context3.a(2, _objectSpread2({}, this._memoryCache));
|
|
173
|
+
case 1:
|
|
174
|
+
_context3.p = 1;
|
|
175
|
+
_context3.n = 2;
|
|
176
|
+
return getCachedJsonData(CACHE_KEY);
|
|
177
|
+
case 2:
|
|
178
|
+
metadata = _context3.v;
|
|
179
|
+
validated = this._validateMetadata(metadata);
|
|
180
|
+
this._memoryCache = validated;
|
|
181
|
+
this._memoryCacheTime = Date.now();
|
|
182
|
+
return _context3.a(2, _objectSpread2({}, validated));
|
|
183
|
+
case 3:
|
|
184
|
+
_context3.p = 3;
|
|
185
|
+
_t2 = _context3.v;
|
|
186
|
+
console.warn('⚠️ S3MetadataCacheService: Failed to get metadata:', _t2);
|
|
187
|
+
return _context3.a(2, this._createEmptyMetadata());
|
|
188
|
+
}
|
|
189
|
+
}, _callee3, this, [[1, 3]]);
|
|
190
|
+
}));
|
|
191
|
+
function getMetadata() {
|
|
192
|
+
return _getMetadata.apply(this, arguments);
|
|
193
|
+
}
|
|
194
|
+
return getMetadata;
|
|
195
|
+
}()
|
|
196
|
+
/**
|
|
197
|
+
* Add or update a component in the cache
|
|
198
|
+
* Uses mutex to prevent race conditions
|
|
199
|
+
* @param {Object} component - Component metadata to add/update
|
|
200
|
+
* @returns {Promise<boolean>} Success status
|
|
201
|
+
*/
|
|
202
|
+
)
|
|
203
|
+
}, {
|
|
204
|
+
key: "addComponent",
|
|
205
|
+
value: (function () {
|
|
206
|
+
var _addComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee4(component) {
|
|
207
|
+
var metadata, validated, existingIndex, _t3;
|
|
208
|
+
return _regenerator().w(function (_context4) {
|
|
209
|
+
while (1) switch (_context4.n) {
|
|
210
|
+
case 0:
|
|
211
|
+
if (!(!component || !component.id && !component.uuid)) {
|
|
212
|
+
_context4.n = 1;
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
console.warn('⚠️ S3MetadataCacheService: Cannot add component without id or uuid');
|
|
216
|
+
return _context4.a(2, false);
|
|
217
|
+
case 1:
|
|
218
|
+
_context4.n = 2;
|
|
219
|
+
return this._mutex.acquire();
|
|
220
|
+
case 2:
|
|
221
|
+
_context4.p = 2;
|
|
222
|
+
_context4.n = 3;
|
|
223
|
+
return getCachedJsonData(CACHE_KEY);
|
|
224
|
+
case 3:
|
|
225
|
+
metadata = _context4.v;
|
|
226
|
+
validated = this._validateMetadata(metadata); // Remove existing entry if it exists (by id or uuid)
|
|
227
|
+
existingIndex = validated.components.findIndex(function (c) {
|
|
228
|
+
return c.id === component.id || c.uuid === component.uuid || component.id && c.uuid === component.id || component.uuid && c.id === component.uuid;
|
|
229
|
+
});
|
|
230
|
+
if (existingIndex !== -1) {
|
|
231
|
+
validated.components.splice(existingIndex, 1);
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
// Add new component
|
|
235
|
+
validated.components.push(component);
|
|
236
|
+
validated.timestamp = Date.now();
|
|
237
|
+
|
|
238
|
+
// Write back to cache
|
|
239
|
+
_context4.n = 4;
|
|
240
|
+
return cacheJsonData(CACHE_KEY, validated);
|
|
241
|
+
case 4:
|
|
242
|
+
// Update memory cache
|
|
243
|
+
this._memoryCache = validated;
|
|
244
|
+
this._memoryCacheTime = Date.now();
|
|
245
|
+
console.log("\uD83D\uDCBE S3MetadataCacheService: Added/updated component ".concat(component.name || component.id));
|
|
246
|
+
return _context4.a(2, true);
|
|
247
|
+
case 5:
|
|
248
|
+
_context4.p = 5;
|
|
249
|
+
_t3 = _context4.v;
|
|
250
|
+
console.error('❌ S3MetadataCacheService: Failed to add component:', _t3);
|
|
251
|
+
return _context4.a(2, false);
|
|
252
|
+
case 6:
|
|
253
|
+
_context4.p = 6;
|
|
254
|
+
this._mutex.release();
|
|
255
|
+
return _context4.f(6);
|
|
256
|
+
case 7:
|
|
257
|
+
return _context4.a(2);
|
|
258
|
+
}
|
|
259
|
+
}, _callee4, this, [[2, 5, 6, 7]]);
|
|
260
|
+
}));
|
|
261
|
+
function addComponent(_x) {
|
|
262
|
+
return _addComponent.apply(this, arguments);
|
|
263
|
+
}
|
|
264
|
+
return addComponent;
|
|
265
|
+
}()
|
|
266
|
+
/**
|
|
267
|
+
* Remove a component from the cache
|
|
268
|
+
* Uses mutex to prevent race conditions
|
|
269
|
+
* @param {string} identifier - Component id or uuid to remove
|
|
270
|
+
* @returns {Promise<boolean>} Success status
|
|
271
|
+
*/
|
|
272
|
+
)
|
|
273
|
+
}, {
|
|
274
|
+
key: "removeComponent",
|
|
275
|
+
value: (function () {
|
|
276
|
+
var _removeComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee5(identifier) {
|
|
277
|
+
var metadata, validated, originalLength, removed, _t4;
|
|
278
|
+
return _regenerator().w(function (_context5) {
|
|
279
|
+
while (1) switch (_context5.n) {
|
|
280
|
+
case 0:
|
|
281
|
+
if (identifier) {
|
|
282
|
+
_context5.n = 1;
|
|
283
|
+
break;
|
|
284
|
+
}
|
|
285
|
+
console.warn('⚠️ S3MetadataCacheService: Cannot remove component without identifier');
|
|
286
|
+
return _context5.a(2, false);
|
|
287
|
+
case 1:
|
|
288
|
+
_context5.n = 2;
|
|
289
|
+
return this._mutex.acquire();
|
|
290
|
+
case 2:
|
|
291
|
+
_context5.p = 2;
|
|
292
|
+
_context5.n = 3;
|
|
293
|
+
return getCachedJsonData(CACHE_KEY);
|
|
294
|
+
case 3:
|
|
295
|
+
metadata = _context5.v;
|
|
296
|
+
if (!(!metadata || !metadata.components)) {
|
|
297
|
+
_context5.n = 4;
|
|
298
|
+
break;
|
|
299
|
+
}
|
|
300
|
+
console.log('ℹ️ S3MetadataCacheService: No metadata to remove from');
|
|
301
|
+
return _context5.a(2, true);
|
|
302
|
+
case 4:
|
|
303
|
+
validated = this._validateMetadata(metadata);
|
|
304
|
+
originalLength = validated.components.length; // Filter out the component by both id and uuid
|
|
305
|
+
validated.components = validated.components.filter(function (c) {
|
|
306
|
+
return c.id !== identifier && c.uuid !== identifier;
|
|
307
|
+
});
|
|
308
|
+
removed = originalLength !== validated.components.length;
|
|
309
|
+
if (!removed) {
|
|
310
|
+
_context5.n = 6;
|
|
311
|
+
break;
|
|
312
|
+
}
|
|
313
|
+
validated.timestamp = Date.now();
|
|
314
|
+
_context5.n = 5;
|
|
315
|
+
return cacheJsonData(CACHE_KEY, validated);
|
|
316
|
+
case 5:
|
|
317
|
+
// Update memory cache
|
|
318
|
+
this._memoryCache = validated;
|
|
319
|
+
this._memoryCacheTime = Date.now();
|
|
320
|
+
console.log("\uD83D\uDDD1\uFE0F S3MetadataCacheService: Removed component ".concat(identifier));
|
|
321
|
+
case 6:
|
|
322
|
+
return _context5.a(2, true);
|
|
323
|
+
case 7:
|
|
324
|
+
_context5.p = 7;
|
|
325
|
+
_t4 = _context5.v;
|
|
326
|
+
console.error('❌ S3MetadataCacheService: Failed to remove component:', _t4);
|
|
327
|
+
return _context5.a(2, false);
|
|
328
|
+
case 8:
|
|
329
|
+
_context5.p = 8;
|
|
330
|
+
this._mutex.release();
|
|
331
|
+
return _context5.f(8);
|
|
332
|
+
case 9:
|
|
333
|
+
return _context5.a(2);
|
|
334
|
+
}
|
|
335
|
+
}, _callee5, this, [[2, 7, 8, 9]]);
|
|
336
|
+
}));
|
|
337
|
+
function removeComponent(_x2) {
|
|
338
|
+
return _removeComponent.apply(this, arguments);
|
|
339
|
+
}
|
|
340
|
+
return removeComponent;
|
|
341
|
+
}()
|
|
342
|
+
/**
|
|
343
|
+
* Clear all cached metadata
|
|
344
|
+
* @returns {Promise<boolean>} Success status
|
|
345
|
+
*/
|
|
346
|
+
)
|
|
347
|
+
}, {
|
|
348
|
+
key: "clear",
|
|
349
|
+
value: (function () {
|
|
350
|
+
var _clear = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee6() {
|
|
351
|
+
var _t5;
|
|
352
|
+
return _regenerator().w(function (_context6) {
|
|
353
|
+
while (1) switch (_context6.n) {
|
|
354
|
+
case 0:
|
|
355
|
+
_context6.n = 1;
|
|
356
|
+
return this._mutex.acquire();
|
|
357
|
+
case 1:
|
|
358
|
+
_context6.p = 1;
|
|
359
|
+
_context6.n = 2;
|
|
360
|
+
return removeCachedJsonData(CACHE_KEY);
|
|
361
|
+
case 2:
|
|
362
|
+
this._invalidateMemoryCache();
|
|
363
|
+
console.log('🗑️ S3MetadataCacheService: Cleared all metadata');
|
|
364
|
+
return _context6.a(2, true);
|
|
365
|
+
case 3:
|
|
366
|
+
_context6.p = 3;
|
|
367
|
+
_t5 = _context6.v;
|
|
368
|
+
console.error('❌ S3MetadataCacheService: Failed to clear metadata:', _t5);
|
|
369
|
+
return _context6.a(2, false);
|
|
370
|
+
case 4:
|
|
371
|
+
_context6.p = 4;
|
|
372
|
+
this._mutex.release();
|
|
373
|
+
return _context6.f(4);
|
|
374
|
+
case 5:
|
|
375
|
+
return _context6.a(2);
|
|
376
|
+
}
|
|
377
|
+
}, _callee6, this, [[1, 3, 4, 5]]);
|
|
378
|
+
}));
|
|
379
|
+
function clear() {
|
|
380
|
+
return _clear.apply(this, arguments);
|
|
381
|
+
}
|
|
382
|
+
return clear;
|
|
383
|
+
}()
|
|
384
|
+
/**
|
|
385
|
+
* Check if a component exists in the cache
|
|
386
|
+
* @param {string} identifier - Component id or uuid
|
|
387
|
+
* @returns {Promise<boolean>} True if exists
|
|
388
|
+
*/
|
|
389
|
+
)
|
|
390
|
+
}, {
|
|
391
|
+
key: "hasComponent",
|
|
392
|
+
value: (function () {
|
|
393
|
+
var _hasComponent = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee7(identifier) {
|
|
394
|
+
var components;
|
|
395
|
+
return _regenerator().w(function (_context7) {
|
|
396
|
+
while (1) switch (_context7.n) {
|
|
397
|
+
case 0:
|
|
398
|
+
_context7.n = 1;
|
|
399
|
+
return this.getAll();
|
|
400
|
+
case 1:
|
|
401
|
+
components = _context7.v;
|
|
402
|
+
return _context7.a(2, components.some(function (c) {
|
|
403
|
+
return c.id === identifier || c.uuid === identifier;
|
|
404
|
+
}));
|
|
405
|
+
}
|
|
406
|
+
}, _callee7, this);
|
|
407
|
+
}));
|
|
408
|
+
function hasComponent(_x3) {
|
|
409
|
+
return _hasComponent.apply(this, arguments);
|
|
410
|
+
}
|
|
411
|
+
return hasComponent;
|
|
412
|
+
}()
|
|
413
|
+
/**
|
|
414
|
+
* Force refresh from persistent cache (bypass memory cache)
|
|
415
|
+
* @returns {Promise<Array>} Array of cached components
|
|
416
|
+
*/
|
|
417
|
+
)
|
|
418
|
+
}, {
|
|
419
|
+
key: "refresh",
|
|
420
|
+
value: (function () {
|
|
421
|
+
var _refresh = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee8() {
|
|
422
|
+
return _regenerator().w(function (_context8) {
|
|
423
|
+
while (1) switch (_context8.n) {
|
|
424
|
+
case 0:
|
|
425
|
+
this._invalidateMemoryCache();
|
|
426
|
+
return _context8.a(2, this.getAll());
|
|
427
|
+
}
|
|
428
|
+
}, _callee8, this);
|
|
429
|
+
}));
|
|
430
|
+
function refresh() {
|
|
431
|
+
return _refresh.apply(this, arguments);
|
|
432
|
+
}
|
|
433
|
+
return refresh;
|
|
434
|
+
}()
|
|
435
|
+
/**
|
|
436
|
+
* Replace all cached components with a new array
|
|
437
|
+
* Used for bulk operations like initial fetch
|
|
438
|
+
* @param {Array} components - Array of components to cache
|
|
439
|
+
* @returns {Promise<boolean>} Success status
|
|
440
|
+
*/
|
|
441
|
+
)
|
|
442
|
+
}, {
|
|
443
|
+
key: "setAll",
|
|
444
|
+
value: (function () {
|
|
445
|
+
var _setAll = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee9(components) {
|
|
446
|
+
var metadata, _t6;
|
|
447
|
+
return _regenerator().w(function (_context9) {
|
|
448
|
+
while (1) switch (_context9.n) {
|
|
449
|
+
case 0:
|
|
450
|
+
if (Array.isArray(components)) {
|
|
451
|
+
_context9.n = 1;
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
454
|
+
console.warn('⚠️ S3MetadataCacheService: setAll requires an array');
|
|
455
|
+
return _context9.a(2, false);
|
|
456
|
+
case 1:
|
|
457
|
+
_context9.n = 2;
|
|
458
|
+
return this._mutex.acquire();
|
|
459
|
+
case 2:
|
|
460
|
+
_context9.p = 2;
|
|
461
|
+
metadata = {
|
|
462
|
+
version: CACHE_VERSION,
|
|
463
|
+
components: components,
|
|
464
|
+
timestamp: Date.now()
|
|
465
|
+
};
|
|
466
|
+
_context9.n = 3;
|
|
467
|
+
return cacheJsonData(CACHE_KEY, metadata);
|
|
468
|
+
case 3:
|
|
469
|
+
// Update memory cache
|
|
470
|
+
this._memoryCache = metadata;
|
|
471
|
+
this._memoryCacheTime = Date.now();
|
|
472
|
+
console.log("\uD83D\uDCBE S3MetadataCacheService: Set ".concat(components.length, " components"));
|
|
473
|
+
return _context9.a(2, true);
|
|
474
|
+
case 4:
|
|
475
|
+
_context9.p = 4;
|
|
476
|
+
_t6 = _context9.v;
|
|
477
|
+
console.error('❌ S3MetadataCacheService: Failed to set components:', _t6);
|
|
478
|
+
return _context9.a(2, false);
|
|
479
|
+
case 5:
|
|
480
|
+
_context9.p = 5;
|
|
481
|
+
this._mutex.release();
|
|
482
|
+
return _context9.f(5);
|
|
483
|
+
case 6:
|
|
484
|
+
return _context9.a(2);
|
|
485
|
+
}
|
|
486
|
+
}, _callee9, this, [[2, 4, 5, 6]]);
|
|
487
|
+
}));
|
|
488
|
+
function setAll(_x4) {
|
|
489
|
+
return _setAll.apply(this, arguments);
|
|
490
|
+
}
|
|
491
|
+
return setAll;
|
|
492
|
+
}())
|
|
493
|
+
}]);
|
|
494
|
+
}(); // Export singleton instance
|
|
495
|
+
var s3MetadataCache = new S3MetadataCacheService();
|
|
496
|
+
|
|
497
|
+
export { S3MetadataCacheService, s3MetadataCache };
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { asyncToGenerator as _asyncToGenerator, regenerator as _regenerator } from '../../../_virtual/_rollupPluginBabelHelpers.js';
|
|
2
|
+
import { cacheManager } from './CacheManager.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Retrieve the injected Auth instance from cacheManager config.
|
|
6
|
+
* Falls back gracefully if not configured (skip credential refresh).
|
|
7
|
+
*/
|
|
8
|
+
function getAuth() {
|
|
9
|
+
return cacheManager.config.auth || null;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Measure S3 operation time and log results
|
|
14
|
+
* @param {string} operation - Operation name (e.g., "Upload GLB", "Download JSON")
|
|
15
|
+
* @param {Function} asyncFn - Async function to measure
|
|
16
|
+
* @param {number} fileSize - Optional file size in bytes for speed calculation
|
|
17
|
+
* @returns {Promise} - Result from asyncFn
|
|
18
|
+
*/
|
|
19
|
+
function measureS3Transfer(_x, _x2) {
|
|
20
|
+
return _measureS3Transfer.apply(this, arguments);
|
|
21
|
+
}
|
|
22
|
+
function _measureS3Transfer() {
|
|
23
|
+
_measureS3Transfer = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee2(operation, asyncFn) {
|
|
24
|
+
var fileSize,
|
|
25
|
+
startTime,
|
|
26
|
+
executeTransfer,
|
|
27
|
+
Auth,
|
|
28
|
+
endTime,
|
|
29
|
+
duration,
|
|
30
|
+
_args2 = arguments,
|
|
31
|
+
_t,
|
|
32
|
+
_t2;
|
|
33
|
+
return _regenerator().w(function (_context2) {
|
|
34
|
+
while (1) switch (_context2.n) {
|
|
35
|
+
case 0:
|
|
36
|
+
fileSize = _args2.length > 2 && _args2[2] !== undefined ? _args2[2] : null;
|
|
37
|
+
startTime = performance.now();
|
|
38
|
+
executeTransfer = /*#__PURE__*/function () {
|
|
39
|
+
var _ref = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee() {
|
|
40
|
+
var result, endTime, duration, logMessage, sizeMB, speedMBps;
|
|
41
|
+
return _regenerator().w(function (_context) {
|
|
42
|
+
while (1) switch (_context.n) {
|
|
43
|
+
case 0:
|
|
44
|
+
_context.n = 1;
|
|
45
|
+
return asyncFn();
|
|
46
|
+
case 1:
|
|
47
|
+
result = _context.v;
|
|
48
|
+
endTime = performance.now();
|
|
49
|
+
duration = ((endTime - startTime) / 1000).toFixed(3); // Convert to seconds
|
|
50
|
+
logMessage = "\u23F1\uFE0F S3 ".concat(operation, ": ").concat(duration, "s");
|
|
51
|
+
if (fileSize) {
|
|
52
|
+
sizeMB = (fileSize / (1024 * 1024)).toFixed(2);
|
|
53
|
+
speedMBps = (sizeMB / duration).toFixed(2);
|
|
54
|
+
logMessage += " (".concat(sizeMB, " MB @ ").concat(speedMBps, " MB/s)");
|
|
55
|
+
}
|
|
56
|
+
console.log(logMessage);
|
|
57
|
+
return _context.a(2, result);
|
|
58
|
+
}
|
|
59
|
+
}, _callee);
|
|
60
|
+
}));
|
|
61
|
+
return function executeTransfer() {
|
|
62
|
+
return _ref.apply(this, arguments);
|
|
63
|
+
};
|
|
64
|
+
}();
|
|
65
|
+
_context2.p = 1;
|
|
66
|
+
_context2.n = 2;
|
|
67
|
+
return executeTransfer();
|
|
68
|
+
case 2:
|
|
69
|
+
return _context2.a(2, _context2.v);
|
|
70
|
+
case 3:
|
|
71
|
+
_context2.p = 3;
|
|
72
|
+
_t = _context2.v;
|
|
73
|
+
if (!(_t.code === 'ExpiredToken' || _t.message && _t.message.includes('ExpiredToken'))) {
|
|
74
|
+
_context2.n = 8;
|
|
75
|
+
break;
|
|
76
|
+
}
|
|
77
|
+
console.warn("\u26A0\uFE0F Token expired during ".concat(operation, ". Attempting session refresh and retry..."));
|
|
78
|
+
Auth = getAuth();
|
|
79
|
+
if (Auth) {
|
|
80
|
+
_context2.n = 4;
|
|
81
|
+
break;
|
|
82
|
+
}
|
|
83
|
+
console.error("\u274C Cannot refresh credentials: Auth not injected via cacheManager.configure({ auth })");
|
|
84
|
+
throw _t;
|
|
85
|
+
case 4:
|
|
86
|
+
_context2.p = 4;
|
|
87
|
+
_context2.n = 5;
|
|
88
|
+
return Auth.currentCredentials({
|
|
89
|
+
bypassCache: true
|
|
90
|
+
});
|
|
91
|
+
case 5:
|
|
92
|
+
console.log("\u2705 Session refreshed. Retrying ".concat(operation, "..."));
|
|
93
|
+
|
|
94
|
+
// Reset timer for the retry
|
|
95
|
+
startTime = performance.now();
|
|
96
|
+
_context2.n = 6;
|
|
97
|
+
return executeTransfer();
|
|
98
|
+
case 6:
|
|
99
|
+
return _context2.a(2, _context2.v);
|
|
100
|
+
case 7:
|
|
101
|
+
_context2.p = 7;
|
|
102
|
+
_t2 = _context2.v;
|
|
103
|
+
console.error("\u274C Retry failed for ".concat(operation, ":"), _t2);
|
|
104
|
+
// If retry fails, throw the Retry Error (likely unrelated or persistent auth issue)
|
|
105
|
+
throw _t2;
|
|
106
|
+
case 8:
|
|
107
|
+
// Standard error handling for non-expired tokens (or if logic above didn't catch it)
|
|
108
|
+
endTime = performance.now();
|
|
109
|
+
duration = ((endTime - startTime) / 1000).toFixed(3);
|
|
110
|
+
console.error("\u274C S3 ".concat(operation, " failed after ").concat(duration, "s:"), _t);
|
|
111
|
+
throw _t;
|
|
112
|
+
case 9:
|
|
113
|
+
return _context2.a(2);
|
|
114
|
+
}
|
|
115
|
+
}, _callee2, null, [[4, 7], [1, 3]]);
|
|
116
|
+
}));
|
|
117
|
+
return _measureS3Transfer.apply(this, arguments);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export { measureS3Transfer };
|