k2hash 1.1.34 → 2.0.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/binding.gyp +106 -0
- package/build/cjs/index.js +296 -0
- package/build/esm/index.js +293 -0
- package/buildutils/make_node_prebuild_variables.sh +359 -0
- package/buildutils/node_prebuild.sh +371 -0
- package/buildutils/node_prebuild_install.sh +307 -0
- package/index.js +4 -1
- package/index.mjs +154 -0
- package/package.json +76 -20
- package/src/index.ts +378 -0
- package/src/k2h_cbs.cc +27 -41
- package/src/k2h_cbs.h +17 -13
- package/src/k2h_common.h +1 -1
- package/src/k2h_keyqueue.cc +513 -339
- package/src/k2h_keyqueue.h +38 -30
- package/src/k2h_keyqueue_async.h +222 -184
- package/src/k2h_queue.cc +483 -304
- package/src/k2h_queue.h +38 -30
- package/src/k2h_queue_async.h +218 -173
- package/src/k2h_shm.cc +1963 -1221
- package/src/k2h_shm.h +109 -104
- package/src/k2h_shm_async.h +722 -560
- package/src/k2hash.cc +22 -8
- package/src/k2hkeyqueue.cc +21 -8
- package/src/k2hqueue.cc +21 -8
- package/types/index.d.ts +570 -0
- package/ChangeLog +0 -137
- package/src/binding.gyp +0 -146
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": "
|
|
3
|
+
"version": "2.0.0",
|
|
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": "
|
|
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
|
-
"
|
|
28
|
+
"node-addon-api": "^8.5.0",
|
|
29
|
+
"prebuild-install": "^7.1.3"
|
|
13
30
|
},
|
|
14
31
|
"devDependencies": {
|
|
15
|
-
"
|
|
16
|
-
"
|
|
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
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"build
|
|
23
|
-
"build:
|
|
24
|
-
"build:
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
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@
|
|
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
|
+
*/
|