@satoshibits/cache-keys
Version:
Type-safe cache key generation with zero dependencies
120 lines • 4.81 kB
JavaScript
;
import { sanitizeKeyComponent, decodeKeyComponent, splitKeyComponents } from './sanitizer.mjs';
/**
* Create a type-safe cache key factory
*
* @param namespace The namespace for this key type (e.g., 'user', 'account')
* @param type The specific type within the namespace (e.g., 'profile', 'settings')
* @param formatter Function to format the key suffix from arguments
* @param parser Optional function to parse the key back into components
* @returns A cache key factory
*/
export function createKeyFactory(namespace, type, formatter, parser) {
var prefix = type ? "".concat(namespace, ":").concat(type, ":") : "".concat(namespace, ":");
return {
key: function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
var suffix = formatter.apply(void 0, args);
return "".concat(prefix).concat(suffix);
},
parse: function (key) {
var _a;
if (!this.matches(key))
return null;
var suffix = key.slice(prefix.length);
if (parser) {
return parser(suffix);
}
// Default parser splits by colon and returns first part as 'id'
var parts = splitKeyComponents(suffix, ':', true);
return { id: (_a = parts[0]) !== null && _a !== void 0 ? _a : '' };
},
matches: function (key) {
return key.startsWith(prefix);
},
pattern: function () {
return "".concat(prefix, "*");
}
};
}
/**
* Create a simple key factory for single ID keys
*
* @param namespace The namespace for this key type
* @param type The specific type within the namespace
* @returns A cache key factory for single ID keys
*/
export function createSimpleKeyFactory(namespace, type) {
return createKeyFactory(namespace, type, function (id) { return sanitizeKeyComponent(String(id)); }, function (suffix) { return ({ id: decodeKeyComponent(suffix) }); });
}
/**
* Create a key factory for keys with two IDs
*
* @param namespace The namespace for this key type
* @param type The specific type within the namespace
* @param id1Name Name for the first ID in parsed result
* @param id2Name Name for the second ID in parsed result
* @returns A cache key factory for dual ID keys
*/
export function createDualKeyFactory(namespace, type, id1Name, id2Name) {
if (id1Name === void 0) { id1Name = 'id1'; }
if (id2Name === void 0) { id2Name = 'id2'; }
return createKeyFactory(namespace, type, function (id1, id2) {
return "".concat(sanitizeKeyComponent(String(id1)), ":").concat(sanitizeKeyComponent(String(id2)));
}, function (suffix) {
var _a;
var _b, _c;
var parts = splitKeyComponents(suffix, ':', true);
if (parts.length !== 2)
return null;
return _a = {},
_a[id1Name] = (_b = parts[0]) !== null && _b !== void 0 ? _b : '',
_a[id2Name] = (_c = parts[1]) !== null && _c !== void 0 ? _c : '',
_a;
});
}
/**
* Create a key factory for paginated lists
*
* @param namespace The namespace for this key type
* @param type The specific type within the namespace
* @returns A cache key factory for paginated keys
*/
export function createPaginatedKeyFactory(namespace, type) {
return createKeyFactory(namespace, type, function (id, page, limit) {
return "".concat(sanitizeKeyComponent(String(id)), ":page_").concat(page, ":limit_").concat(limit);
}, function (suffix) {
var _a, _b, _c;
var match = /^(.+?):page_(\d+):limit_(\d+)$/.exec(suffix);
if (!match)
return null;
return {
id: decodeKeyComponent((_a = match[1]) !== null && _a !== void 0 ? _a : ''),
page: (_b = match[2]) !== null && _b !== void 0 ? _b : '',
limit: (_c = match[3]) !== null && _c !== void 0 ? _c : '',
};
});
}
/**
* Create a versioned key factory
*
* @param namespace The namespace for this key type
* @param type The specific type within the namespace
* @returns A cache key factory for versioned keys
*/
export function createVersionedKeyFactory(namespace, type) {
return createKeyFactory(namespace, type, function (id, version) { return "".concat(sanitizeKeyComponent(String(id)), ":v").concat(version); }, function (suffix) {
var _a, _b;
var match = /^(.+?):v(\d+)$/.exec(suffix);
if (!match)
return null;
return {
id: decodeKeyComponent((_a = match[1]) !== null && _a !== void 0 ? _a : ''),
version: (_b = match[2]) !== null && _b !== void 0 ? _b : '',
};
});
}
//# sourceMappingURL=factory.mjs.map