k2hash 1.1.34 → 2.0.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/index.mjs ADDED
@@ -0,0 +1,154 @@
1
+ /*
2
+ * K2HASH
3
+ *
4
+ * Copyright 2015 Yahoo Japan Corporation.
5
+ *
6
+ * K2HASH is key-valuew store base libraries.
7
+ * K2HASH is made for the purpose of the construction of
8
+ * original KVS system and the offer of the library.
9
+ * The characteristic is this KVS library which Key can
10
+ * layer. And can support multi-processing and multi-thread,
11
+ * and is provided safely as available KVS.
12
+ *
13
+ * For the full copyright and license information, please view
14
+ * the license file that was distributed with this source code.
15
+ *
16
+ * AUTHOR: Takeshi Nakatani
17
+ * CREATE: Wed 19 Nov 2025
18
+ * REVISION:
19
+ */
20
+
21
+ //
22
+ // lazy-load the built CJS bundle and provide compatible exports
23
+ //
24
+ // [NOTE]
25
+ //
26
+ // This file intentionally does NOT require('./build/cjs/index.js') at top-level.
27
+ //
28
+
29
+ import { createRequire } from 'module';
30
+
31
+ const require = createRequire(import.meta.url);
32
+
33
+ //
34
+ // Load CJS
35
+ //
36
+ let _loaded_cjs = null;
37
+ function loadCjs()
38
+ {
39
+ if(null !== _loaded_cjs){
40
+ return _loaded_cjs;
41
+ }
42
+ _loaded_cjs = require('./build/cjs/index.js');
43
+ return _loaded_cjs;
44
+ }
45
+
46
+ //
47
+ // Factory that delegates to CJS impl on first use
48
+ //
49
+ function k2hashFactory(...args)
50
+ {
51
+ const cjs = loadCjs();
52
+ const impl = (typeof cjs === 'function') ? cjs : (cjs && cjs.default) ? cjs.default : cjs;
53
+ if(typeof impl === 'function'){
54
+ return impl(...args);
55
+ }
56
+ return impl;
57
+ }
58
+
59
+ //
60
+ // Provide callable/constructible proxies for named exports
61
+ //
62
+ // This mirrors createLazyProxy from src/index.ts but scoped to ESM file.
63
+ //
64
+ function createLazyExport(name)
65
+ {
66
+ let _cached = undefined;
67
+
68
+ function loadActual()
69
+ {
70
+ if(_cached !== undefined){
71
+ return _cached;
72
+ }
73
+ const _cjs = loadCjs();
74
+ const _actual = (_cjs && _cjs[name]) ? _cjs[name] : (_cjs && _cjs.default && _cjs.default[name]) ? _cjs.default[name] : undefined;
75
+ if (!_actual){
76
+ throw new Error("Native export " + JSON.stringify(name) + " is not available from ./build/cjs/index.js");
77
+ }
78
+ _cached = _actual;
79
+ return _cached;
80
+ }
81
+
82
+ const target = function(...args)
83
+ {
84
+ const _actual = loadActual();
85
+ return _actual.apply(this, args);
86
+ };
87
+
88
+ const handler = {
89
+ apply(_t, thisArg, args) {
90
+ const _actual = loadActual();
91
+ return _actual.apply(thisArg, args);
92
+ },
93
+ construct(_t, args, newTarget) {
94
+ const _actual = loadActual();
95
+ return Reflect.construct(_actual, args, newTarget);
96
+ },
97
+ get(_t, prop, receiver) {
98
+ const _actual = loadActual();
99
+ return Reflect.get(_actual, prop, receiver);
100
+ },
101
+ set(_t, prop, value, receiver) {
102
+ const _actual = loadActual();
103
+ return Reflect.set(_actual, prop, value, receiver);
104
+ },
105
+ has(_t, prop) {
106
+ const _actual = loadActual();
107
+ return prop in _actual;
108
+ },
109
+ ownKeys(_t) {
110
+ const _actual = loadActual();
111
+ return Reflect.ownKeys(_actual);
112
+ },
113
+ getOwnPropertyDescriptor(_t, prop) {
114
+ const _actual = loadActual();
115
+ return Object.getOwnPropertyDescriptor(_actual, prop) || undefined;
116
+ },
117
+ getPrototypeOf(_t) {
118
+ const _actual = loadActual();
119
+ return Object.getPrototypeOf(_actual);
120
+ },
121
+ setPrototypeOf(_t, proto) {
122
+ const _actual = loadActual();
123
+ return Object.setPrototypeOf(_actual, proto);
124
+ },
125
+ defineProperty(_t, prop, descriptor) {
126
+ const _actual = loadActual();
127
+ return Reflect.defineProperty(_actual, prop, descriptor);
128
+ },
129
+ deleteProperty(_t, prop) {
130
+ const _actual = loadActual();
131
+ return Reflect.deleteProperty(_actual, prop);
132
+ }
133
+ };
134
+
135
+ return new Proxy(target, handler);
136
+ }
137
+
138
+ //
139
+ // Export named lazy-callable proxies
140
+ //
141
+ export const K2hNode = createLazyExport('K2hNode');
142
+ export const K2hQueue = createLazyExport('K2hQueue');
143
+ export const K2hKeyQueue = createLazyExport('K2hKeyQueue');
144
+
145
+ export default k2hashFactory;
146
+
147
+ /*
148
+ * Local variables:
149
+ * tab-width: 4
150
+ * c-basic-offset: 4
151
+ * End:
152
+ * vim600: noexpandtab sw=4 ts=4 fdm=marker
153
+ * vim<600: noexpandtab sw=4 ts=4
154
+ */
package/package.json CHANGED
@@ -1,33 +1,77 @@
1
1
  {
2
2
  "name": "k2hash",
3
- "version": "1.1.34",
3
+ "version": "2.0.1",
4
4
  "description": "K2HASH addon library for Node.js",
5
5
  "os": "linux",
6
6
  "main": "index.js",
7
+ "module": "index.mjs",
8
+ "types": "types/index.d.ts",
7
9
  "directories": {
8
- "test": "test"
10
+ "test": "tests"
9
11
  },
12
+ "files": [
13
+ "index.js",
14
+ "index.mjs",
15
+ "binding.gyp",
16
+ "types",
17
+ "src",
18
+ "build/cjs/index.js",
19
+ "build/esm/index.js",
20
+ "buildutils/make_node_prebuild_variables.sh",
21
+ "buildutils/node_prebuild_install.sh",
22
+ "buildutils/node_prebuild.sh",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
10
26
  "dependencies": {
11
27
  "bindings": "^1.5.0",
12
- "nan": "^2.22.0"
28
+ "node-addon-api": "^8.5.0",
29
+ "prebuild-install": "^7.1.3"
13
30
  },
14
31
  "devDependencies": {
15
- "chai": "^4.5.0",
16
- "mocha": "^11.1.0"
32
+ "@rollup/plugin-commonjs": "^29.0.0",
33
+ "@rollup/plugin-node-resolve": "^16.0.3",
34
+ "@rollup/plugin-replace": "^6.0.3",
35
+ "@rollup/plugin-terser": "^0.4.4",
36
+ "@types/chai": "^5.2.3",
37
+ "@types/mocha": "^10.0.10",
38
+ "@types/node": "^25.0.3",
39
+ "chai": "^6.2.2",
40
+ "mocha": "^11.7.5",
41
+ "node-gyp": "^12.1.0",
42
+ "prebuild": "^13.0.1",
43
+ "rollup": "^4.54.0",
44
+ "typescript": "^5.9.3",
45
+ "ts-node": "^10.9.2"
17
46
  },
18
47
  "scripts": {
19
- "build": "npm run build:before && npm run build:configure && npm run build:rebuild && npm run build:linkdir && npm run build:after",
20
- "build:before": "echo \"Build - Start\"",
21
- "build:configure": "if [ -f src/binding.gyp ]; then cd src; fi && node-gyp configure --verbose --release --target_arch=x64 --coverage=true",
22
- "build:rebuild": "if [ -f src/binding.gyp ]; then cd src; fi && node-gyp rebuild --verbose --release --target_arch=x64 --coverage=true",
23
- "build:linkdir": "if [ ! -f build -a ! -s build ]; then ln -s src/build .; fi",
24
- "build:after": "echo \"Build - Succeed\"",
25
- "install": "npm run build",
26
- "test": "npm run test:all",
27
- "test:all": "echo \"Test - All\" && tests/test.sh && echo \"Finished\"",
28
- "test:k2hash": "echo \"Test - k2hash\" && tests/test.sh k2hash && echo \"Finished\"",
29
- "test:k2hqueue": "echo \"Test - k2hqueue\" && tests/test.sh k2hqueue && echo \"Finished\"",
30
- "test:k2hkeyqueue": "echo \"Test - k2hkeyqueue\" && tests/test.sh k2hkeyqueue && echo \"Finished\""
48
+ "help": "echo 'command list:\n npm run install\n npm run install:onlypackages\n npm run build\n npm run build:ts\n npm run build:ts:cjs\n npm run build:ts:esm\n npm run build:ts:tests:cjs\n npm run build:types\n npm run build:checktypes\n npm run build:configure\n npm run build:rebuild\n npm run build:prebuild\n npm run build:prebuild:pure\n npm run build:bundle:esm\n npm run prepublishOnly\n npm run lint\n npm run test\n npm run test:ci\n npm run test:all\n npm run test:smoke\n npm run test:smoke:cjs\n npm run test:smoke:esm\n npm run test:smoke:ts\n npm run test:k2hash\n npm run test:k2hqueue\n npm run test:k2hkeyqueue\n'",
49
+ "install": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Install' && ./buildutils/node_prebuild_install.sh || (echo '[INFO] No binaries found, so building from source\n' && if [ -d build/cjs ] && [ -d build/esm ]; then npm run build:rebuild; else npm run build; fi) && echo '-> [DONE] Install\n'",
50
+ "install:onlypackages": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Install:onlypackages' && npm install --ignore-scripts && echo '-> [DONE] Install:onlypackages\n'",
51
+ "build": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build' && npm run build:checktypes && npm run build:configure && npm run build:rebuild && npm run build:ts && echo '-> [DONE] Build\n'",
52
+ "build:ts": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:ts' && npm run build:ts:cjs && npm run build:ts:esm && echo '-> [DONE] Build:ts\n'",
53
+ "build:ts:cjs": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:ts:cjs' && tsc -p tsconfig.cjs.json && echo '-> [DONE] Build:ts:cjs\n'",
54
+ "build:ts:esm": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:ts:esm' && tsc -p tsconfig.esm.json && echo '-> [DONE] Build:ts:esm\n'",
55
+ "build:ts:tests:cjs": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:ts:tests:cjs' && tsc -p tsconfig.tests.json && echo '-> [DONE] Build:ts:tests:cjs\n'",
56
+ "build:types": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:types' && echo '[NOTICE] We already provide index.d.ts manually, so NOT need to build types.(if run, index.d.ts is generated in \"types-generated\", but NOT use it.)' && tsc -p tsconfig.types.json && echo '-> [DONE] Build:types\n'",
57
+ "build:checktypes": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:checktypes' && tsc --noEmit -p tsconfig.types.json && echo '-> [DONE] Build:checktypes\n'",
58
+ "build:configure": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:configure' && if [ -f binding.gyp ]; then (node-gyp configure --verbose --release --target_arch=$(uname -m | sed 's/x86_64/x64/')); else echo '[WARNING] No binding.gyp, skipping configure'; fi && echo '-> [DONE] Build:configure\n'",
59
+ "build:rebuild": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:rebuild' && if [ -f binding.gyp ]; then (node-gyp rebuild --verbose --release --target_arch=$(uname -m | sed 's/x86_64/x64/')); else echo '[WARNING] No binding.gyp, skipping rebuild'; fi && echo '-> [DONE] Build:rebuild\n'",
60
+ "build:prebuild": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:prebuild' && ./buildutils/node_prebuild.sh && echo '-> [DONE] Build:prebuild\n'",
61
+ "build:prebuild:pure": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:prebuild:pure (for only prebuild confirmation)' && GYP_DEFINES=openssl_fips= prebuild --strip --napi --path prebuilds && echo '-> [DONE] Build:prebuild:pure\n'",
62
+ "build:bundle:esm": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Build:bundle:esm' && echo '[NOTICE] Currently, rollup is NOT necessary, Does NOT use those outputed files, so do NOT run before packaging.' && rollup -c rollup.config.mjs && echo '-> [DONE] Build:bundle:esm\n'",
63
+ "prepublishOnly": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] PrepublishOnly' && echo '[INFO] Currently, no implementation. If there are signatures and final inspections, etc., the processing will be implemented here.' && echo '-> [DONE] PrepublishOnly\n'",
64
+ "lint": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Lint' && echo '[INFO] No linter configured' && echo '-> [DONE] Lint\n'",
65
+ "test": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test' && if [ ! -f build/cjs/index.js ]; then npm run build || exit 1; fi && npm run test:all && echo '-> [DONE] Test\n'",
66
+ "test:ci": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:ci' && if [ ! -f build/cjs/index.js ]; then echo '[ERROR] Not found build/cjs/index.js (build missing)'; exit 1; fi && npm run test:all && echo '-> [DONE] Test:ci\n'",
67
+ "test:all": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:all' && npm run test:smoke && tests/test.sh && echo '-> [DONE] Test:all\n'",
68
+ "test:smoke": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:smoke' && npm run test:smoke:cjs && npm run test:smoke:esm && npm run test:smoke:ts && echo '-> [DONE] Test:smoke\n'",
69
+ "test:smoke:cjs": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:smoke:cjs' && node tests/smoke_test_cjs.js && echo '-> [DONE] Test:smoke:cjs\n'",
70
+ "test:smoke:esm": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:smoke:esm' && node tests/smoke_test_esm.mjs && echo '-> [DONE] Test:smoke:esm\n'",
71
+ "test:smoke:ts": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:smoke:ts' && tsc --noEmit tests/smoke_test_ts.ts && echo '-> [DONE] Test:smoke:ts\n'",
72
+ "test:k2hash": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:k2hash' && tests/test.sh k2hash && echo '-> [DONE] Test:k2hash\n'",
73
+ "test:k2hqueue": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:k2hqueue' && tests/test.sh k2hqueue && echo '-> [DONE] Test:k2hqueue\n'",
74
+ "test:k2hkeyqueue": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:k2hkeyqueue]' && tests/test.sh k2hkeyqueue && echo '-> [DONE] Test:k2hkeyqueue\n'"
31
75
  },
32
76
  "repository": {
33
77
  "type": "git",
@@ -44,15 +88,27 @@
44
88
  "transaction",
45
89
  "database",
46
90
  "queue",
47
- "in-memory"
91
+ "in-memory",
92
+ "n-api",
93
+ "native",
94
+ "addon"
48
95
  ],
49
96
  "bugs": {
50
97
  "url": "http://github.com/yahoojapan/k2hash_nodejs/issues",
51
- "email": "antpickax-support@mail.yahoo.co.jp"
98
+ "email": "ml-antpickax-support@lycorp.co.jp"
52
99
  },
53
100
  "author": "Takeshi Nakatani <ggtakec@gmail.com> (https://github.com/ggtakec)",
54
101
  "contributors": [
55
102
  "Hirotaka Wakabayashi <hiwakaba@lycorp.co.jp> (https://github.com/hiwakaba)"
56
103
  ],
57
- "license": "MIT"
104
+ "license": "MIT",
105
+ "exports": {
106
+ ".": {
107
+ "import": "./index.mjs",
108
+ "require": "./index.js"
109
+ }
110
+ },
111
+ "engines": {
112
+ "node": ">=14"
113
+ }
58
114
  }
