keyv-registry 0.1.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.
Files changed (47) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +202 -0
  3. package/dist/cjs/index.d.cts +37 -0
  4. package/dist/cjs/index.d.ts +37 -0
  5. package/dist/cjs/index.js +82 -0
  6. package/dist/cjs/index.js.map +1 -0
  7. package/dist/cjs/loadAdapter.d.cts +9 -0
  8. package/dist/cjs/loadAdapter.d.ts +9 -0
  9. package/dist/cjs/loadAdapter.js +74 -0
  10. package/dist/cjs/loadAdapter.js.map +1 -0
  11. package/dist/cjs/package.json +1 -0
  12. package/dist/cjs/registry.d.cts +13 -0
  13. package/dist/cjs/registry.d.ts +13 -0
  14. package/dist/cjs/registry.js +119 -0
  15. package/dist/cjs/registry.js.map +1 -0
  16. package/dist/cjs/types.d.cts +33 -0
  17. package/dist/cjs/types.d.ts +33 -0
  18. package/dist/cjs/types.js +5 -0
  19. package/dist/cjs/types.js.map +1 -0
  20. package/dist/cjs/utils.d.cts +8 -0
  21. package/dist/cjs/utils.d.ts +8 -0
  22. package/dist/cjs/utils.js +152 -0
  23. package/dist/cjs/utils.js.map +1 -0
  24. package/dist/cjs/worker.d.cts +5 -0
  25. package/dist/cjs/worker.d.ts +5 -0
  26. package/dist/cjs/worker.js +138 -0
  27. package/dist/cjs/worker.js.map +1 -0
  28. package/dist/esm/index.d.ts +37 -0
  29. package/dist/esm/index.js +50 -0
  30. package/dist/esm/index.js.map +1 -0
  31. package/dist/esm/loadAdapter.d.ts +9 -0
  32. package/dist/esm/loadAdapter.js +52 -0
  33. package/dist/esm/loadAdapter.js.map +1 -0
  34. package/dist/esm/package.json +1 -0
  35. package/dist/esm/registry.d.ts +13 -0
  36. package/dist/esm/registry.js +73 -0
  37. package/dist/esm/registry.js.map +1 -0
  38. package/dist/esm/types.d.ts +33 -0
  39. package/dist/esm/types.js +3 -0
  40. package/dist/esm/types.js.map +1 -0
  41. package/dist/esm/utils.d.ts +8 -0
  42. package/dist/esm/utils.js +33 -0
  43. package/dist/esm/utils.js.map +1 -0
  44. package/dist/esm/worker.d.ts +5 -0
  45. package/dist/esm/worker.js +75 -0
  46. package/dist/esm/worker.js.map +1 -0
  47. package/package.json +62 -0
