@vived/host 4.7.0 → 4.8.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/cjs/Assets/UCs/GetAssetBlobURLUC.js +104 -27
- package/dist/cjs/Assets/UCs/GetAssetBlobURLUC.js.map +1 -1
- package/dist/cjs/Assets/UCs/GetAssetFileUC.js +111 -34
- package/dist/cjs/Assets/UCs/GetAssetFileUC.js.map +1 -1
- package/dist/cjs/Cache/Controllers/clearCache.js +13 -0
- package/dist/cjs/Cache/Controllers/clearCache.js.map +1 -0
- package/dist/cjs/Cache/Controllers/index.js +18 -0
- package/dist/cjs/Cache/Controllers/index.js.map +1 -0
- package/dist/cjs/Cache/Entities/AssetCacheEntity.js +95 -0
- package/dist/cjs/Cache/Entities/AssetCacheEntity.js.map +1 -0
- package/dist/cjs/Cache/Entities/CacheEntity.js +54 -0
- package/dist/cjs/Cache/Entities/CacheEntity.js.map +1 -0
- package/dist/cjs/Cache/Entities/ScriptCacheEntity.js +137 -0
- package/dist/cjs/Cache/Entities/ScriptCacheEntity.js.map +1 -0
- package/dist/cjs/Cache/Entities/index.js +25 -0
- package/dist/cjs/Cache/Entities/index.js.map +1 -0
- package/dist/cjs/Cache/Factories/index.js +18 -0
- package/dist/cjs/Cache/Factories/index.js.map +1 -0
- package/dist/cjs/Cache/Factories/setupCache.js +25 -0
- package/dist/cjs/Cache/Factories/setupCache.js.map +1 -0
- package/dist/cjs/Cache/Mocks/MockCacheEntity.js +22 -0
- package/dist/cjs/Cache/Mocks/MockCacheEntity.js.map +1 -0
- package/dist/cjs/Cache/Mocks/MockGetAssetFromCacheUC.js +19 -0
- package/dist/cjs/Cache/Mocks/MockGetAssetFromCacheUC.js.map +1 -0
- package/dist/cjs/Cache/Mocks/MockGetScriptFromCacheUC.js +22 -0
- package/dist/cjs/Cache/Mocks/MockGetScriptFromCacheUC.js.map +1 -0
- package/dist/cjs/Cache/Mocks/MockStoreAssetInCacheUC.js +17 -0
- package/dist/cjs/Cache/Mocks/MockStoreAssetInCacheUC.js.map +1 -0
- package/dist/cjs/Cache/Mocks/MockStoreScriptInCacheUC.js +22 -0
- package/dist/cjs/Cache/Mocks/MockStoreScriptInCacheUC.js.map +1 -0
- package/dist/cjs/Cache/Mocks/index.js +22 -0
- package/dist/cjs/Cache/Mocks/index.js.map +1 -0
- package/dist/cjs/Cache/UCs/GetAssetFromCacheUC.js +40 -0
- package/dist/cjs/Cache/UCs/GetAssetFromCacheUC.js.map +1 -0
- package/dist/cjs/Cache/UCs/GetScriptFromCacheUC.js +49 -0
- package/dist/cjs/Cache/UCs/GetScriptFromCacheUC.js.map +1 -0
- package/dist/cjs/Cache/UCs/StoreAssetInCacheUC.js +39 -0
- package/dist/cjs/Cache/UCs/StoreAssetInCacheUC.js.map +1 -0
- package/dist/cjs/Cache/UCs/StoreScriptInCacheUC.js +48 -0
- package/dist/cjs/Cache/UCs/StoreScriptInCacheUC.js.map +1 -0
- package/dist/cjs/Cache/UCs/index.js +26 -0
- package/dist/cjs/Cache/UCs/index.js.map +1 -0
- package/dist/cjs/Cache/index.js +21 -0
- package/dist/cjs/Cache/index.js.map +1 -0
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/Assets/UCs/GetAssetBlobURLUC.js +104 -27
- package/dist/esm/Assets/UCs/GetAssetBlobURLUC.js.map +1 -1
- package/dist/esm/Assets/UCs/GetAssetFileUC.js +111 -34
- package/dist/esm/Assets/UCs/GetAssetFileUC.js.map +1 -1
- package/dist/esm/Cache/Controllers/clearCache.js +10 -0
- package/dist/esm/Cache/Controllers/clearCache.js.map +1 -0
- package/dist/esm/Cache/Controllers/index.js +2 -0
- package/dist/esm/Cache/Controllers/index.js.map +1 -0
- package/dist/esm/Cache/Entities/AssetCacheEntity.js +90 -0
- package/dist/esm/Cache/Entities/AssetCacheEntity.js.map +1 -0
- package/dist/esm/Cache/Entities/CacheEntity.js +49 -0
- package/dist/esm/Cache/Entities/CacheEntity.js.map +1 -0
- package/dist/esm/Cache/Entities/ScriptCacheEntity.js +132 -0
- package/dist/esm/Cache/Entities/ScriptCacheEntity.js.map +1 -0
- package/dist/esm/Cache/Entities/index.js +9 -0
- package/dist/esm/Cache/Entities/index.js.map +1 -0
- package/dist/esm/Cache/Factories/index.js +2 -0
- package/dist/esm/Cache/Factories/index.js.map +1 -0
- package/dist/esm/Cache/Factories/setupCache.js +22 -0
- package/dist/esm/Cache/Factories/setupCache.js.map +1 -0
- package/dist/esm/Cache/Mocks/MockCacheEntity.js +17 -0
- package/dist/esm/Cache/Mocks/MockCacheEntity.js.map +1 -0
- package/dist/esm/Cache/Mocks/MockGetAssetFromCacheUC.js +14 -0
- package/dist/esm/Cache/Mocks/MockGetAssetFromCacheUC.js.map +1 -0
- package/dist/esm/Cache/Mocks/MockGetScriptFromCacheUC.js +17 -0
- package/dist/esm/Cache/Mocks/MockGetScriptFromCacheUC.js.map +1 -0
- package/dist/esm/Cache/Mocks/MockStoreAssetInCacheUC.js +12 -0
- package/dist/esm/Cache/Mocks/MockStoreAssetInCacheUC.js.map +1 -0
- package/dist/esm/Cache/Mocks/MockStoreScriptInCacheUC.js +17 -0
- package/dist/esm/Cache/Mocks/MockStoreScriptInCacheUC.js.map +1 -0
- package/dist/esm/Cache/Mocks/index.js +6 -0
- package/dist/esm/Cache/Mocks/index.js.map +1 -0
- package/dist/esm/Cache/UCs/GetAssetFromCacheUC.js +35 -0
- package/dist/esm/Cache/UCs/GetAssetFromCacheUC.js.map +1 -0
- package/dist/esm/Cache/UCs/GetScriptFromCacheUC.js +44 -0
- package/dist/esm/Cache/UCs/GetScriptFromCacheUC.js.map +1 -0
- package/dist/esm/Cache/UCs/StoreAssetInCacheUC.js +34 -0
- package/dist/esm/Cache/UCs/StoreAssetInCacheUC.js.map +1 -0
- package/dist/esm/Cache/UCs/StoreScriptInCacheUC.js +43 -0
- package/dist/esm/Cache/UCs/StoreScriptInCacheUC.js.map +1 -0
- package/dist/esm/Cache/UCs/index.js +10 -0
- package/dist/esm/Cache/UCs/index.js.map +1 -0
- package/dist/esm/Cache/index.js +5 -0
- package/dist/esm/Cache/index.js.map +1 -0
- package/dist/esm/index.js +1 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/types/Assets/UCs/GetAssetBlobURLUC.d.ts.map +1 -1
- package/dist/types/Cache/Controllers/clearCache.d.ts +3 -0
- package/dist/types/Cache/Controllers/clearCache.d.ts.map +1 -0
- package/dist/types/Cache/Controllers/index.d.ts +2 -0
- package/dist/types/Cache/Controllers/index.d.ts.map +1 -0
- package/dist/types/Cache/Entities/AssetCacheEntity.d.ts +43 -0
- package/dist/types/Cache/Entities/AssetCacheEntity.d.ts.map +1 -0
- package/dist/types/Cache/Entities/CacheEntity.d.ts +57 -0
- package/dist/types/Cache/Entities/CacheEntity.d.ts.map +1 -0
- package/dist/types/Cache/Entities/ScriptCacheEntity.d.ts +64 -0
- package/dist/types/Cache/Entities/ScriptCacheEntity.d.ts.map +1 -0
- package/dist/types/Cache/Entities/index.d.ts +9 -0
- package/dist/types/Cache/Entities/index.d.ts.map +1 -0
- package/dist/types/Cache/Factories/index.d.ts +2 -0
- package/dist/types/Cache/Factories/index.d.ts.map +1 -0
- package/dist/types/Cache/Factories/setupCache.d.ts +6 -0
- package/dist/types/Cache/Factories/setupCache.d.ts.map +1 -0
- package/dist/types/Cache/Mocks/MockCacheEntity.d.ts +13 -0
- package/dist/types/Cache/Mocks/MockCacheEntity.d.ts.map +1 -0
- package/dist/types/Cache/Mocks/MockGetAssetFromCacheUC.d.ts +8 -0
- package/dist/types/Cache/Mocks/MockGetAssetFromCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/Mocks/MockGetScriptFromCacheUC.d.ts +9 -0
- package/dist/types/Cache/Mocks/MockGetScriptFromCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/Mocks/MockStoreAssetInCacheUC.d.ts +8 -0
- package/dist/types/Cache/Mocks/MockStoreAssetInCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/Mocks/MockStoreScriptInCacheUC.d.ts +9 -0
- package/dist/types/Cache/Mocks/MockStoreScriptInCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/Mocks/index.d.ts +6 -0
- package/dist/types/Cache/Mocks/index.d.ts.map +1 -0
- package/dist/types/Cache/UCs/GetAssetFromCacheUC.d.ts +8 -0
- package/dist/types/Cache/UCs/GetAssetFromCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/UCs/GetScriptFromCacheUC.d.ts +13 -0
- package/dist/types/Cache/UCs/GetScriptFromCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/UCs/StoreAssetInCacheUC.d.ts +8 -0
- package/dist/types/Cache/UCs/StoreAssetInCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/UCs/StoreScriptInCacheUC.d.ts +13 -0
- package/dist/types/Cache/UCs/StoreScriptInCacheUC.d.ts.map +1 -0
- package/dist/types/Cache/UCs/index.d.ts +10 -0
- package/dist/types/Cache/UCs/index.d.ts.map +1 -0
- package/dist/types/Cache/index.d.ts +5 -0
- package/dist/types/Cache/index.d.ts.map +1 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/index.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ exports.GetAssetBlobURLUC = void 0;
|
|
|
4
4
|
exports.makeGetAssetBlobURLUC = makeGetAssetBlobURLUC;
|
|
5
5
|
const core_1 = require("@vived/core");
|
|
6
6
|
const VivedAPI_1 = require("../../VivedAPI");
|
|
7
|
+
const Cache_1 = require("../../Cache");
|
|
7
8
|
const AssetRepo_1 = require("../Entities/AssetRepo");
|
|
8
9
|
const GetAssetUC_1 = require("./GetAssetUC");
|
|
9
10
|
class GetAssetBlobURLUC extends core_1.AppObjectUC {
|
|
@@ -17,60 +18,136 @@ function makeGetAssetBlobURLUC(appObject) {
|
|
|
17
18
|
return new GetAssetBlobURLUCImp(appObject);
|
|
18
19
|
}
|
|
19
20
|
class GetAssetBlobURLUCImp extends GetAssetBlobURLUC {
|
|
21
|
+
get assetRepo() {
|
|
22
|
+
return this.getCachedSingleton(AssetRepo_1.AssetRepo.type);
|
|
23
|
+
}
|
|
20
24
|
get fetchAssetFile() {
|
|
21
25
|
return this.getCachedSingleton(VivedAPI_1.FetchAssetFileFromAPIUC.type)?.doFetch;
|
|
22
26
|
}
|
|
23
27
|
get getAsset() {
|
|
24
28
|
return this.getCachedSingleton(GetAssetUC_1.GetAssetUC.type)?.getAsset;
|
|
25
29
|
}
|
|
30
|
+
get getAssetFromCache() {
|
|
31
|
+
return this.getCachedSingleton(Cache_1.GetAssetFromCacheUC.type)?.getAsset;
|
|
32
|
+
}
|
|
33
|
+
get storeAssetInCache() {
|
|
34
|
+
return this.getCachedSingleton(Cache_1.StoreAssetInCacheUC.type)?.storeAsset;
|
|
35
|
+
}
|
|
26
36
|
constructor(appObject) {
|
|
27
37
|
super(appObject, GetAssetBlobURLUC.type);
|
|
28
38
|
this.getAssetBlobURL = (assetID) => {
|
|
29
39
|
const assetRepo = this.assetRepo;
|
|
30
40
|
const getAsset = this.getAsset;
|
|
31
41
|
const fetchAssetFile = this.fetchAssetFile;
|
|
42
|
+
const getAssetFromCache = this.getAssetFromCache;
|
|
43
|
+
const storeAssetInCache = this.storeAssetInCache;
|
|
32
44
|
if (!assetRepo || !getAsset || !fetchAssetFile) {
|
|
33
45
|
return Promise.reject();
|
|
34
46
|
}
|
|
47
|
+
// Check if asset already exists in memory with a blob URL
|
|
35
48
|
const existing = assetRepo.get(assetID);
|
|
36
49
|
if (existing && existing.blobURL) {
|
|
37
50
|
return Promise.resolve(existing.blobURL);
|
|
38
51
|
}
|
|
39
52
|
return new Promise((resolve, reject) => {
|
|
40
53
|
let fetchedAsset;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
54
|
+
// First check if the asset exists in cache
|
|
55
|
+
if (getAssetFromCache) {
|
|
56
|
+
getAssetFromCache(assetID)
|
|
57
|
+
.then((cachedBlob) => {
|
|
58
|
+
if (cachedBlob) {
|
|
59
|
+
// Asset found in cache, get metadata
|
|
60
|
+
return getAsset(assetID).then((asset) => {
|
|
61
|
+
fetchedAsset = asset;
|
|
62
|
+
// Convert Blob to File
|
|
63
|
+
const filename = asset.filename || "cached-asset";
|
|
64
|
+
return new File([cachedBlob], filename, {
|
|
65
|
+
type: cachedBlob.type
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
else {
|
|
70
|
+
// Not in cache, get asset and fetch from API
|
|
71
|
+
return getAsset(assetID).then((asset) => {
|
|
72
|
+
asset.isFetchingFile = true;
|
|
73
|
+
asset.fetchError = undefined;
|
|
74
|
+
fetchedAsset = asset;
|
|
75
|
+
return fetchAssetFile(asset);
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
})
|
|
79
|
+
.then((file) => {
|
|
80
|
+
if (fetchedAsset) {
|
|
81
|
+
fetchedAsset.setFile(file);
|
|
82
|
+
fetchedAsset.isFetchingFile = false;
|
|
83
|
+
// Store the fetched file in cache if not from cache already
|
|
84
|
+
if (storeAssetInCache) {
|
|
85
|
+
storeAssetInCache(assetID, new Blob([file], { type: file.type }), file.type).catch((e) => {
|
|
86
|
+
this.warn(`Failed to cache asset: ${e.message}`);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
if (fetchedAsset.blobURL) {
|
|
90
|
+
resolve(fetchedAsset.blobURL);
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
55
93
|
}
|
|
94
|
+
reject(new Error("Blob URL is empty"));
|
|
95
|
+
})
|
|
96
|
+
.catch((e) => {
|
|
97
|
+
// Cache error or fetch error, try normal flow
|
|
98
|
+
this.warn(`Cache error or fetch error: ${e.message}`);
|
|
99
|
+
this.fetchAssetNormally(assetID, resolve, reject);
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// No cache available, use normal flow
|
|
104
|
+
this.fetchAssetNormally(assetID, resolve, reject);
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
};
|
|
108
|
+
// Helper method for the normal asset fetching flow without cache
|
|
109
|
+
this.fetchAssetNormally = (assetID, resolve, reject) => {
|
|
110
|
+
const getAsset = this.getAsset;
|
|
111
|
+
const fetchAssetFile = this.fetchAssetFile;
|
|
112
|
+
const storeAssetInCache = this.storeAssetInCache;
|
|
113
|
+
if (!getAsset || !fetchAssetFile) {
|
|
114
|
+
reject(new Error("Required dependencies not found"));
|
|
115
|
+
return;
|
|
116
|
+
}
|
|
117
|
+
let fetchedAsset;
|
|
118
|
+
getAsset(assetID)
|
|
119
|
+
.then((asset) => {
|
|
120
|
+
asset.isFetchingFile = true;
|
|
121
|
+
asset.fetchError = undefined;
|
|
122
|
+
fetchedAsset = asset;
|
|
123
|
+
return fetchAssetFile(asset);
|
|
124
|
+
})
|
|
125
|
+
.then((file) => {
|
|
126
|
+
if (fetchedAsset) {
|
|
127
|
+
fetchedAsset.setFile(file);
|
|
128
|
+
fetchedAsset.isFetchingFile = false;
|
|
129
|
+
// Store the fetched file in cache if caching is available
|
|
130
|
+
if (storeAssetInCache) {
|
|
131
|
+
storeAssetInCache(assetID, new Blob([file], { type: file.type }), file.type).catch((e) => {
|
|
132
|
+
this.warn(`Failed to cache asset: ${e.message}`);
|
|
133
|
+
});
|
|
56
134
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
if (fetchedAsset) {
|
|
61
|
-
fetchedAsset.fetchError = e;
|
|
62
|
-
fetchedAsset.isFetchingFile = false;
|
|
135
|
+
if (fetchedAsset.blobURL) {
|
|
136
|
+
resolve(fetchedAsset.blobURL);
|
|
137
|
+
return;
|
|
63
138
|
}
|
|
64
|
-
|
|
65
|
-
|
|
139
|
+
}
|
|
140
|
+
reject(new Error("Blob URL is empty"));
|
|
141
|
+
})
|
|
142
|
+
.catch((e) => {
|
|
143
|
+
if (fetchedAsset) {
|
|
144
|
+
fetchedAsset.fetchError = e;
|
|
145
|
+
fetchedAsset.isFetchingFile = false;
|
|
146
|
+
}
|
|
147
|
+
reject(e);
|
|
66
148
|
});
|
|
67
149
|
};
|
|
68
150
|
this.appObjects.registerSingleton(this);
|
|
69
|
-
this.assetRepo = appObject.getComponent(AssetRepo_1.AssetRepo.type);
|
|
70
|
-
if (!this.assetRepo) {
|
|
71
|
-
this.error("UC added to an App Object that does not have AssetRepo");
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
151
|
}
|
|
75
152
|
}
|
|
76
153
|
//# sourceMappingURL=GetAssetBlobURLUC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GetAssetBlobURLUC.js","sourceRoot":"","sources":["../../../../src/Assets/UCs/GetAssetBlobURLUC.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n getSingletonComponent,\r\n AppObject,\r\n AppObjectRepo,\r\n AppObjectUC\r\n} from \"@vived/core\";\r\nimport { FetchAssetFileFromAPIUC } from \"../../VivedAPI\";\r\nimport { AssetEntity } from \"../Entities/AssetEntity\";\r\nimport { AssetRepo } from \"../Entities/AssetRepo\";\r\nimport { GetAssetUC } from \"./GetAssetUC\";\r\n\r\nexport abstract class GetAssetBlobURLUC extends AppObjectUC {\r\n static type = \"GetAssetBlobURLUC\";\r\n\r\n abstract getAssetBlobURL(assetID: string): Promise<string>;\r\n\r\n static get(appObjects: AppObjectRepo): GetAssetBlobURLUC | undefined {\r\n return getSingletonComponent<GetAssetBlobURLUC>(\r\n GetAssetBlobURLUC.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\nexport function makeGetAssetBlobURLUC(appObject: AppObject): GetAssetBlobURLUC {\r\n return new GetAssetBlobURLUCImp(appObject);\r\n}\r\n\r\nclass GetAssetBlobURLUCImp extends GetAssetBlobURLUC {\r\n private assetRepo?: AssetRepo;\r\n\r\n private get fetchAssetFile() {\r\n return this.getCachedSingleton<FetchAssetFileFromAPIUC>(\r\n FetchAssetFileFromAPIUC.type\r\n )?.doFetch;\r\n }\r\n\r\n private get getAsset() {\r\n return this.getCachedSingleton<GetAssetUC>(GetAssetUC.type)?.getAsset;\r\n }\r\n\r\n getAssetBlobURL = (assetID: string): Promise<string> => {\r\n const assetRepo = this.assetRepo;\r\n const getAsset = this.getAsset;\r\n const fetchAssetFile = this.fetchAssetFile;\r\n\r\n if (!assetRepo || !getAsset || !fetchAssetFile) {\r\n return Promise.reject();\r\n }\r\n\r\n const existing = assetRepo.get(assetID);\r\n if (existing && existing.blobURL) {\r\n return Promise.resolve(existing.blobURL);\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n let fetchedAsset: AssetEntity | undefined;\r\n\r\n getAsset(assetID)\r\n .then((asset) => {\r\n asset.isFetchingFile = true;\r\n asset.fetchError = undefined;\r\n fetchedAsset = asset;\r\n return fetchAssetFile(asset);\r\n })\r\n .then((file) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.setFile(file);\r\n fetchedAsset.isFetchingFile = false;\r\n\r\n if (fetchedAsset.blobURL) {\r\n resolve(fetchedAsset.blobURL);\r\n return;\r\n }\r\n }\r\n reject(new Error(\"Blob URL is empty\"));\r\n })\r\n .catch((e: Error) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.fetchError = e;\r\n fetchedAsset.isFetchingFile = false;\r\n }\r\n reject(e);\r\n });\r\n });\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, GetAssetBlobURLUC.type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n\r\n this.assetRepo = appObject.getComponent<AssetRepo>(AssetRepo.type);\r\n if (!this.assetRepo) {\r\n this.error(\"UC added to an App Object that does not have AssetRepo\");\r\n return;\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"GetAssetBlobURLUC.js","sourceRoot":"","sources":["../../../../src/Assets/UCs/GetAssetBlobURLUC.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n getSingletonComponent,\r\n AppObject,\r\n AppObjectRepo,\r\n AppObjectUC\r\n} from \"@vived/core\";\r\nimport { FetchAssetFileFromAPIUC } from \"../../VivedAPI\";\r\nimport { GetAssetFromCacheUC, StoreAssetInCacheUC } from \"../../Cache\";\r\nimport { AssetEntity } from \"../Entities/AssetEntity\";\r\nimport { AssetRepo } from \"../Entities/AssetRepo\";\r\nimport { GetAssetUC } from \"./GetAssetUC\";\r\n\r\nexport abstract class GetAssetBlobURLUC extends AppObjectUC {\r\n static type = \"GetAssetBlobURLUC\";\r\n\r\n abstract getAssetBlobURL(assetID: string): Promise<string>;\r\n\r\n static get(appObjects: AppObjectRepo): GetAssetBlobURLUC | undefined {\r\n return getSingletonComponent<GetAssetBlobURLUC>(\r\n GetAssetBlobURLUC.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\nexport function makeGetAssetBlobURLUC(appObject: AppObject): GetAssetBlobURLUC {\r\n return new GetAssetBlobURLUCImp(appObject);\r\n}\r\n\r\nclass GetAssetBlobURLUCImp extends GetAssetBlobURLUC {\r\n private get assetRepo() {\r\n return this.getCachedSingleton<AssetRepo>(AssetRepo.type);\r\n }\r\n\r\n private get fetchAssetFile() {\r\n return this.getCachedSingleton<FetchAssetFileFromAPIUC>(\r\n FetchAssetFileFromAPIUC.type\r\n )?.doFetch;\r\n }\r\n\r\n private get getAsset() {\r\n return this.getCachedSingleton<GetAssetUC>(GetAssetUC.type)?.getAsset;\r\n }\r\n\r\n private get getAssetFromCache() {\r\n return this.getCachedSingleton<GetAssetFromCacheUC>(\r\n GetAssetFromCacheUC.type\r\n )?.getAsset;\r\n }\r\n\r\n private get storeAssetInCache() {\r\n return this.getCachedSingleton<StoreAssetInCacheUC>(\r\n StoreAssetInCacheUC.type\r\n )?.storeAsset;\r\n }\r\n\r\n getAssetBlobURL = (assetID: string): Promise<string> => {\r\n const assetRepo = this.assetRepo;\r\n const getAsset = this.getAsset;\r\n const fetchAssetFile = this.fetchAssetFile;\r\n const getAssetFromCache = this.getAssetFromCache;\r\n const storeAssetInCache = this.storeAssetInCache;\r\n\r\n if (!assetRepo || !getAsset || !fetchAssetFile) {\r\n return Promise.reject();\r\n }\r\n\r\n // Check if asset already exists in memory with a blob URL\r\n const existing = assetRepo.get(assetID);\r\n if (existing && existing.blobURL) {\r\n return Promise.resolve(existing.blobURL);\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n let fetchedAsset: AssetEntity | undefined;\r\n\r\n // First check if the asset exists in cache\r\n if (getAssetFromCache) {\r\n getAssetFromCache(assetID)\r\n .then((cachedBlob) => {\r\n if (cachedBlob) {\r\n // Asset found in cache, get metadata\r\n return getAsset(assetID).then((asset) => {\r\n fetchedAsset = asset;\r\n // Convert Blob to File\r\n const filename = asset.filename || \"cached-asset\";\r\n return new File([cachedBlob], filename, {\r\n type: cachedBlob.type\r\n });\r\n });\r\n } else {\r\n // Not in cache, get asset and fetch from API\r\n return getAsset(assetID).then((asset) => {\r\n asset.isFetchingFile = true;\r\n asset.fetchError = undefined;\r\n fetchedAsset = asset;\r\n return fetchAssetFile(asset);\r\n });\r\n }\r\n })\r\n .then((file) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.setFile(file);\r\n fetchedAsset.isFetchingFile = false;\r\n\r\n // Store the fetched file in cache if not from cache already\r\n if (storeAssetInCache) {\r\n storeAssetInCache(\r\n assetID,\r\n new Blob([file], { type: file.type }),\r\n file.type\r\n ).catch((e) => {\r\n this.warn(`Failed to cache asset: ${e.message}`);\r\n });\r\n }\r\n\r\n if (fetchedAsset.blobURL) {\r\n resolve(fetchedAsset.blobURL);\r\n return;\r\n }\r\n }\r\n reject(new Error(\"Blob URL is empty\"));\r\n })\r\n .catch((e: Error) => {\r\n // Cache error or fetch error, try normal flow\r\n this.warn(`Cache error or fetch error: ${e.message}`);\r\n this.fetchAssetNormally(assetID, resolve, reject);\r\n });\r\n } else {\r\n // No cache available, use normal flow\r\n this.fetchAssetNormally(assetID, resolve, reject);\r\n }\r\n });\r\n };\r\n\r\n // Helper method for the normal asset fetching flow without cache\r\n private fetchAssetNormally = (\r\n assetID: string,\r\n resolve: (blobURL: string) => void,\r\n reject: (error: Error) => void\r\n ): void => {\r\n const getAsset = this.getAsset;\r\n const fetchAssetFile = this.fetchAssetFile;\r\n const storeAssetInCache = this.storeAssetInCache;\r\n\r\n if (!getAsset || !fetchAssetFile) {\r\n reject(new Error(\"Required dependencies not found\"));\r\n return;\r\n }\r\n\r\n let fetchedAsset: AssetEntity | undefined;\r\n\r\n getAsset(assetID)\r\n .then((asset) => {\r\n asset.isFetchingFile = true;\r\n asset.fetchError = undefined;\r\n fetchedAsset = asset;\r\n return fetchAssetFile(asset);\r\n })\r\n .then((file) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.setFile(file);\r\n fetchedAsset.isFetchingFile = false;\r\n\r\n // Store the fetched file in cache if caching is available\r\n if (storeAssetInCache) {\r\n storeAssetInCache(\r\n assetID,\r\n new Blob([file], { type: file.type }),\r\n file.type\r\n ).catch((e) => {\r\n this.warn(`Failed to cache asset: ${e.message}`);\r\n });\r\n }\r\n\r\n if (fetchedAsset.blobURL) {\r\n resolve(fetchedAsset.blobURL);\r\n return;\r\n }\r\n }\r\n reject(new Error(\"Blob URL is empty\"));\r\n })\r\n .catch((e: Error) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.fetchError = e;\r\n fetchedAsset.isFetchingFile = false;\r\n }\r\n reject(e);\r\n });\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, GetAssetBlobURLUC.type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n }\r\n}\r\n"]}
|
|
@@ -4,6 +4,7 @@ exports.GetAssetFileUC = void 0;
|
|
|
4
4
|
exports.makeGetAssetFileUC = makeGetAssetFileUC;
|
|
5
5
|
const core_1 = require("@vived/core");
|
|
6
6
|
const VivedAPI_1 = require("../../VivedAPI");
|
|
7
|
+
const Cache_1 = require("../../Cache");
|
|
7
8
|
const AssetRepo_1 = require("../Entities/AssetRepo");
|
|
8
9
|
const GetAssetUC_1 = require("./GetAssetUC");
|
|
9
10
|
class GetAssetFileUC extends core_1.AppObjectUC {
|
|
@@ -17,56 +18,132 @@ function makeGetAssetFileUC(appObject) {
|
|
|
17
18
|
return new GetAssetFileUCImp(appObject);
|
|
18
19
|
}
|
|
19
20
|
class GetAssetFileUCImp extends GetAssetFileUC {
|
|
21
|
+
get assetRepo() {
|
|
22
|
+
return this.getCachedSingleton(AssetRepo_1.AssetRepo.type);
|
|
23
|
+
}
|
|
20
24
|
get fetchAssetFile() {
|
|
21
25
|
return this.getCachedSingleton(VivedAPI_1.FetchAssetFileFromAPIUC.type)?.doFetch;
|
|
22
26
|
}
|
|
23
27
|
get getAsset() {
|
|
24
28
|
return this.getCachedSingleton(GetAssetUC_1.GetAssetUC.type)?.getAsset;
|
|
25
29
|
}
|
|
30
|
+
get getAssetFromCache() {
|
|
31
|
+
return this.getCachedSingleton(Cache_1.GetAssetFromCacheUC.type)?.getAsset;
|
|
32
|
+
}
|
|
33
|
+
get storeAssetInCache() {
|
|
34
|
+
return this.getCachedSingleton(Cache_1.StoreAssetInCacheUC.type)?.storeAsset;
|
|
35
|
+
}
|
|
36
|
+
async tryGetFromCacheOrFetch(assetID) {
|
|
37
|
+
const getAssetFromCache = this.getAssetFromCache;
|
|
38
|
+
// If no cache is available, go straight to normal fetching
|
|
39
|
+
if (!getAssetFromCache) {
|
|
40
|
+
return this.fetchAssetDirectly(assetID);
|
|
41
|
+
}
|
|
42
|
+
// Try to get the asset from cache
|
|
43
|
+
const cachedBlob = await getAssetFromCache(assetID);
|
|
44
|
+
if (cachedBlob) {
|
|
45
|
+
// Asset found in cache, get metadata and create file
|
|
46
|
+
return this.createFileFromCachedBlob(assetID, cachedBlob);
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
// Not in cache, fetch directly
|
|
50
|
+
return this.fetchAssetDirectly(assetID);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async createFileFromCachedBlob(assetID, cachedBlob) {
|
|
54
|
+
const getAsset = this.getAsset;
|
|
55
|
+
if (!getAsset) {
|
|
56
|
+
throw new Error("Required dependencies not found");
|
|
57
|
+
}
|
|
58
|
+
// Get asset metadata
|
|
59
|
+
const asset = await getAsset(assetID);
|
|
60
|
+
// Convert blob to file
|
|
61
|
+
const filename = asset.filename || "cached-asset";
|
|
62
|
+
const file = new File([cachedBlob], filename, {
|
|
63
|
+
type: cachedBlob.type
|
|
64
|
+
});
|
|
65
|
+
// Update asset state
|
|
66
|
+
asset.setFile(file);
|
|
67
|
+
asset.isFetchingFile = false;
|
|
68
|
+
return file;
|
|
69
|
+
}
|
|
70
|
+
async fetchAssetDirectly(assetID) {
|
|
71
|
+
const getAsset = this.getAsset;
|
|
72
|
+
const fetchAssetFile = this.fetchAssetFile;
|
|
73
|
+
if (!getAsset || !fetchAssetFile) {
|
|
74
|
+
throw new Error("Required dependencies not found");
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
// Get asset and prepare for fetching
|
|
78
|
+
const asset = await getAsset(assetID);
|
|
79
|
+
asset.isFetchingFile = true;
|
|
80
|
+
asset.fetchError = undefined;
|
|
81
|
+
// Fetch the file
|
|
82
|
+
const file = await fetchAssetFile(asset);
|
|
83
|
+
// Update asset state
|
|
84
|
+
asset.setFile(file);
|
|
85
|
+
asset.isFetchingFile = false;
|
|
86
|
+
// Try to store in cache
|
|
87
|
+
await this.tryCacheAssetFile(assetID, file);
|
|
88
|
+
return file;
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
await this.handleFetchError(assetID, error);
|
|
92
|
+
throw error;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
async handleFetchError(assetID, error) {
|
|
96
|
+
const getAsset = this.getAsset;
|
|
97
|
+
if (!getAsset) {
|
|
98
|
+
return;
|
|
99
|
+
}
|
|
100
|
+
try {
|
|
101
|
+
const asset = await getAsset(assetID);
|
|
102
|
+
asset.fetchError = error;
|
|
103
|
+
asset.isFetchingFile = false;
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
// If we can't get the asset, we can't update its error state
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async tryCacheAssetFile(assetID, file) {
|
|
110
|
+
const storeAssetInCache = this.storeAssetInCache;
|
|
111
|
+
if (!storeAssetInCache) {
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
try {
|
|
115
|
+
await storeAssetInCache(assetID, new Blob([file], { type: file.type }), file.type);
|
|
116
|
+
}
|
|
117
|
+
catch (e) {
|
|
118
|
+
this.warn(`Failed to cache asset: ${e.message}`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
26
121
|
constructor(appObject) {
|
|
27
122
|
super(appObject, GetAssetFileUC.type);
|
|
28
|
-
this.getAssetFile = (assetID) => {
|
|
123
|
+
this.getAssetFile = async (assetID) => {
|
|
29
124
|
const assetRepo = this.assetRepo;
|
|
30
125
|
const getAsset = this.getAsset;
|
|
31
126
|
const fetchAssetFile = this.fetchAssetFile;
|
|
127
|
+
// Check for required dependencies
|
|
32
128
|
if (!assetRepo || !getAsset || !fetchAssetFile) {
|
|
33
|
-
return Promise.reject();
|
|
129
|
+
return Promise.reject(new Error("Missing required dependencies"));
|
|
130
|
+
}
|
|
131
|
+
// Check if asset already exists in memory with a file
|
|
132
|
+
const existingAsset = assetRepo.get(assetID);
|
|
133
|
+
if (existingAsset?.file) {
|
|
134
|
+
return existingAsset.file;
|
|
34
135
|
}
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
return
|
|
136
|
+
// Try to get from cache first, then fall back to normal fetching if needed
|
|
137
|
+
try {
|
|
138
|
+
return await this.tryGetFromCacheOrFetch(assetID);
|
|
139
|
+
}
|
|
140
|
+
catch (error) {
|
|
141
|
+
// If cache access failed, try the normal flow
|
|
142
|
+
this.warn(`Cache error: ${error.message}`);
|
|
143
|
+
return this.fetchAssetDirectly(assetID);
|
|
38
144
|
}
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
let fetchedAsset;
|
|
41
|
-
getAsset(assetID)
|
|
42
|
-
.then((asset) => {
|
|
43
|
-
asset.isFetchingFile = true;
|
|
44
|
-
asset.fetchError = undefined;
|
|
45
|
-
fetchedAsset = asset;
|
|
46
|
-
return fetchAssetFile(asset);
|
|
47
|
-
})
|
|
48
|
-
.then((file) => {
|
|
49
|
-
if (fetchedAsset) {
|
|
50
|
-
fetchedAsset.setFile(file);
|
|
51
|
-
fetchedAsset.isFetchingFile = false;
|
|
52
|
-
}
|
|
53
|
-
resolve(file);
|
|
54
|
-
})
|
|
55
|
-
.catch((e) => {
|
|
56
|
-
if (fetchedAsset) {
|
|
57
|
-
fetchedAsset.fetchError = e;
|
|
58
|
-
fetchedAsset.isFetchingFile = false;
|
|
59
|
-
}
|
|
60
|
-
reject(e);
|
|
61
|
-
});
|
|
62
|
-
});
|
|
63
145
|
};
|
|
64
146
|
this.appObjects.registerSingleton(this);
|
|
65
|
-
this.assetRepo = appObject.getComponent(AssetRepo_1.AssetRepo.type);
|
|
66
|
-
if (!this.assetRepo) {
|
|
67
|
-
this.error("UC added to an App Object that does not have AssetRepo");
|
|
68
|
-
return;
|
|
69
|
-
}
|
|
70
147
|
}
|
|
71
148
|
}
|
|
72
149
|
//# sourceMappingURL=GetAssetFileUC.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GetAssetFileUC.js","sourceRoot":"","sources":["../../../../src/Assets/UCs/GetAssetFileUC.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n getSingletonComponent,\r\n AppObject,\r\n AppObjectRepo,\r\n AppObjectUC\r\n} from \"@vived/core\";\r\nimport { FetchAssetFileFromAPIUC } from \"../../VivedAPI\";\r\nimport { AssetEntity } from \"../Entities/AssetEntity\";\r\nimport { AssetRepo } from \"../Entities/AssetRepo\";\r\nimport { GetAssetUC } from \"./GetAssetUC\";\r\n\r\nexport abstract class GetAssetFileUC extends AppObjectUC {\r\n static type = \"GetAssetFileUC\";\r\n\r\n abstract getAssetFile(assetID: string): Promise<File>;\r\n\r\n static get(appObjects: AppObjectRepo): GetAssetFileUC | undefined {\r\n return getSingletonComponent<GetAssetFileUC>(\r\n GetAssetFileUC.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\nexport function makeGetAssetFileUC(appObject: AppObject): GetAssetFileUC {\r\n return new GetAssetFileUCImp(appObject);\r\n}\r\n\r\nclass GetAssetFileUCImp extends GetAssetFileUC {\r\n private assetRepo?: AssetRepo;\r\n\r\n private get fetchAssetFile() {\r\n return this.getCachedSingleton<FetchAssetFileFromAPIUC>(\r\n FetchAssetFileFromAPIUC.type\r\n )?.doFetch;\r\n }\r\n\r\n private get getAsset() {\r\n return this.getCachedSingleton<GetAssetUC>(GetAssetUC.type)?.getAsset;\r\n }\r\n\r\n getAssetFile = (assetID: string): Promise<File> => {\r\n const assetRepo = this.assetRepo;\r\n const getAsset = this.getAsset;\r\n const fetchAssetFile = this.fetchAssetFile;\r\n\r\n if (!assetRepo || !getAsset || !fetchAssetFile) {\r\n return Promise.reject();\r\n }\r\n\r\n const existing = assetRepo.get(assetID);\r\n if (existing && existing.file) {\r\n return Promise.resolve(existing.file);\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n let fetchedAsset: AssetEntity | undefined;\r\n\r\n getAsset(assetID)\r\n .then((asset) => {\r\n asset.isFetchingFile = true;\r\n asset.fetchError = undefined;\r\n fetchedAsset = asset;\r\n return fetchAssetFile(asset);\r\n })\r\n .then((file) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.setFile(file);\r\n fetchedAsset.isFetchingFile = false;\r\n }\r\n resolve(file);\r\n })\r\n .catch((e: Error) => {\r\n if (fetchedAsset) {\r\n fetchedAsset.fetchError = e;\r\n fetchedAsset.isFetchingFile = false;\r\n }\r\n reject(e);\r\n });\r\n });\r\n };\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, GetAssetFileUC.type);\r\n\r\n this.appObjects.registerSingleton(this);\r\n\r\n this.assetRepo = appObject.getComponent<AssetRepo>(AssetRepo.type);\r\n if (!this.assetRepo) {\r\n this.error(\"UC added to an App Object that does not have AssetRepo\");\r\n return;\r\n }\r\n }\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"GetAssetFileUC.js","sourceRoot":"","sources":["../../../../src/Assets/UCs/GetAssetFileUC.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n getSingletonComponent,\r\n AppObject,\r\n AppObjectRepo,\r\n AppObjectUC\r\n} from \"@vived/core\";\r\nimport { FetchAssetFileFromAPIUC } from \"../../VivedAPI\";\r\nimport { GetAssetFromCacheUC, StoreAssetInCacheUC } from \"../../Cache\";\r\nimport { AssetRepo } from \"../Entities/AssetRepo\";\r\nimport { GetAssetUC } from \"./GetAssetUC\";\r\n\r\nexport abstract class GetAssetFileUC extends AppObjectUC {\r\n static type = \"GetAssetFileUC\";\r\n\r\n abstract getAssetFile(assetID: string): Promise<File>;\r\n\r\n static get(appObjects: AppObjectRepo): GetAssetFileUC | undefined {\r\n return getSingletonComponent<GetAssetFileUC>(\r\n GetAssetFileUC.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\nexport function makeGetAssetFileUC(appObject: AppObject): GetAssetFileUC {\r\n return new GetAssetFileUCImp(appObject);\r\n}\r\n\r\nclass GetAssetFileUCImp extends GetAssetFileUC {\r\n private get assetRepo() {\r\n return this.getCachedSingleton<AssetRepo>(AssetRepo.type);\r\n }\r\n\r\n private get fetchAssetFile() {\r\n return this.getCachedSingleton<FetchAssetFileFromAPIUC>(\r\n FetchAssetFileFromAPIUC.type\r\n )?.doFetch;\r\n }\r\n\r\n private get getAsset() {\r\n return this.getCachedSingleton<GetAssetUC>(GetAssetUC.type)?.getAsset;\r\n }\r\n\r\n private get getAssetFromCache() {\r\n return this.getCachedSingleton<GetAssetFromCacheUC>(\r\n GetAssetFromCacheUC.type\r\n )?.getAsset;\r\n }\r\n\r\n private get storeAssetInCache() {\r\n return this.getCachedSingleton<StoreAssetInCacheUC>(\r\n StoreAssetInCacheUC.type\r\n )?.storeAsset;\r\n }\r\n\r\n getAssetFile = async (assetID: string): Promise<File> => {\r\n const assetRepo = this.assetRepo;\r\n const getAsset = this.getAsset;\r\n const fetchAssetFile = this.fetchAssetFile;\r\n\r\n // Check for required dependencies\r\n if (!assetRepo || !getAsset || !fetchAssetFile) {\r\n return Promise.reject(new Error(\"Missing required dependencies\"));\r\n }\r\n\r\n // Check if asset already exists in memory with a file\r\n const existingAsset = assetRepo.get(assetID);\r\n if (existingAsset?.file) {\r\n return existingAsset.file;\r\n }\r\n\r\n // Try to get from cache first, then fall back to normal fetching if needed\r\n try {\r\n return await this.tryGetFromCacheOrFetch(assetID);\r\n } catch (error) {\r\n // If cache access failed, try the normal flow\r\n this.warn(`Cache error: ${(error as Error).message}`);\r\n return this.fetchAssetDirectly(assetID);\r\n }\r\n };\r\n\r\n private async tryGetFromCacheOrFetch(assetID: string): Promise<File> {\r\n const getAssetFromCache = this.getAssetFromCache;\r\n\r\n // If no cache is available, go straight to normal fetching\r\n if (!getAssetFromCache) {\r\n return this.fetchAssetDirectly(assetID);\r\n }\r\n\r\n // Try to get the asset from cache\r\n const cachedBlob = await getAssetFromCache(assetID);\r\n\r\n if (cachedBlob) {\r\n // Asset found in cache, get metadata and create file\r\n return this.createFileFromCachedBlob(assetID, cachedBlob);\r\n } else {\r\n // Not in cache, fetch directly\r\n return this.fetchAssetDirectly(assetID);\r\n }\r\n }\r\n\r\n private async createFileFromCachedBlob(\r\n assetID: string,\r\n cachedBlob: Blob\r\n ): Promise<File> {\r\n const getAsset = this.getAsset;\r\n\r\n if (!getAsset) {\r\n throw new Error(\"Required dependencies not found\");\r\n }\r\n\r\n // Get asset metadata\r\n const asset = await getAsset(assetID);\r\n\r\n // Convert blob to file\r\n const filename = asset.filename || \"cached-asset\";\r\n const file = new File([cachedBlob], filename, {\r\n type: cachedBlob.type\r\n });\r\n\r\n // Update asset state\r\n asset.setFile(file);\r\n asset.isFetchingFile = false;\r\n\r\n return file;\r\n }\r\n\r\n private async fetchAssetDirectly(assetID: string): Promise<File> {\r\n const getAsset = this.getAsset;\r\n const fetchAssetFile = this.fetchAssetFile;\r\n\r\n if (!getAsset || !fetchAssetFile) {\r\n throw new Error(\"Required dependencies not found\");\r\n }\r\n\r\n try {\r\n // Get asset and prepare for fetching\r\n const asset = await getAsset(assetID);\r\n asset.isFetchingFile = true;\r\n asset.fetchError = undefined;\r\n\r\n // Fetch the file\r\n const file = await fetchAssetFile(asset);\r\n\r\n // Update asset state\r\n asset.setFile(file);\r\n asset.isFetchingFile = false;\r\n\r\n // Try to store in cache\r\n await this.tryCacheAssetFile(assetID, file);\r\n\r\n return file;\r\n } catch (error) {\r\n await this.handleFetchError(assetID, error as Error);\r\n throw error;\r\n }\r\n }\r\n\r\n private async handleFetchError(assetID: string, error: Error): Promise<void> {\r\n const getAsset = this.getAsset;\r\n\r\n if (!getAsset) {\r\n return;\r\n }\r\n\r\n try {\r\n const asset = await getAsset(assetID);\r\n asset.fetchError = error;\r\n asset.isFetchingFile = false;\r\n } catch {\r\n // If we can't get the asset, we can't update its error state\r\n }\r\n }\r\n\r\n private async tryCacheAssetFile(assetID: string, file: File): Promise<void> {\r\n const storeAssetInCache = this.storeAssetInCache;\r\n\r\n if (!storeAssetInCache) {\r\n return;\r\n }\r\n\r\n try {\r\n await storeAssetInCache(\r\n assetID,\r\n new Blob([file], { type: file.type }),\r\n file.type\r\n );\r\n } catch (e) {\r\n this.warn(`Failed to cache asset: ${(e as Error).message}`);\r\n }\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, GetAssetFileUC.type);\r\n this.appObjects.registerSingleton(this);\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.clearCache = clearCache;
|
|
4
|
+
const CacheEntity_1 = require("../Entities/CacheEntity");
|
|
5
|
+
function clearCache(appObjects) {
|
|
6
|
+
const cacheEntity = CacheEntity_1.CacheEntity.get(appObjects);
|
|
7
|
+
if (!cacheEntity) {
|
|
8
|
+
appObjects.submitWarning("clearCache", "Unable to find CacheEntity");
|
|
9
|
+
return Promise.reject();
|
|
10
|
+
}
|
|
11
|
+
return cacheEntity.clear();
|
|
12
|
+
}
|
|
13
|
+
//# sourceMappingURL=clearCache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"clearCache.js","sourceRoot":"","sources":["../../../../src/Cache/Controllers/clearCache.ts"],"names":[],"mappings":";;AAGA,gCAQC;AAVD,yDAAsD;AAEtD,SAAgB,UAAU,CAAC,UAAyB;IAClD,MAAM,WAAW,GAAG,yBAAW,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;IAChD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,UAAU,CAAC,aAAa,CAAC,YAAY,EAAE,4BAA4B,CAAC,CAAC;QACrE,OAAO,OAAO,CAAC,MAAM,EAAE,CAAC;IAC1B,CAAC;IAED,OAAO,WAAW,CAAC,KAAK,EAAE,CAAC;AAC7B,CAAC","sourcesContent":["import { AppObjectRepo } from \"@vived/core\";\r\nimport { CacheEntity } from \"../Entities/CacheEntity\";\r\n\r\nexport function clearCache(appObjects: AppObjectRepo): Promise<void> {\r\n const cacheEntity = CacheEntity.get(appObjects);\r\n if (!cacheEntity) {\r\n appObjects.submitWarning(\"clearCache\", \"Unable to find CacheEntity\");\r\n return Promise.reject();\r\n }\r\n\r\n return cacheEntity.clear();\r\n}\r\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./clearCache"), exports);
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/Cache/Controllers/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;AAAA,+CAA6B","sourcesContent":["export * from \"./clearCache\";\r\n"]}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.AssetCacheEntity = void 0;
|
|
4
|
+
exports.makeAssetCacheEntity = makeAssetCacheEntity;
|
|
5
|
+
const core_1 = require("@vived/core");
|
|
6
|
+
const CacheEntity_1 = require("./CacheEntity");
|
|
7
|
+
/**
|
|
8
|
+
* AssetCacheEntity provides functionality for caching binary assets in the application.
|
|
9
|
+
* It serves as a specialized cache storage for assets such as images, videos, or other binary content.
|
|
10
|
+
* This entity is implemented as a singleton component and requires a CacheEntity instance to function.
|
|
11
|
+
*/
|
|
12
|
+
class AssetCacheEntity extends core_1.AppObjectEntity {
|
|
13
|
+
/**
|
|
14
|
+
* Gets the singleton instance of AssetCacheEntity from the app objects repository.
|
|
15
|
+
* @param appObjects - The app objects repository
|
|
16
|
+
* @returns The AssetCacheEntity instance if found, otherwise undefined
|
|
17
|
+
*/
|
|
18
|
+
static get(appObjects) {
|
|
19
|
+
return (0, core_1.getSingletonComponent)(AssetCacheEntity.type, appObjects);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
exports.AssetCacheEntity = AssetCacheEntity;
|
|
23
|
+
AssetCacheEntity.type = "AssetCacheEntity";
|
|
24
|
+
function makeAssetCacheEntity(appObject) {
|
|
25
|
+
return new AssetCacheEntityImp(appObject);
|
|
26
|
+
}
|
|
27
|
+
class AssetCacheEntityImp extends AssetCacheEntity {
|
|
28
|
+
get cacheEntity() {
|
|
29
|
+
return this.getCachedSingleton(CacheEntity_1.CacheEntity.type);
|
|
30
|
+
}
|
|
31
|
+
constructor(appObject) {
|
|
32
|
+
super(appObject, AssetCacheEntity.type);
|
|
33
|
+
this.appObjects.registerSingleton(this);
|
|
34
|
+
}
|
|
35
|
+
async getAsset(assetId) {
|
|
36
|
+
const cacheKey = this.generateCacheKey(assetId);
|
|
37
|
+
const cacheEntity = this.cacheEntity;
|
|
38
|
+
if (!cacheEntity) {
|
|
39
|
+
this.warn("CacheEntity not found");
|
|
40
|
+
return undefined;
|
|
41
|
+
}
|
|
42
|
+
try {
|
|
43
|
+
const { value, metadata } = await cacheEntity.get(cacheKey);
|
|
44
|
+
if (value instanceof Blob) {
|
|
45
|
+
return value;
|
|
46
|
+
}
|
|
47
|
+
// Handle case where the value is stored as an ArrayBuffer
|
|
48
|
+
if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {
|
|
49
|
+
const contentType = metadata?.contentType || "application/octet-stream";
|
|
50
|
+
return new Blob([value], { type: contentType });
|
|
51
|
+
}
|
|
52
|
+
this.warn("Cached asset is not a Blob or ArrayBuffer");
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
catch (e) {
|
|
56
|
+
return undefined;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
async storeAsset(assetId, content, contentType) {
|
|
60
|
+
const cacheKey = this.generateCacheKey(assetId);
|
|
61
|
+
const cacheEntity = this.cacheEntity;
|
|
62
|
+
if (!cacheEntity) {
|
|
63
|
+
this.warn("CacheEntity not found");
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const metadata = {
|
|
67
|
+
assetId,
|
|
68
|
+
timestamp: Date.now(),
|
|
69
|
+
contentType: contentType || content.type
|
|
70
|
+
};
|
|
71
|
+
await cacheEntity.store(cacheKey, content, metadata);
|
|
72
|
+
}
|
|
73
|
+
async hasAsset(assetId) {
|
|
74
|
+
const cacheKey = this.generateCacheKey(assetId);
|
|
75
|
+
const cacheEntity = this.cacheEntity;
|
|
76
|
+
if (!cacheEntity) {
|
|
77
|
+
this.warn("CacheEntity not found");
|
|
78
|
+
return false;
|
|
79
|
+
}
|
|
80
|
+
return await cacheEntity.has(cacheKey);
|
|
81
|
+
}
|
|
82
|
+
async invalidateAsset(assetId) {
|
|
83
|
+
const cacheEntity = this.cacheEntity;
|
|
84
|
+
if (!cacheEntity) {
|
|
85
|
+
this.warn("CacheEntity not found");
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
const cacheKey = this.generateCacheKey(assetId);
|
|
89
|
+
await cacheEntity.invalidate(cacheKey);
|
|
90
|
+
}
|
|
91
|
+
generateCacheKey(assetId) {
|
|
92
|
+
return `asset:${assetId}`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=AssetCacheEntity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AssetCacheEntity.js","sourceRoot":"","sources":["../../../../src/Cache/Entities/AssetCacheEntity.ts"],"names":[],"mappings":"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","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo,\r\n getSingletonComponent\r\n} from \"@vived/core\";\r\nimport { CacheEntity } from \"./CacheEntity\";\r\n\r\n/**\r\n * AssetCacheEntity provides functionality for caching binary assets in the application.\r\n * It serves as a specialized cache storage for assets such as images, videos, or other binary content.\r\n * This entity is implemented as a singleton component and requires a CacheEntity instance to function.\r\n */\r\nexport abstract class AssetCacheEntity extends AppObjectEntity {\r\n static readonly type = \"AssetCacheEntity\";\r\n\r\n /**\r\n * Retrieves an asset from the cache by its unique identifier.\r\n * @param assetId - The unique identifier of the asset to retrieve\r\n * @returns A Promise that resolves to the cached Blob if found, otherwise undefined\r\n */\r\n abstract getAsset(assetId: string): Promise<Blob | undefined>;\r\n\r\n /**\r\n * Stores an asset in the cache with the specified identifier.\r\n * @param assetId - The unique identifier to associate with the asset\r\n * @param content - The binary content to cache as a Blob\r\n * @param contentType - Optional MIME type of the content\r\n * @returns A Promise that resolves when the asset has been stored\r\n */\r\n abstract storeAsset(\r\n assetId: string,\r\n content: Blob,\r\n contentType?: string\r\n ): Promise<void>;\r\n\r\n /**\r\n * Checks if an asset exists in the cache.\r\n * @param assetId - The unique identifier of the asset to check\r\n * @returns A Promise that resolves to true if the asset exists, otherwise false\r\n */\r\n abstract hasAsset(assetId: string): Promise<boolean>;\r\n\r\n /**\r\n * Removes an asset from the cache.\r\n * @param assetId - The unique identifier of the asset to invalidate\r\n * @returns A Promise that resolves when the asset has been invalidated\r\n */\r\n abstract invalidateAsset(assetId: string): Promise<void>;\r\n\r\n /**\r\n * Gets the singleton instance of AssetCacheEntity from the app objects repository.\r\n * @param appObjects - The app objects repository\r\n * @returns The AssetCacheEntity instance if found, otherwise undefined\r\n */\r\n static get(appObjects: AppObjectRepo): AssetCacheEntity | undefined {\r\n return getSingletonComponent<AssetCacheEntity>(\r\n AssetCacheEntity.type,\r\n appObjects\r\n );\r\n }\r\n}\r\n\r\nexport function makeAssetCacheEntity(appObject: AppObject): AssetCacheEntity {\r\n return new AssetCacheEntityImp(appObject);\r\n}\r\n\r\ntype AssetCacheMetadata = {\r\n assetId: string;\r\n timestamp: number;\r\n contentType?: string;\r\n};\r\n\r\nclass AssetCacheEntityImp extends AssetCacheEntity {\r\n private get cacheEntity(): CacheEntity | undefined {\r\n return this.getCachedSingleton<CacheEntity>(CacheEntity.type);\r\n }\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, AssetCacheEntity.type);\r\n this.appObjects.registerSingleton(this);\r\n }\r\n\r\n async getAsset(assetId: string): Promise<Blob | undefined> {\r\n const cacheKey = this.generateCacheKey(assetId);\r\n\r\n const cacheEntity = this.cacheEntity;\r\n if (!cacheEntity) {\r\n this.warn(\"CacheEntity not found\");\r\n return undefined;\r\n }\r\n\r\n try {\r\n const { value, metadata } = await cacheEntity.get(cacheKey);\r\n if (value instanceof Blob) {\r\n return value;\r\n }\r\n\r\n // Handle case where the value is stored as an ArrayBuffer\r\n if (value instanceof ArrayBuffer || ArrayBuffer.isView(value)) {\r\n const contentType = metadata?.contentType || \"application/octet-stream\";\r\n return new Blob([value], { type: contentType });\r\n }\r\n\r\n this.warn(\"Cached asset is not a Blob or ArrayBuffer\");\r\n return undefined;\r\n } catch (e) {\r\n return undefined;\r\n }\r\n }\r\n\r\n async storeAsset(\r\n assetId: string,\r\n content: Blob,\r\n contentType?: string\r\n ): Promise<void> {\r\n const cacheKey = this.generateCacheKey(assetId);\r\n\r\n const cacheEntity = this.cacheEntity;\r\n if (!cacheEntity) {\r\n this.warn(\"CacheEntity not found\");\r\n return;\r\n }\r\n\r\n const metadata: AssetCacheMetadata = {\r\n assetId,\r\n timestamp: Date.now(),\r\n contentType: contentType || content.type\r\n };\r\n\r\n await cacheEntity.store(cacheKey, content, metadata);\r\n }\r\n\r\n async hasAsset(assetId: string): Promise<boolean> {\r\n const cacheKey = this.generateCacheKey(assetId);\r\n\r\n const cacheEntity = this.cacheEntity;\r\n if (!cacheEntity) {\r\n this.warn(\"CacheEntity not found\");\r\n return false;\r\n }\r\n\r\n return await cacheEntity.has(cacheKey);\r\n }\r\n\r\n async invalidateAsset(assetId: string): Promise<void> {\r\n const cacheEntity = this.cacheEntity;\r\n if (!cacheEntity) {\r\n this.warn(\"CacheEntity not found\");\r\n return;\r\n }\r\n\r\n const cacheKey = this.generateCacheKey(assetId);\r\n await cacheEntity.invalidate(cacheKey);\r\n }\r\n\r\n private generateCacheKey(assetId: string): string {\r\n return `asset:${assetId}`;\r\n }\r\n}\r\n"]}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CacheEntity = void 0;
|
|
4
|
+
exports.makeCacheEntity = makeCacheEntity;
|
|
5
|
+
const core_1 = require("@vived/core");
|
|
6
|
+
/**
|
|
7
|
+
* Abstract entity that provides caching functionality for the application.
|
|
8
|
+
* CacheEntity is a singleton component that stores key-value pairs with optional metadata.
|
|
9
|
+
* It provides methods for storing, retrieving, checking existence, and invalidating cached values.
|
|
10
|
+
*/
|
|
11
|
+
class CacheEntity extends core_1.AppObjectEntity {
|
|
12
|
+
/**
|
|
13
|
+
* Gets the singleton instance of CacheEntity from the AppObjectRepo.
|
|
14
|
+
* @param appObjects - The application object repository
|
|
15
|
+
* @returns The CacheEntity instance or undefined if not registered
|
|
16
|
+
*/
|
|
17
|
+
static get(appObjects) {
|
|
18
|
+
return (0, core_1.getSingletonComponent)(CacheEntity.type, appObjects);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.CacheEntity = CacheEntity;
|
|
22
|
+
CacheEntity.type = "CacheEntity";
|
|
23
|
+
function makeCacheEntity(appObject) {
|
|
24
|
+
return new CacheEntityImp(appObject);
|
|
25
|
+
}
|
|
26
|
+
class CacheEntityImp extends CacheEntity {
|
|
27
|
+
constructor(appObject) {
|
|
28
|
+
super(appObject, CacheEntity.type);
|
|
29
|
+
this.cache = new Map();
|
|
30
|
+
this.appObjects.registerSingleton(this);
|
|
31
|
+
}
|
|
32
|
+
async get(key) {
|
|
33
|
+
if (!this.cache.has(key)) {
|
|
34
|
+
throw new Error(`Cache key not found: ${key}`);
|
|
35
|
+
}
|
|
36
|
+
return this.cache.get(key);
|
|
37
|
+
}
|
|
38
|
+
async store(key, value, metadata) {
|
|
39
|
+
this.cache.set(key, { value, metadata });
|
|
40
|
+
}
|
|
41
|
+
async has(key) {
|
|
42
|
+
return this.cache.has(key);
|
|
43
|
+
}
|
|
44
|
+
async invalidate(key) {
|
|
45
|
+
this.cache.delete(key);
|
|
46
|
+
}
|
|
47
|
+
async clear() {
|
|
48
|
+
this.cache.clear();
|
|
49
|
+
}
|
|
50
|
+
async size() {
|
|
51
|
+
return this.cache.size;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=CacheEntity.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CacheEntity.js","sourceRoot":"","sources":["../../../../src/Cache/Entities/CacheEntity.ts"],"names":[],"mappings":";;;AA0EA,0CAEC;AA5ED,sCAKqB;AAErB;;;;GAIG;AACH,MAAsB,WAAY,SAAQ,sBAAe;IAoDvD;;;;OAIG;IACH,MAAM,CAAC,GAAG,CAAC,UAAyB;QAClC,OAAO,IAAA,4BAAqB,EAAc,WAAW,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;IAC1E,CAAC;;AA3DH,kCA4DC;AA3DiB,gBAAI,GAAG,aAAa,CAAC;AA6DvC,SAAgB,eAAe,CAAC,SAAoB;IAClD,OAAO,IAAI,cAAc,CAAC,SAAS,CAAC,CAAC;AACvC,CAAC;AAED,MAAM,cAAe,SAAQ,WAAW;IAItC,YAAY,SAAoB;QAC9B,KAAK,CAAC,SAAS,EAAE,WAAW,CAAC,IAAI,CAAC,CAAC;QAJ7B,UAAK,GACX,IAAI,GAAG,EAAE,CAAC;QAIV,IAAI,CAAC,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC1C,CAAC;IAED,KAAK,CAAC,GAAG,CACP,GAAW;QAEX,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,IAAI,KAAK,CAAC,wBAAwB,GAAG,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAGxB,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,KAAK,CACT,GAAW,EACX,KAAU,EACV,QAA8B;QAE9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3C,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,GAAW;QACnB,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC7B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW;QAC1B,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;IAED,KAAK,CAAC,IAAI;QACR,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC;IACzB,CAAC;CACF","sourcesContent":["import {\r\n AppObject,\r\n AppObjectEntity,\r\n AppObjectRepo,\r\n getSingletonComponent\r\n} from \"@vived/core\";\r\n\r\n/**\r\n * Abstract entity that provides caching functionality for the application.\r\n * CacheEntity is a singleton component that stores key-value pairs with optional metadata.\r\n * It provides methods for storing, retrieving, checking existence, and invalidating cached values.\r\n */\r\nexport abstract class CacheEntity extends AppObjectEntity {\r\n static readonly type = \"CacheEntity\";\r\n\r\n /**\r\n * Retrieves a value from the cache by its key.\r\n * @param key - The unique identifier for the cached item\r\n * @returns Promise resolving to an object containing the cached value and optional metadata\r\n * @throws Error if the key does not exist in the cache\r\n */\r\n abstract get(\r\n key: string\r\n ): Promise<{ value: any; metadata?: Record<string, any> }>;\r\n\r\n /**\r\n * Stores a value in the cache with an associated key and optional metadata.\r\n * @param key - The unique identifier for the cached item\r\n * @param value - The value to cache\r\n * @param metadata - Optional metadata associated with the cached value\r\n * @returns Promise that resolves when the value has been stored\r\n */\r\n abstract store(\r\n key: string,\r\n value: any,\r\n metadata?: Record<string, any>\r\n ): Promise<void>;\r\n\r\n /**\r\n * Checks if a key exists in the cache.\r\n * @param key - The key to check\r\n * @returns Promise resolving to boolean indicating if the key exists\r\n */\r\n abstract has(key: string): Promise<boolean>;\r\n\r\n /**\r\n * Removes an item from the cache by its key.\r\n * @param key - The key to remove\r\n * @returns Promise that resolves when the key has been invalidated\r\n */\r\n abstract invalidate(key: string): Promise<void>;\r\n\r\n /**\r\n * Removes all items from the cache.\r\n * @returns Promise that resolves when the cache has been cleared\r\n */\r\n abstract clear(): Promise<void>;\r\n\r\n /**\r\n * Gets the number of items in the cache.\r\n * @returns Promise resolving to the number of cached items\r\n */\r\n abstract size(): Promise<number>;\r\n\r\n /**\r\n * Gets the singleton instance of CacheEntity from the AppObjectRepo.\r\n * @param appObjects - The application object repository\r\n * @returns The CacheEntity instance or undefined if not registered\r\n */\r\n static get(appObjects: AppObjectRepo): CacheEntity | undefined {\r\n return getSingletonComponent<CacheEntity>(CacheEntity.type, appObjects);\r\n }\r\n}\r\n\r\nexport function makeCacheEntity(appObject: AppObject): CacheEntity {\r\n return new CacheEntityImp(appObject);\r\n}\r\n\r\nclass CacheEntityImp extends CacheEntity {\r\n private cache: Map<string, { value: any; metadata?: Record<string, any> }> =\r\n new Map();\r\n\r\n constructor(appObject: AppObject) {\r\n super(appObject, CacheEntity.type);\r\n this.appObjects.registerSingleton(this);\r\n }\r\n\r\n async get(\r\n key: string\r\n ): Promise<{ value: any; metadata?: Record<string, any> }> {\r\n if (!this.cache.has(key)) {\r\n throw new Error(`Cache key not found: ${key}`);\r\n }\r\n return this.cache.get(key) as {\r\n value: any;\r\n metadata?: Record<string, any>;\r\n };\r\n }\r\n\r\n async store(\r\n key: string,\r\n value: any,\r\n metadata?: Record<string, any>\r\n ): Promise<void> {\r\n this.cache.set(key, { value, metadata });\r\n }\r\n\r\n async has(key: string): Promise<boolean> {\r\n return this.cache.has(key);\r\n }\r\n\r\n async invalidate(key: string): Promise<void> {\r\n this.cache.delete(key);\r\n }\r\n\r\n async clear(): Promise<void> {\r\n this.cache.clear();\r\n }\r\n\r\n async size(): Promise<number> {\r\n return this.cache.size;\r\n }\r\n}\r\n"]}
|