package/src/index.ts ADDED
@@ -0,0 +1,378 @@
1
+ /*
2
+ * K2HASH
3
+ *
4
+ * Copyright 2015 Yahoo Japan Corporation.
5
+ *
6
+ * K2HASH is key-valuew store base libraries.
7
+ * K2HASH is made for the purpose of the construction of
8
+ * original KVS system and the offer of the library.
9
+ * The characteristic is this KVS library which Key can
10
+ * layer. And can support multi-processing and multi-thread,
11
+ * and is provided safely as available KVS.
12
+ *
13
+ * For the full copyright and license information, please view
14
+ * the license file that was distributed with this source code.
15
+ *
16
+ * AUTHOR: Takeshi Nakatani
17
+ * CREATE: Wed 19 Nov 2025
18
+ * REVISION:
19
+ */
20
+
21
+ //---------------------------------------------------------
22
+ // High-level TypeScript wrapper for the native k2hash addon
23
+ //
24
+ // [NOTE]
25
+ // Implementation intentionally uses `any` for the native
26
+ // binding because detailed types are provided in the
27
+ // hand-written types/index.d.ts which will be included in
28
+ // the package.
29
+ //
30
+ // Lazy-loading, compatibility-preserving implementation for
31
+ // the k2hash package.
32
+ // - ensureNative() loads the native binding on first use.
33
+ // - copyPropsToFactory preserves callable default + named
34
+ // properties.
35
+ // - createLazyProxy provides callable/constructible named
36
+ // exports.
37
+ //
38
+ //---------------------------------------------------------
39
+ // How to call this module supported(index.js/index.mjs)
40
+ //---------------------------------------------------------
41
+ // - CommonJS
42
+ // const k2hash = require('k2hash');
43
+ // const k2h = k2hash();
44
+ //
45
+ // - CommonJS(reference constuctor directly)
46
+ // const k2hash = require('k2hash');
47
+ // const K2hNode = k2hash.K2hNode;
48
+ // const k2h = k2hash();
49
+ //
50
+ // - TypeScript(1)
51
+ // import k2hash from 'k2hash';
52
+ // const k2h = k2hash();
53
+ //
54
+ // - TypeScript(2)
55
+ // import k2hash from 'k2hash';
56
+ // const k2h = new k2hash();
57
+ //
58
+ // - TypeScript(3: compatible calling)
59
+ // import k2hash = require('k2hash');
60
+ // const k2h = k2hash();
61
+ //
62
+ // - TypeScript(reference constuctor directly)
63
+ // import k2hash from 'k2hash';
64
+ // const K2hNode = k2hash.K2hNode;
65
+ // const k2h = k2hash();
66
+ //
67
+ // - ESM(pure ES module files: guaranteed version)
68
+ // import { createRequire } from 'module';
69
+ // const require = createRequire(import.meta.url);
70
+ // const k2hash = require('k2hash');
71
+ // const k2h = k2hash();
72
+ //---------------------------------------------------------
73
+
74
+ type AnyFn = (...args: any[]) => any;
75
+
76
+ let _native: any = undefined;
77
+ let _nativeLoaded = false;
78
+
79
+ // [NOTE]
80
+ // Copy properties from native onto the factory(mirrors original runtime
81
+ // normalization)
82
+ // We try to preserve descriptors when possible.
83
+ //
84
+ function copyPropsToFactory(k2hashFactory: AnyFn, factory_native: any)
85
+ {
86
+ if(!factory_native || (typeof factory_native !== 'object' && typeof factory_native !== 'function')){
87
+ return;
88
+ }
89
+
90
+ try{
91
+ Object.getOwnPropertyNames(factory_native).forEach((name) => {
92
+ if(name === 'prototype'){
93
+ return;
94
+ }
95
+ try{
96
+ const desc = Object.getOwnPropertyDescriptor(factory_native, name);
97
+ if(desc){
98
+ Object.defineProperty(k2hashFactory, name, desc);
99
+ }
100
+ }catch{
101
+ try{
102
+ (k2hashFactory as any)[name] = factory_native[name];
103
+ }catch{
104
+ // ignore
105
+ }
106
+ }
107
+ });
108
+
109
+ Object.getOwnPropertySymbols(factory_native).forEach((sym) => {
110
+ try{
111
+ const desc = Object.getOwnPropertyDescriptor(factory_native, sym as any);
112
+ if(desc){
113
+ Object.defineProperty(k2hashFactory, sym as any, desc);
114
+ }
115
+ }catch{
116
+ try{
117
+ (k2hashFactory as any)[sym as any] = factory_native[sym as any];
118
+ }catch{
119
+ // ignore
120
+ }
121
+ }
122
+ });
123
+ }catch{
124
+ // ignore odd cases(native undefined or primitive)
125
+ }
126
+
127
+ try{
128
+ if(factory_native && factory_native.K2hNode){
129
+ (k2hashFactory as any).K2hNode = factory_native.K2hNode;
130
+ }
131
+ if(factory_native && factory_native.K2hQueue){
132
+ (k2hashFactory as any).K2hQueue = factory_native.K2hQueue;
133
+ }
134
+ if(factory_native && factory_native.K2hKeyQueue){
135
+ (k2hashFactory as any).K2hKeyQueue = factory_native.K2hKeyQueue;
136
+ }
137
+ }catch{
138
+ // ignore
139
+ }
140
+ }
141
+
142
+ // [NOTE]
143
+ // Load native on first need. Also call copyPropsToFactory once after
144
+ // loading.
145
+ // require('bindings') may throw if native not present at build/test time
146
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
147
+ //
148
+ function ensureNative(): any
149
+ {
150
+ if(_nativeLoaded){
151
+ return _native;
152
+ }
153
+ _nativeLoaded = true;
154
+
155
+ try{
156
+ const bindings = require('bindings');
157
+ _native = bindings('k2hash');
158
+ }catch{
159
+ _native = undefined;
160
+ }
161
+
162
+ // [NOTE]
163
+ // If we successfully loaded native, copy properties onto the factory so
164
+ // default export retains the same shape as before (callable + named
165
+ // properties).
166
+ //
167
+ if(_native){
168
+ try{
169
+ // [NOTE]
170
+ // k2hashFactory is hoisted(function declaration), safe to
171
+ // reference here
172
+ copyPropsToFactory(k2hashFactory as AnyFn, _native);
173
+ }catch{
174
+ // swallow copy errors to preserve robustness
175
+ }
176
+ }
177
+ return _native;
178
+ }
179
+
180
+ // [NOTE]
181
+ // Default factory that mirrors previous behavior
182
+ //
183
+ function k2hashFactory(...args: any[]): any
184
+ {
185
+ const _factory_native = ensureNative();
186
+ if(typeof _factory_native === 'function'){
187
+ try{
188
+ const retobj = (_factory_native as AnyFn).apply(null, args);
189
+ if(retobj !== undefined){
190
+ return retobj;
191
+ }
192
+ }catch{
193
+ // fallthrough to constructor fallback
194
+ }
195
+ }
196
+
197
+ if(_factory_native && typeof _factory_native.K2hNode === 'function'){
198
+ try{
199
+ return new _factory_native.K2hNode(...args);
200
+ }catch{
201
+ // fallthrough
202
+ }
203
+ }
204
+
205
+ // fallback: return native itself (could be an object with properties)
206
+ return _factory_native;
207
+ }
208
+
209
+ // [NOTE]
210
+ // Returns a callable & constructible Proxy that forwards to native export
211
+ //
212
+ function createLazyProxy(name: string): AnyFn
213
+ {
214
+ let _cached: any = undefined;
215
+
216
+ function loadActual()
217
+ {
218
+ if(_cached !== undefined){
219
+ return _cached;
220
+ }
221
+ const _lazy_native = ensureNative();
222
+ const _actual = _lazy_native && _lazy_native[name] ? _lazy_native[name] : undefined;
223
+ if(!_actual){
224
+ throw new Error("Native export " + JSON.stringify(name) + " is not available");
225
+ }
226
+ _cached = _actual;
227
+ return _cached;
228
+ }
229
+
230
+ const target = function (this: any, ...args: any[])
231
+ {
232
+ const _actual = loadActual();
233
+ return _actual.apply(this, args);
234
+ };
235
+
236
+ const handler: ProxyHandler<any> = {
237
+ apply(_t, thisArg, args) {
238
+ const _actual = loadActual();
239
+ return _actual.apply(thisArg, args);
240
+ },
241
+ construct(_t, args, newTarget) {
242
+ const _actual = loadActual();
243
+ return Reflect.construct(_actual, args, newTarget);
244
+ },
245
+ get(_t, prop, receiver) {
246
+ const _actual = loadActual();
247
+ return Reflect.get(_actual, prop, receiver);
248
+ },
249
+ set(_t, prop, value, receiver) {
250
+ const _actual = loadActual();
251
+ return Reflect.set(_actual, prop, value, receiver);
252
+ },
253
+ has(_t, prop) {
254
+ const _actual = loadActual();
255
+ return prop in _actual;
256
+ },
257
+ ownKeys(_t) {
258
+ const _actual = loadActual();
259
+ return Reflect.ownKeys(_actual);
260
+ },
261
+ getOwnPropertyDescriptor(_t, prop) {
262
+ const _actual = loadActual();
263
+ return Object.getOwnPropertyDescriptor(_actual, prop) || undefined;
264
+ },
265
+ getPrototypeOf(_t) {
266
+ const _actual = loadActual();
267
+ return Object.getPrototypeOf(_actual);
268
+ },
269
+ setPrototypeOf(_t, proto) {
270
+ const _actual = loadActual();
271
+ return Object.setPrototypeOf(_actual, proto);
272
+ },
273
+ defineProperty(_t, prop, descriptor) {
274
+ const _actual = loadActual();
275
+ return Reflect.defineProperty(_actual, prop, descriptor);
276
+ },
277
+ deleteProperty(_t, prop) {
278
+ const _actual = loadActual();
279
+ return Reflect.deleteProperty(_actual, prop);
280
+ }
281
+ };
282
+
283
+ return new Proxy(target as AnyFn, handler) as AnyFn;
284
+ }
285
+
286
+ //
287
+ // Export named proxies to keep compatibility with existing consumers
288
+ //
289
+ // Named convenience exports (runtime values).
290
+ // Types are provided by types/index.d.ts.
291
+ //
292
+ export const K2hNode = createLazyProxy('K2hNode');
293
+ export const K2hQueue = createLazyProxy('K2hQueue');
294
+ export const K2hKeyQueue = createLazyProxy('K2hKeyQueue');
295
+
296
+ export default k2hashFactory;
297
+
298
+ //
299
+ // Compatibility normalization for CommonJS output
300
+ //
301
+ // [NOTE]
302
+ // When TypeScript/packager emits CommonJS, it can produce "module.exports = { default: ..., ... }"
303
+ // which causes ESM consumers to get an object whose "default" is the callable factory.
304
+ // Normalize module.exports so that "require(...)" yields a callable function while
305
+ // preserving named properties.
306
+ // This runs only in CommonJS environments and is intentionally defensive.
307
+ //
308
+ declare const module: any;
309
+
310
+ try{
311
+ if(typeof module !== 'undefined' && module && module.exports){
312
+ const own_module_export = module.exports as any;
313
+
314
+ //
315
+ // If module.exports is exactly { default: fn }, replace module.exports with fn.
316
+ //
317
+ if( own_module_export &&
318
+ typeof own_module_export === 'object' &&
319
+ Object.prototype.hasOwnProperty.call(own_module_export, 'default') &&
320
+ typeof own_module_export.default === 'function' &&
321
+ Object.keys(own_module_export).length === 1 )
322
+ {
323
+ module.exports = own_module_export.default;
324
+
325
+ }else if(own_module_export && typeof own_module_export === 'object' && typeof own_module_export.default === 'function'){
326
+ //
327
+ // If default is a function but other named exports exist,
328
+ // prefer a top-level callable while preserving named props.
329
+ //
330
+ try{
331
+ const defaultFn = own_module_export.default as Function;
332
+
333
+ // If top-level is not already callable, make it so.
334
+ if(typeof own_module_export !== 'function'){
335
+ // create a callable wrapper that forwards to defaultFn
336
+ const callable = function(this: any, ...args: any[]){
337
+ return defaultFn.apply(this, args);
338
+ };
339
+
340
+ // copy named properties from original exports except 'default'
341
+ Object.keys(own_module_export).forEach((key) => {
342
+ if(key === 'default'){
343
+ return;
344
+ }
345
+ try{
346
+ (callable as any)[key] = own_module_export[key];
347
+ }catch{
348
+ // ignore
349
+ }
350
+ });
351
+
352
+ // preserve reference to original module
353
+ try{
354
+ (callable as any).__orig_module = own_module_export;
355
+ }catch{
356
+ // ignore
357
+ }
358
+
359
+ // replace module.exports with callable that also carries named props
360
+ module.exports = callable;
361
+ }
362
+ }catch{
363
+ // swallow normalization errors - not critical
364
+ }
365
+ }
366
+ }
367
+ }catch{
368
+ // ignore
369
+ }
370
+
371
+ /*
372
+ * Local variables:
373
+ * tab-width: 4
374
+ * c-basic-offset: 4
375
+ * End:
376
+ * vim600: noexpandtab sw=4 ts=4 fdm=marker
377
+ * vim<600: noexpandtab sw=4 ts=4
378
+ */