@@ -0,0 +1,33 @@
1
+ import type Keyv from 'keyv';
2
+ /**
3
+ * Configuration for a protocol adapter
4
+ */
5
+ export interface AdapterConfig {
6
+ /** npm package name, or null for built-in adapters */
7
+ package: string | null;
8
+ /** Named export from the package (default: 'default') */
9
+ exportName?: string;
10
+ /** Custom function to map URL to adapter options */
11
+ optionsMapper?: (url: URL) => Record<string, unknown>;
12
+ }
13
+ /**
14
+ * Options for createStore
15
+ */
16
+ export interface CreateStoreOptions {
17
+ /** Pre-instantiated adapter (bypasses URI loading) */
18
+ store?: unknown;
19
+ /** Keyv namespace */
20
+ namespace?: string;
21
+ /** Default TTL in milliseconds */
22
+ ttl?: number;
23
+ /** Additional Keyv options */
24
+ [key: string]: unknown;
25
+ }
26
+ /**
27
+ * Callback type for createStore
28
+ */
29
+ export type CreateStoreCallback<T> = (err: Error | null, store?: Keyv<T>) => void;
30
+ /**
31
+ * Internal callback type for loadAdapter
32
+ */
33
+ export type LoadAdapterCallback = (err: Error | null, Adapter?: unknown) => void;
@@ -0,0 +1,33 @@
1
+ import type Keyv from 'keyv';
2
+ /**
3
+ * Configuration for a protocol adapter
4
+ */
5
+ export interface AdapterConfig {
6
+ /** npm package name, or null for built-in adapters */
7
+ package: string | null;
8
+ /** Named export from the package (default: 'default') */
9
+ exportName?: string;
10
+ /** Custom function to map URL to adapter options */
11
+ optionsMapper?: (url: URL) => Record<string, unknown>;
12
+ }
13
+ /**
14
+ * Options for createStore
15
+ */
16
+ export interface CreateStoreOptions {
17
+ /** Pre-instantiated adapter (bypasses URI loading) */
18
+ store?: unknown;
19
+ /** Keyv namespace */
20
+ namespace?: string;
21
+ /** Default TTL in milliseconds */
22
+ ttl?: number;
23
+ /** Additional Keyv options */
24
+ [key: string]: unknown;
25
+ }
26
+ /**
27
+ * Callback type for createStore
28
+ */
29
+ export type CreateStoreCallback<T> = (err: Error | null, store?: Keyv<T>) => void;
30
+ /**
31
+ * Internal callback type for loadAdapter
32
+ */
33
+ export type LoadAdapterCallback = (err: Error | null, Adapter?: unknown) => void;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":""}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Resolve file path from URL, handling ~ and . prefixes
3
+ */
4
+ export declare function resolveFilePath(url: URL): string;
5
+ /**
6
+ * Parse URL search params into options object with type conversion
7
+ */
8
+ export declare function parseUriOptions(url: URL): Record<string, unknown>;
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Resolve file path from URL, handling ~ and . prefixes
3
+ */
4
+ export declare function resolveFilePath(url: URL): string;
5
+ /**
6
+ * Parse URL search params into options object with type conversion
7
+ */
8
+ export declare function parseUriOptions(url: URL): Record<string, unknown>;
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ function _export(target, all) {
6
+ for(var name in all)Object.defineProperty(target, name, {
7
+ enumerable: true,
8
+ get: Object.getOwnPropertyDescriptor(all, name).get
9
+ });
10
+ }
11
+ _export(exports, {
12
+ get parseUriOptions () {
13
+ return parseUriOptions;
14
+ },
15
+ get resolveFilePath () {
16
+ return resolveFilePath;
17
+ }
18
+ });
19
+ var _nodefs = /*#__PURE__*/ _interop_require_wildcard(require("node:fs"));
20
+ var _nodeos = /*#__PURE__*/ _interop_require_wildcard(require("node:os"));
21
+ var _nodepath = /*#__PURE__*/ _interop_require_wildcard(require("node:path"));
22
+ function _array_like_to_array(arr, len) {
23
+ if (len == null || len > arr.length) len = arr.length;
24
+ for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
25
+ return arr2;
26
+ }
27
+ function _array_with_holes(arr) {
28
+ if (Array.isArray(arr)) return arr;
29
+ }
30
+ function _getRequireWildcardCache(nodeInterop) {
31
+ if (typeof WeakMap !== "function") return null;
32
+ var cacheBabelInterop = new WeakMap();
33
+ var cacheNodeInterop = new WeakMap();
34
+ return (_getRequireWildcardCache = function(nodeInterop) {
35
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
36
+ })(nodeInterop);
37
+ }
38
+ function _interop_require_wildcard(obj, nodeInterop) {
39
+ if (!nodeInterop && obj && obj.__esModule) {
40
+ return obj;
41
+ }
42
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
43
+ return {
44
+ default: obj
45
+ };
46
+ }
47
+ var cache = _getRequireWildcardCache(nodeInterop);
48
+ if (cache && cache.has(obj)) {
49
+ return cache.get(obj);
50
+ }
51
+ var newObj = {
52
+ __proto__: null
53
+ };
54
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
55
+ for(var key in obj){
56
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
57
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
58
+ if (desc && (desc.get || desc.set)) {
59
+ Object.defineProperty(newObj, key, desc);
60
+ } else {
61
+ newObj[key] = obj[key];
62
+ }
63
+ }
64
+ }
65
+ newObj.default = obj;
66
+ if (cache) {
67
+ cache.set(obj, newObj);
68
+ }
69
+ return newObj;
70
+ }
71
+ function _iterable_to_array_limit(arr, i) {
72
+ var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
73
+ if (_i == null) return;
74
+ var _arr = [];
75
+ var _n = true;
76
+ var _d = false;
77
+ var _s, _e;
78
+ try {
79
+ for(_i = _i.call(arr); !(_n = (_s = _i.next()).done); _n = true){
80
+ _arr.push(_s.value);
81
+ if (i && _arr.length === i) break;
82
+ }
83
+ } catch (err) {
84
+ _d = true;
85
+ _e = err;
86
+ } finally{
87
+ try {
88
+ if (!_n && _i["return"] != null) _i["return"]();
89
+ } finally{
90
+ if (_d) throw _e;
91
+ }
92
+ }
93
+ return _arr;
94
+ }
95
+ function _non_iterable_rest() {
96
+ throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
97
+ }
98
+ function _sliced_to_array(arr, i) {
99
+ return _array_with_holes(arr) || _iterable_to_array_limit(arr, i) || _unsupported_iterable_to_array(arr, i) || _non_iterable_rest();
100
+ }
101
+ function _unsupported_iterable_to_array(o, minLen) {
102
+ if (!o) return;
103
+ if (typeof o === "string") return _array_like_to_array(o, minLen);
104
+ var n = Object.prototype.toString.call(o).slice(8, -1);
105
+ if (n === "Object" && o.constructor) n = o.constructor.name;
106
+ if (n === "Map" || n === "Set") return Array.from(n);
107
+ if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
108
+ }
109
+ function resolveFilePath(url) {
110
+ var filePath = url.pathname;
111
+ // Handle ~ for home directory
112
+ if (url.host === '~') {
113
+ filePath = _nodepath.join(_nodeos.homedir(), filePath.slice(1));
114
+ } else if (url.host === '.') {
115
+ filePath = _nodepath.join(process.cwd(), filePath.slice(1));
116
+ }
117
+ // Ensure directory exists
118
+ _nodefs.mkdirSync(_nodepath.dirname(filePath), {
119
+ recursive: true
120
+ });
121
+ return filePath;
122
+ }
123
+ function parseUriOptions(url) {
124
+ var options = {};
125
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
126
+ try {
127
+ for(var _iterator = url.searchParams[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
128
+ var _step_value = _sliced_to_array(_step.value, 2), key = _step_value[0], value = _step_value[1];
129
+ // Auto-convert types
130
+ if (value === 'true') options[key] = true;
131
+ else if (value === 'false') options[key] = false;
132
+ else if (/^\d+$/.test(value)) options[key] = Number.parseInt(value, 10);
133
+ else if (/^\d+\.\d+$/.test(value)) options[key] = Number.parseFloat(value);
134
+ else options[key] = value;
135
+ }
136
+ } catch (err) {
137
+ _didIteratorError = true;
138
+ _iteratorError = err;
139
+ } finally{
140
+ try {
141
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
142
+ _iterator.return();
143
+ }
144
+ } finally{
145
+ if (_didIteratorError) {
146
+ throw _iteratorError;
147
+ }
148
+ }
149
+ }
150
+ return options;
151
+ }
152
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/utils.ts"],"sourcesContent":["import * as fs from 'node:fs';\nimport * as os from 'node:os';\nimport * as path from 'node:path';\n\n/**\n * Resolve file path from URL, handling ~ and . prefixes\n */\nexport function resolveFilePath(url: URL): string {\n let filePath = url.pathname;\n\n // Handle ~ for home directory\n if (url.host === '~') {\n filePath = path.join(os.homedir(), filePath.slice(1));\n }\n // Handle . for current directory\n else if (url.host === '.') {\n filePath = path.join(process.cwd(), filePath.slice(1));\n }\n\n // Ensure directory exists\n fs.mkdirSync(path.dirname(filePath), { recursive: true });\n\n return filePath;\n}\n\n/**\n * Parse URL search params into options object with type conversion\n */\nexport function parseUriOptions(url: URL): Record<string, unknown> {\n const options: Record<string, unknown> = {};\n\n for (const [key, value] of url.searchParams) {\n // Auto-convert types\n if (value === 'true') options[key] = true;\n else if (value === 'false') options[key] = false;\n else if (/^\\d+$/.test(value)) options[key] = Number.parseInt(value, 10);\n else if (/^\\d+\\.\\d+$/.test(value)) options[key] = Number.parseFloat(value);\n else options[key] = value;\n }\n\n return options;\n}\n"],"names":["parseUriOptions","resolveFilePath","url","filePath","pathname","host","path","join","os","homedir","slice","process","cwd","fs","mkdirSync","dirname","recursive","options","searchParams","key","value","test","Number","parseInt","parseFloat"],"mappings":";;;;;;;;;;;QA4BgBA;eAAAA;;QArBAC;eAAAA;;;8DAPI;8DACA;gEACE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKf,SAASA,gBAAgBC,GAAQ;IACtC,IAAIC,WAAWD,IAAIE,QAAQ;IAE3B,8BAA8B;IAC9B,IAAIF,IAAIG,IAAI,KAAK,KAAK;QACpBF,WAAWG,UAAKC,IAAI,CAACC,QAAGC,OAAO,IAAIN,SAASO,KAAK,CAAC;IACpD,OAEK,IAAIR,IAAIG,IAAI,KAAK,KAAK;QACzBF,WAAWG,UAAKC,IAAI,CAACI,QAAQC,GAAG,IAAIT,SAASO,KAAK,CAAC;IACrD;IAEA,0BAA0B;IAC1BG,QAAGC,SAAS,CAACR,UAAKS,OAAO,CAACZ,WAAW;QAAEa,WAAW;IAAK;IAEvD,OAAOb;AACT;AAKO,SAASH,gBAAgBE,GAAQ;IACtC,IAAMe,UAAmC,CAAC;QAErC,kCAAA,2BAAA;;QAAL,QAAK,YAAsBf,IAAIgB,YAAY,qBAAtC,SAAA,6BAAA,QAAA,yBAAA,iCAAwC;YAAxC,mCAAA,iBAAOC,sBAAKC;YACf,qBAAqB;YACrB,IAAIA,UAAU,QAAQH,OAAO,CAACE,IAAI,GAAG;iBAChC,IAAIC,UAAU,SAASH,OAAO,CAACE,IAAI,GAAG;iBACtC,IAAI,QAAQE,IAAI,CAACD,QAAQH,OAAO,CAACE,IAAI,GAAGG,OAAOC,QAAQ,CAACH,OAAO;iBAC/D,IAAI,aAAaC,IAAI,CAACD,QAAQH,OAAO,CAACE,IAAI,GAAGG,OAAOE,UAAU,CAACJ;iBAC/DH,OAAO,CAACE,IAAI,GAAGC;QACtB;;QAPK;QAAA;;;iBAAA,6BAAA;gBAAA;;;gBAAA;sBAAA;;;;IASL,OAAOH;AACT"}
@@ -0,0 +1,5 @@
1
+ import type { CreateStoreCallback, CreateStoreOptions } from './types.js';
2
+ /**
3
+ * Core worker function that creates a Keyv store
4
+ */
5
+ export default function worker<T>(uri: string, options: CreateStoreOptions, callback: CreateStoreCallback<T>): void;
@@ -0,0 +1,5 @@
1
+ import type { CreateStoreCallback, CreateStoreOptions } from './types.js';
2
+ /**
3
+ * Core worker function that creates a Keyv store
4
+ */
5
+ export default function worker<T>(uri: string, options: CreateStoreOptions, callback: CreateStoreCallback<T>): void;
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, /**
6
+ * Core worker function that creates a Keyv store
7
+ */ "default", {
8
+ enumerable: true,
9
+ get: function() {
10
+ return worker;
11
+ }
12
+ });
13
+ var _keyv = /*#__PURE__*/ _interop_require_default(require("keyv"));
14
+ var _loadAdapterts = /*#__PURE__*/ _interop_require_default(require("./loadAdapter.js"));
15
+ var _registryts = require("./registry.js");
16
+ var _utilsts = require("./utils.js");
17
+ function _define_property(obj, key, value) {
18
+ if (key in obj) {
19
+ Object.defineProperty(obj, key, {
20
+ value: value,
21
+ enumerable: true,
22
+ configurable: true,
23
+ writable: true
24
+ });
25
+ } else {
26
+ obj[key] = value;
27
+ }
28
+ return obj;
29
+ }
30
+ function _interop_require_default(obj) {
31
+ return obj && obj.__esModule ? obj : {
32
+ default: obj
33
+ };
34
+ }
35
+ function _object_spread(target) {
36
+ for(var i = 1; i < arguments.length; i++){
37
+ var source = arguments[i] != null ? arguments[i] : {};
38
+ var ownKeys = Object.keys(source);
39
+ if (typeof Object.getOwnPropertySymbols === "function") {
40
+ ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
41
+ return Object.getOwnPropertyDescriptor(source, sym).enumerable;
42
+ }));
43
+ }
44
+ ownKeys.forEach(function(key) {
45
+ _define_property(target, key, source[key]);
46
+ });
47
+ }
48
+ return target;
49
+ }
50
+ function _object_without_properties(source, excluded) {
51
+ if (source == null) return {};
52
+ var target = _object_without_properties_loose(source, excluded);
53
+ var key, i;
54
+ if (Object.getOwnPropertySymbols) {
55
+ var sourceSymbolKeys = Object.getOwnPropertySymbols(source);
56
+ for(i = 0; i < sourceSymbolKeys.length; i++){
57
+ key = sourceSymbolKeys[i];
58
+ if (excluded.indexOf(key) >= 0) continue;
59
+ if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
60
+ target[key] = source[key];
61
+ }
62
+ }
63
+ return target;
64
+ }
65
+ function _object_without_properties_loose(source, excluded) {
66
+ if (source == null) return {};
67
+ var target = {};
68
+ var sourceKeys = Object.keys(source);
69
+ var key, i;
70
+ for(i = 0; i < sourceKeys.length; i++){
71
+ key = sourceKeys[i];
72
+ if (excluded.indexOf(key) >= 0) continue;
73
+ target[key] = source[key];
74
+ }
75
+ return target;
76
+ }
77
+ function worker(uri, options, callback) {
78
+ // Passthrough: pre-instantiated adapter provided
79
+ if (options.store) {
80
+ try {
81
+ var keyv = new _keyv.default(_object_spread({}, options));
82
+ callback(null, keyv);
83
+ } catch (err) {
84
+ callback(err);
85
+ }
86
+ return;
87
+ }
88
+ // Parse URI
89
+ var url;
90
+ try {
91
+ url = new URL(uri);
92
+ } catch (_err) {
93
+ callback(new Error("Invalid URI: ".concat(uri)));
94
+ return;
95
+ }
96
+ var config = (0, _registryts.getAdapterConfig)(url.protocol);
97
+ if (!config) {
98
+ callback(new Error("Unknown protocol: ".concat(url.protocol, ". Use registerAdapter() to add support.")));
99
+ return;
100
+ }
101
+ // Memory store - no package needed
102
+ if (config.package === null) {
103
+ try {
104
+ var keyv1 = new _keyv.default(_object_spread({}, (0, _utilsts.parseUriOptions)(url), options));
105
+ callback(null, keyv1);
106
+ } catch (err) {
107
+ callback(err);
108
+ }
109
+ return;
110
+ }
111
+ // Load adapter (install if needed)
112
+ (0, _loadAdapterts.default)(config.package, config.exportName, function(err, AdapterClass) {
113
+ if (err) {
114
+ callback(err);
115
+ return;
116
+ }
117
+ try {
118
+ var _config_optionsMapper;
119
+ var _config_optionsMapper1;
120
+ // Build adapter options: URI params + custom mapper + user options
121
+ var adapterOptions = _object_spread({}, (0, _utilsts.parseUriOptions)(url), (_config_optionsMapper1 = (_config_optionsMapper = config.optionsMapper) === null || _config_optionsMapper === void 0 ? void 0 : _config_optionsMapper.call(config, url)) !== null && _config_optionsMapper1 !== void 0 ? _config_optionsMapper1 : {
122
+ uri: uri
123
+ }, options);
124
+ // Remove store from adapter options to avoid confusion
125
+ var _ = adapterOptions.store, cleanAdapterOptions = _object_without_properties(adapterOptions, [
126
+ "store"
127
+ ]);
128
+ var storeInstance = new AdapterClass(cleanAdapterOptions);
129
+ var keyv = new _keyv.default(_object_spread({
130
+ store: storeInstance
131
+ }, options));
132
+ callback(null, keyv);
133
+ } catch (createErr) {
134
+ callback(createErr);
135
+ }
136
+ });
137
+ }
138
+ /* CJS INTEROP */ if (exports.__esModule && exports.default) { try { Object.defineProperty(exports.default, '__esModule', { value: true }); for (var key in exports) { exports.default[key] = exports[key]; } } catch (_) {}; module.exports = exports.default; }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/worker.ts"],"sourcesContent":["import Keyv from 'keyv';\nimport loadAdapter from './loadAdapter.ts';\nimport { getAdapterConfig } from './registry.ts';\nimport type { CreateStoreCallback, CreateStoreOptions } from './types.ts';\nimport { parseUriOptions } from './utils.ts';\n\n/**\n * Core worker function that creates a Keyv store\n */\nexport default function worker<T>(uri: string, options: CreateStoreOptions, callback: CreateStoreCallback<T>): void {\n // Passthrough: pre-instantiated adapter provided\n if (options.store) {\n try {\n const keyv = new Keyv<T>({ ...options });\n callback(null, keyv);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Parse URI\n let url: URL;\n try {\n url = new URL(uri);\n } catch (_err) {\n callback(new Error(`Invalid URI: ${uri}`));\n return;\n }\n\n const config = getAdapterConfig(url.protocol);\n\n if (!config) {\n callback(new Error(`Unknown protocol: ${url.protocol}. Use registerAdapter() to add support.`));\n return;\n }\n\n // Memory store - no package needed\n if (config.package === null) {\n try {\n const keyv = new Keyv<T>({ ...parseUriOptions(url), ...options });\n callback(null, keyv);\n } catch (err) {\n callback(err as Error);\n }\n return;\n }\n\n // Load adapter (install if needed)\n loadAdapter(config.package, config.exportName, (err, AdapterClass) => {\n if (err) {\n callback(err);\n return;\n }\n\n try {\n // Build adapter options: URI params + custom mapper + user options\n const adapterOptions = {\n ...parseUriOptions(url),\n ...(config.optionsMapper?.(url) ?? { uri }),\n ...options,\n };\n\n // Remove store from adapter options to avoid confusion\n const { store: _, ...cleanAdapterOptions } = adapterOptions;\n\n const storeInstance = new (AdapterClass as new (options: Record<string, unknown>) => unknown)(cleanAdapterOptions);\n const keyv = new Keyv<T>({ store: storeInstance, ...options });\n\n callback(null, keyv);\n } catch (createErr) {\n callback(createErr as Error);\n }\n });\n}\n"],"names":["worker","uri","options","callback","store","keyv","Keyv","err","url","URL","_err","Error","config","getAdapterConfig","protocol","package","parseUriOptions","loadAdapter","exportName","AdapterClass","adapterOptions","optionsMapper","_","cleanAdapterOptions","storeInstance","createErr"],"mappings":";;;;+BAMA;;CAEC,GACD;;;eAAwBA;;;2DATP;oEACO;0BACS;uBAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAKjB,SAASA,OAAUC,GAAW,EAAEC,OAA2B,EAAEC,QAAgC;IAC1G,iDAAiD;IACjD,IAAID,QAAQE,KAAK,EAAE;QACjB,IAAI;YACF,IAAMC,OAAO,IAAIC,aAAI,CAAI,mBAAKJ;YAC9BC,SAAS,MAAME;QACjB,EAAE,OAAOE,KAAK;YACZJ,SAASI;QACX;QACA;IACF;IAEA,YAAY;IACZ,IAAIC;IACJ,IAAI;QACFA,MAAM,IAAIC,IAAIR;IAChB,EAAE,OAAOS,MAAM;QACbP,SAAS,IAAIQ,MAAM,AAAC,gBAAmB,OAAJV;QACnC;IACF;IAEA,IAAMW,SAASC,IAAAA,4BAAgB,EAACL,IAAIM,QAAQ;IAE5C,IAAI,CAACF,QAAQ;QACXT,SAAS,IAAIQ,MAAM,AAAC,qBAAiC,OAAbH,IAAIM,QAAQ,EAAC;QACrD;IACF;IAEA,mCAAmC;IACnC,IAAIF,OAAOG,OAAO,KAAK,MAAM;QAC3B,IAAI;YACF,IAAMV,QAAO,IAAIC,aAAI,CAAI,mBAAKU,IAAAA,wBAAe,EAACR,MAASN;YACvDC,SAAS,MAAME;QACjB,EAAE,OAAOE,KAAK;YACZJ,SAASI;QACX;QACA;IACF;IAEA,mCAAmC;IACnCU,IAAAA,sBAAW,EAACL,OAAOG,OAAO,EAAEH,OAAOM,UAAU,EAAE,SAACX,KAAKY;QACnD,IAAIZ,KAAK;YACPJ,SAASI;YACT;QACF;QAEA,IAAI;gBAIIK;gBAAAA;YAHN,mEAAmE;YACnE,IAAMQ,iBAAiB,mBAClBJ,IAAAA,wBAAe,EAACR,MACfI,CAAAA,0BAAAA,wBAAAA,OAAOS,aAAa,cAApBT,4CAAAA,2BAAAA,QAAuBJ,kBAAvBI,oCAAAA,yBAA+B;gBAAEX,KAAAA;YAAI,GACtCC;YAGL,uDAAuD;YACvD,IAAQE,AAAOkB,IAA8BF,eAArChB,OAAamB,iDAAwBH;gBAArChB;;YAER,IAAMoB,gBAAgB,IAAKL,aAAmEI;YAC9F,IAAMlB,OAAO,IAAIC,aAAI,CAAI;gBAAEF,OAAOoB;eAAkBtB;YAEpDC,SAAS,MAAME;QACjB,EAAE,OAAOoB,WAAW;YAClBtB,SAASsB;QACX;IACF;AACF"}
@@ -0,0 +1,37 @@
1
+ import type Keyv from 'keyv';
2
+ import type { CreateStoreCallback, CreateStoreOptions } from './types.js';
3
+ export { clearAdapterCache } from './loadAdapter.js';
4
+ export { getRegistry, registerAdapter } from './registry.js';
5
+ export type { AdapterConfig, CreateStoreCallback, CreateStoreOptions } from './types.js';
6
+ /**
7
+ * Create a Keyv store from a URI string
8
+ *
9
+ * Supports dual-boot API (callback or Promise):
10
+ *
11
+ * @example
12
+ * // Promise API
13
+ * const store = await createStore('redis://localhost:6379');
14
+ * const file = await createStore('file://~/.cache/app/data.json');
15
+ * const memory = await createStore('memory://');
16
+ *
17
+ * @example
18
+ * // Callback API
19
+ * createStore('redis://localhost:6379', (err, store) => {
20
+ * if (err) throw err;
21
+ * // use store
22
+ * });
23
+ *
24
+ * @example
25
+ * // With options
26
+ * const store = await createStore('redis://localhost:6379', {
27
+ * namespace: 'myapp',
28
+ * ttl: 60000
29
+ * });
30
+ *
31
+ * @example
32
+ * // Pre-instantiated adapter passthrough
33
+ * import KeyvRedis from '@keyv/redis';
34
+ * const redis = new KeyvRedis('redis://localhost:6379');
35
+ * const store = await createStore('redis://ignored', { store: redis });
36
+ */
37
+ export default function createStore<T>(uri: string, options?: CreateStoreOptions | CreateStoreCallback<T>, callback?: CreateStoreCallback<T>): undefined | Promise<Keyv<T>>;
@@ -0,0 +1,50 @@
1
+ import worker from './worker.js';
2
+ export { clearAdapterCache } from './loadAdapter.js';
3
+ export { getRegistry, registerAdapter } from './registry.js';
4
+ /**
5
+ * Create a Keyv store from a URI string
6
+ *
7
+ * Supports dual-boot API (callback or Promise):
8
+ *
9
+ * @example
10
+ * // Promise API
11
+ * const store = await createStore('redis://localhost:6379');
12
+ * const file = await createStore('file://~/.cache/app/data.json');
13
+ * const memory = await createStore('memory://');
14
+ *
15
+ * @example
16
+ * // Callback API
17
+ * createStore('redis://localhost:6379', (err, store) => {
18
+ * if (err) throw err;
19
+ * // use store
20
+ * });
21
+ *
22
+ * @example
23
+ * // With options
24
+ * const store = await createStore('redis://localhost:6379', {
25
+ * namespace: 'myapp',
26
+ * ttl: 60000
27
+ * });
28
+ *
29
+ * @example
30
+ * // Pre-instantiated adapter passthrough
31
+ * import KeyvRedis from '@keyv/redis';
32
+ * const redis = new KeyvRedis('redis://localhost:6379');
33
+ * const store = await createStore('redis://ignored', { store: redis });
34
+ */ export default function createStore(uri, options, callback) {
35
+ // Normalize arguments
36
+ if (typeof options === 'function') {
37
+ callback = options;
38
+ options = {};
39
+ }
40
+ options = options || {};
41
+ // Callback mode
42
+ if (typeof callback === 'function') {
43
+ worker(uri, options, callback);
44
+ return undefined;
45
+ }
46
+ // Promise mode
47
+ return new Promise((resolve, reject)=>{
48
+ worker(uri, options, (err, store)=>err ? reject(err) : resolve(store));
49
+ });
50
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/index.ts"],"sourcesContent":["import type Keyv from 'keyv';\nimport type { CreateStoreCallback, CreateStoreOptions } from './types.ts';\nimport worker from './worker.ts';\n\nexport { clearAdapterCache } from './loadAdapter.ts';\nexport { getRegistry, registerAdapter } from './registry.ts';\nexport type { AdapterConfig, CreateStoreCallback, CreateStoreOptions } from './types.ts';\n\n/**\n * Create a Keyv store from a URI string\n *\n * Supports dual-boot API (callback or Promise):\n *\n * @example\n * // Promise API\n * const store = await createStore('redis://localhost:6379');\n * const file = await createStore('file://~/.cache/app/data.json');\n * const memory = await createStore('memory://');\n *\n * @example\n * // Callback API\n * createStore('redis://localhost:6379', (err, store) => {\n * if (err) throw err;\n * // use store\n * });\n *\n * @example\n * // With options\n * const store = await createStore('redis://localhost:6379', {\n * namespace: 'myapp',\n * ttl: 60000\n * });\n *\n * @example\n * // Pre-instantiated adapter passthrough\n * import KeyvRedis from '@keyv/redis';\n * const redis = new KeyvRedis('redis://localhost:6379');\n * const store = await createStore('redis://ignored', { store: redis });\n */\nexport default function createStore<T>(uri: string, options?: CreateStoreOptions | CreateStoreCallback<T>, callback?: CreateStoreCallback<T>): undefined | Promise<Keyv<T>> {\n // Normalize arguments\n if (typeof options === 'function') {\n callback = options;\n options = {};\n }\n options = options || {};\n\n // Callback mode\n if (typeof callback === 'function') {\n worker(uri, options, callback);\n return undefined;\n }\n\n // Promise mode\n return new Promise((resolve, reject) => {\n worker(uri, options as CreateStoreOptions, (err, store) => (err ? reject(err) : resolve(store as Keyv<T>)));\n });\n}\n"],"names":["worker","clearAdapterCache","getRegistry","registerAdapter","createStore","uri","options","callback","undefined","Promise","resolve","reject","err","store"],"mappings":"AAEA,OAAOA,YAAY,cAAc;AAEjC,SAASC,iBAAiB,QAAQ,mBAAmB;AACrD,SAASC,WAAW,EAAEC,eAAe,QAAQ,gBAAgB;AAG7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GACD,eAAe,SAASC,YAAeC,GAAW,EAAEC,OAAqD,EAAEC,QAAiC;IAC1I,sBAAsB;IACtB,IAAI,OAAOD,YAAY,YAAY;QACjCC,WAAWD;QACXA,UAAU,CAAC;IACb;IACAA,UAAUA,WAAW,CAAC;IAEtB,gBAAgB;IAChB,IAAI,OAAOC,aAAa,YAAY;QAClCP,OAAOK,KAAKC,SAASC;QACrB,OAAOC;IACT;IAEA,eAAe;IACf,OAAO,IAAIC,QAAQ,CAACC,SAASC;QAC3BX,OAAOK,KAAKC,SAA+B,CAACM,KAAKC,QAAWD,MAAMD,OAAOC,OAAOF,QAAQG;IAC1F;AACF"}
@@ -0,0 +1,9 @@
1
+ import type { LoadAdapterCallback } from './types.js';
2
+ /**
3
+ * Load an adapter, installing it dynamically if needed
4
+ */
5
+ export default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void;
6
+ /**
7
+ * Clear the adapter cache (useful for testing)
8
+ */
9
+ export declare function clearAdapterCache(): void;
@@ -0,0 +1,52 @@
1
+ import Module from 'node:module';
2
+ import path from 'node:path';
3
+ import url from 'node:url';
4
+ import installModule from 'install-module-linked';
5
+ // Create require function for ESM compatibility
6
+ const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
7
+ // Determine node_modules path
8
+ const _dirname = path.dirname(typeof __dirname !== 'undefined' ? __dirname : url.fileURLToPath(import.meta.url));
9
+ const nodeModulesPath = path.join(_dirname, '..', '..', 'node_modules');
10
+ // Cache loaded adapters
11
+ const adapterCache = new Map();
12
+ /**
13
+ * Load an adapter, installing it dynamically if needed
14
+ */ export default function loadAdapter(packageName, exportName, callback) {
15
+ const cacheKey = `${packageName}:${exportName !== null && exportName !== void 0 ? exportName : 'default'}`;
16
+ // Return cached adapter if available
17
+ if (adapterCache.has(cacheKey)) {
18
+ callback(null, adapterCache.get(cacheKey));
19
+ return;
20
+ }
21
+ // Try to require first (may already be installed)
22
+ try {
23
+ const mod = _require(packageName);
24
+ var _mod_default;
25
+ const Adapter = exportName ? mod[exportName] : (_mod_default = mod.default) !== null && _mod_default !== void 0 ? _mod_default : mod;
26
+ adapterCache.set(cacheKey, Adapter);
27
+ callback(null, Adapter);
28
+ return;
29
+ } catch {
30
+ // Not installed - dynamically install then load
31
+ installModule(packageName, nodeModulesPath, {}, (err)=>{
32
+ if (err) {
33
+ callback(err);
34
+ return;
35
+ }
36
+ try {
37
+ const mod = _require(packageName);
38
+ var _mod_default;
39
+ const Adapter = exportName ? mod[exportName] : (_mod_default = mod.default) !== null && _mod_default !== void 0 ? _mod_default : mod;
40
+ adapterCache.set(cacheKey, Adapter);
41
+ callback(null, Adapter);
42
+ } catch (loadErr) {
43
+ callback(loadErr);
44
+ }
45
+ });
46
+ }
47
+ }
48
+ /**
49
+ * Clear the adapter cache (useful for testing)
50
+ */ export function clearAdapterCache() {
51
+ adapterCache.clear();
52
+ }
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/Users/kevin/Dev/OpenSource/keyv/keyv-registry/src/loadAdapter.ts"],"sourcesContent":["import Module from 'node:module';\nimport path from 'node:path';\nimport url from 'node:url';\nimport installModule from 'install-module-linked';\nimport type { LoadAdapterCallback } from './types.ts';\n\n// Create require function for ESM compatibility\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// Determine node_modules path\nconst _dirname = path.dirname(typeof __dirname !== 'undefined' ? __dirname : url.fileURLToPath(import.meta.url));\nconst nodeModulesPath = path.join(_dirname, '..', '..', 'node_modules');\n\n// Cache loaded adapters\nconst adapterCache = new Map<string, unknown>();\n\n/**\n * Load an adapter, installing it dynamically if needed\n */\nexport default function loadAdapter(packageName: string, exportName: string | undefined, callback: LoadAdapterCallback): void {\n const cacheKey = `${packageName}:${exportName ?? 'default'}`;\n\n // Return cached adapter if available\n if (adapterCache.has(cacheKey)) {\n callback(null, adapterCache.get(cacheKey));\n return;\n }\n\n // Try to require first (may already be installed)\n try {\n const mod = _require(packageName);\n const Adapter = exportName ? mod[exportName] : (mod.default ?? mod);\n adapterCache.set(cacheKey, Adapter);\n callback(null, Adapter);\n return;\n } catch {\n // Not installed - dynamically install then load\n installModule(packageName, nodeModulesPath, {}, (err: Error | null) => {\n if (err) {\n callback(err);\n return;\n }\n try {\n const mod = _require(packageName);\n const Adapter = exportName ? mod[exportName] : (mod.default ?? mod);\n adapterCache.set(cacheKey, Adapter);\n callback(null, Adapter);\n } catch (loadErr) {\n callback(loadErr as Error);\n }\n });\n }\n}\n\n/**\n * Clear the adapter cache (useful for testing)\n */\nexport function clearAdapterCache(): void {\n adapterCache.clear();\n}\n"],"names":["Module","path","url","installModule","_require","require","createRequire","_dirname","dirname","__dirname","fileURLToPath","nodeModulesPath","join","adapterCache","Map","loadAdapter","packageName","exportName","callback","cacheKey","has","get","mod","Adapter","default","set","err","loadErr","clearAdapterCache","clear"],"mappings":"AAAA,OAAOA,YAAY,cAAc;AACjC,OAAOC,UAAU,YAAY;AAC7B,OAAOC,SAAS,WAAW;AAC3B,OAAOC,mBAAmB,wBAAwB;AAGlD,gDAAgD;AAChD,MAAMC,WAAW,OAAOC,YAAY,cAAcL,OAAOM,aAAa,CAAC,YAAYJ,GAAG,IAAIG;AAE1F,8BAA8B;AAC9B,MAAME,WAAWN,KAAKO,OAAO,CAAC,OAAOC,cAAc,cAAcA,YAAYP,IAAIQ,aAAa,CAAC,YAAYR,GAAG;AAC9G,MAAMS,kBAAkBV,KAAKW,IAAI,CAACL,UAAU,MAAM,MAAM;AAExD,wBAAwB;AACxB,MAAMM,eAAe,IAAIC;AAEzB;;CAEC,GACD,eAAe,SAASC,YAAYC,WAAmB,EAAEC,UAA8B,EAAEC,QAA6B;IACpH,MAAMC,WAAW,GAAGH,YAAY,CAAC,EAAEC,uBAAAA,wBAAAA,aAAc,WAAW;IAE5D,qCAAqC;IACrC,IAAIJ,aAAaO,GAAG,CAACD,WAAW;QAC9BD,SAAS,MAAML,aAAaQ,GAAG,CAACF;QAChC;IACF;IAEA,kDAAkD;IAClD,IAAI;QACF,MAAMG,MAAMlB,SAASY;YAC2BM;QAAhD,MAAMC,UAAUN,aAAaK,GAAG,CAACL,WAAW,GAAIK,CAAAA,eAAAA,IAAIE,OAAO,cAAXF,0BAAAA,eAAeA;QAC/DT,aAAaY,GAAG,CAACN,UAAUI;QAC3BL,SAAS,MAAMK;QACf;IACF,EAAE,OAAM;QACN,gDAAgD;QAChDpB,cAAca,aAAaL,iBAAiB,CAAC,GAAG,CAACe;YAC/C,IAAIA,KAAK;gBACPR,SAASQ;gBACT;YACF;YACA,IAAI;gBACF,MAAMJ,MAAMlB,SAASY;oBAC2BM;gBAAhD,MAAMC,UAAUN,aAAaK,GAAG,CAACL,WAAW,GAAIK,CAAAA,eAAAA,IAAIE,OAAO,cAAXF,0BAAAA,eAAeA;gBAC/DT,aAAaY,GAAG,CAACN,UAAUI;gBAC3BL,SAAS,MAAMK;YACjB,EAAE,OAAOI,SAAS;gBAChBT,SAASS;YACX;QACF;IACF;AACF;AAEA;;CAEC,GACD,OAAO,SAASC;IACdf,aAAagB,KAAK;AACpB"}
@@ -0,0 +1 @@
1
+ { "type": "module" }
@@ -0,0 +1,13 @@
1
+ import type { AdapterConfig } from './types.js';
2
+ /**
3
+ * Register or override a protocol adapter
4
+ */
5
+ export declare function registerAdapter(protocol: string, config: AdapterConfig): void;
6
+ /**
7
+ * Get the current registry (read-only copy)
8
+ */
9
+ export declare function getRegistry(): Readonly<Record<string, AdapterConfig>>;
10
+ /**
11
+ * Get adapter config for a protocol
12
+ */
13
+ export declare function getAdapterConfig(protocol: string): AdapterConfig | undefined;