@oxy.so/core 1.1.1 → 1.2.0
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/.tsbuildinfo +1 -1
- package/dist/cjs/index.js +5 -4
- package/dist/cjs/utils/cache.js +28 -19
- package/dist/cjs/utils/languageUtils.js +26 -0
- package/dist/esm/.tsbuildinfo +1 -1
- package/dist/esm/index.js +1 -1
- package/dist/esm/utils/cache.js +28 -19
- package/dist/esm/utils/languageUtils.js +25 -0
- package/dist/types/.tsbuildinfo +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/utils/cache.d.ts +1 -4
- package/dist/types/utils/languageUtils.d.ts +13 -0
- package/package.json +12 -12
- package/src/index.ts +1 -0
- package/src/utils/__tests__/cacheLifecycle.test.ts +65 -0
- package/src/utils/__tests__/languageUtils.test.ts +25 -0
- package/src/utils/cache.ts +22 -20
- package/src/utils/languageUtils.ts +29 -0
package/dist/esm/index.js
CHANGED
|
@@ -91,7 +91,7 @@ export { TopicType, TopicSource } from './models/Topic.js';
|
|
|
91
91
|
// ---------------------------------------------------------------------------
|
|
92
92
|
// Languages
|
|
93
93
|
// ---------------------------------------------------------------------------
|
|
94
|
-
export { SUPPORTED_LANGUAGES, FALLBACK_LOCALE, getBaseLanguage, normalizeLocale, isSupportedLocale, getLanguageMetadata, getLanguageName, getNativeLanguageName, isRTLLocale, getUserLanguages, getPrimaryLanguage, } from './utils/languageUtils.js';
|
|
94
|
+
export { SUPPORTED_LANGUAGES, FALLBACK_LOCALE, getBaseLanguage, normalizeLocale, isSupportedLocale, getLanguageMetadata, getLanguageName, getNativeLanguageName, isRTLLocale, getUserLanguages, getPrimaryLanguage, coerceToSupportedLocale, } from './utils/languageUtils.js';
|
|
95
95
|
// ---------------------------------------------------------------------------
|
|
96
96
|
// Platform detection
|
|
97
97
|
// ---------------------------------------------------------------------------
|
package/dist/esm/utils/cache.js
CHANGED
|
@@ -78,6 +78,8 @@ export class TTLCache {
|
|
|
78
78
|
const effectiveTTL = ttl === undefined ? this.defaultTTL : ttl;
|
|
79
79
|
const expiresAt = now + effectiveTTL;
|
|
80
80
|
this.cache.set(key, { data, timestamp: now, expiresAt });
|
|
81
|
+
if (!cleanupInterval && activeCaches.has(this))
|
|
82
|
+
updateCleanupInterval();
|
|
81
83
|
}
|
|
82
84
|
/**
|
|
83
85
|
* Delete a specific cache entry
|
|
@@ -85,7 +87,10 @@ export class TTLCache {
|
|
|
85
87
|
* @returns true if entry was deleted, false if not found
|
|
86
88
|
*/
|
|
87
89
|
delete(key) {
|
|
88
|
-
|
|
90
|
+
const deleted = this.cache.delete(key);
|
|
91
|
+
if (activeCaches.has(this))
|
|
92
|
+
updateCleanupInterval();
|
|
93
|
+
return deleted;
|
|
89
94
|
}
|
|
90
95
|
/**
|
|
91
96
|
* Clear all cache entries
|
|
@@ -94,6 +99,8 @@ export class TTLCache {
|
|
|
94
99
|
this.cache.clear();
|
|
95
100
|
this.hits = 0;
|
|
96
101
|
this.misses = 0;
|
|
102
|
+
if (activeCaches.has(this))
|
|
103
|
+
updateCleanupInterval();
|
|
97
104
|
}
|
|
98
105
|
/**
|
|
99
106
|
* Check if a key exists and is not expired
|
|
@@ -191,28 +198,30 @@ const activeCaches = new Set();
|
|
|
191
198
|
*/
|
|
192
199
|
export function registerCacheForCleanup(cache) {
|
|
193
200
|
activeCaches.add(cache);
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
cleanupInterval
|
|
201
|
+
updateCleanupInterval();
|
|
202
|
+
}
|
|
203
|
+
/** Empty registered caches need no timer; importing a client must stay inert. */
|
|
204
|
+
function updateCleanupInterval() {
|
|
205
|
+
const hasEntries = [...activeCaches].some(cache => cache.size() > 0);
|
|
206
|
+
if (!hasEntries) {
|
|
207
|
+
if (cleanupInterval)
|
|
208
|
+
clearInterval(cleanupInterval);
|
|
209
|
+
cleanupInterval = null;
|
|
210
|
+
return;
|
|
203
211
|
}
|
|
212
|
+
if (cleanupInterval)
|
|
213
|
+
return;
|
|
214
|
+
cleanupInterval = setInterval(() => {
|
|
215
|
+
for (const cache of activeCaches)
|
|
216
|
+
cache.cleanup();
|
|
217
|
+
updateCleanupInterval();
|
|
218
|
+
}, 60000);
|
|
219
|
+
cleanupInterval.unref?.();
|
|
204
220
|
}
|
|
205
|
-
/**
|
|
206
|
-
* Unregister a cache from automatic cleanup
|
|
207
|
-
* @param cache Cache instance to unregister
|
|
208
|
-
*/
|
|
221
|
+
/** Unregister a cache without changing its entries or TTL behavior. */
|
|
209
222
|
export function unregisterCacheFromCleanup(cache) {
|
|
210
223
|
activeCaches.delete(cache);
|
|
211
|
-
|
|
212
|
-
if (activeCaches.size === 0 && cleanupInterval) {
|
|
213
|
-
clearInterval(cleanupInterval);
|
|
214
|
-
cleanupInterval = null;
|
|
215
|
-
}
|
|
224
|
+
updateCleanupInterval();
|
|
216
225
|
}
|
|
217
226
|
/**
|
|
218
227
|
* Stop all cleanup intervals (useful for testing)
|
|
@@ -210,3 +210,28 @@ export function getUserLanguages(user) {
|
|
|
210
210
|
export function getPrimaryLanguage(user) {
|
|
211
211
|
return getUserLanguages(user)[0];
|
|
212
212
|
}
|
|
213
|
+
/**
|
|
214
|
+
* Coerce a locale down to one from a CALLER-provided catalog: an exact
|
|
215
|
+
* canonical match wins, else the closest entry sharing the same base
|
|
216
|
+
* language (an `es-MX` account reads a host app's `es-ES` catalog), else
|
|
217
|
+
* `fallback`.
|
|
218
|
+
*
|
|
219
|
+
* A host app's own shipped translation catalog is rarely {@link SUPPORTED_LANGUAGES}
|
|
220
|
+
* itself — Oxy's account-locale catalog is broader than any one app's
|
|
221
|
+
* translated strings — so this is the one place that gap is bridged. Every Oxy
|
|
222
|
+
* app was independently re-deriving this exact algorithm against its own
|
|
223
|
+
* catalog before it moved here.
|
|
224
|
+
*/
|
|
225
|
+
export function coerceToSupportedLocale(locale, supportedLocales, fallback) {
|
|
226
|
+
if (locale) {
|
|
227
|
+
const canonical = normalizeLocale(locale);
|
|
228
|
+
if (canonical && supportedLocales.includes(canonical)) {
|
|
229
|
+
return canonical;
|
|
230
|
+
}
|
|
231
|
+
const base = getBaseLanguage(locale);
|
|
232
|
+
const byBase = supportedLocales.find((entry) => getBaseLanguage(entry) === base);
|
|
233
|
+
if (byBase)
|
|
234
|
+
return byBase;
|
|
235
|
+
}
|
|
236
|
+
return fallback;
|
|
237
|
+
}
|