k2hdkc 1.0.12 → 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 +40 -0
- package/build/cjs/index.js +285 -0
- package/build/esm/index.js +282 -0
- package/buildutils/make_node_prebuild_variables.sh +361 -0
- package/buildutils/node_prebuild.sh +373 -0
- package/buildutils/node_prebuild_install.sh +309 -0
- package/index.js +4 -1
- package/index.mjs +149 -0
- package/package.json +74 -18
- package/src/index.ts +367 -0
- package/src/k2hdkc.cc +21 -8
- package/src/k2hdkc_cbs.cc +27 -41
- package/src/k2hdkc_cbs.h +15 -11
- package/src/k2hdkc_common.h +3 -3
- package/src/k2hdkc_node.cc +1889 -1655
- package/src/k2hdkc_node.h +69 -63
- package/src/k2hdkc_node_async.h +1020 -932
- package/types/index.d.ts +1258 -0
- package/ChangeLog +0 -132
- package/src/binding.gyp +0 -69
package/index.mjs
ADDED
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* K2HDKC
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2017 Yahoo Japan Corporation.
|
|
5
|
+
*
|
|
6
|
+
* K2HDKC is k2hash based distributed KVS cluster.
|
|
7
|
+
* K2HDKC uses K2HASH, CHMPX, FULLOCK libraries. K2HDKC supports
|
|
8
|
+
* distributed KVS cluster server program and client libraries.
|
|
9
|
+
*
|
|
10
|
+
* For the full copyright and license information, please view
|
|
11
|
+
* the license file that was distributed with this source code.
|
|
12
|
+
*
|
|
13
|
+
* AUTHOR: Takeshi Nakatani
|
|
14
|
+
* CREATE: Thu 15 Jan 2026
|
|
15
|
+
* REVISION:
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
//
|
|
19
|
+
// lazy-load the built CJS bundle and provide compatible exports
|
|
20
|
+
//
|
|
21
|
+
// [NOTE]
|
|
22
|
+
//
|
|
23
|
+
// This file intentionally does NOT require('./build/cjs/index.js') at top-level.
|
|
24
|
+
//
|
|
25
|
+
|
|
26
|
+
import { createRequire } from 'module';
|
|
27
|
+
|
|
28
|
+
const require = createRequire(import.meta.url);
|
|
29
|
+
|
|
30
|
+
//
|
|
31
|
+
// Load CJS
|
|
32
|
+
//
|
|
33
|
+
let _loaded_cjs = null;
|
|
34
|
+
function loadCjs()
|
|
35
|
+
{
|
|
36
|
+
if(null !== _loaded_cjs){
|
|
37
|
+
return _loaded_cjs;
|
|
38
|
+
}
|
|
39
|
+
_loaded_cjs = require('./build/cjs/index.js');
|
|
40
|
+
return _loaded_cjs;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
//
|
|
44
|
+
// Factory that delegates to CJS impl on first use
|
|
45
|
+
//
|
|
46
|
+
function k2hdkcFactory(...args)
|
|
47
|
+
{
|
|
48
|
+
const cjs = loadCjs();
|
|
49
|
+
const impl = (typeof cjs === 'function') ? cjs : (cjs && cjs.default) ? cjs.default : cjs;
|
|
50
|
+
if(typeof impl === 'function'){
|
|
51
|
+
return impl(...args);
|
|
52
|
+
}
|
|
53
|
+
return impl;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
//
|
|
57
|
+
// Provide callable/constructible proxies for named exports
|
|
58
|
+
//
|
|
59
|
+
// This mirrors createLazyProxy from src/index.ts but scoped to ESM file.
|
|
60
|
+
//
|
|
61
|
+
function createLazyExport(name)
|
|
62
|
+
{
|
|
63
|
+
let _cached = undefined;
|
|
64
|
+
|
|
65
|
+
function loadActual()
|
|
66
|
+
{
|
|
67
|
+
if(_cached !== undefined){
|
|
68
|
+
return _cached;
|
|
69
|
+
}
|
|
70
|
+
const _cjs = loadCjs();
|
|
71
|
+
const _actual = (_cjs && _cjs[name]) ? _cjs[name] : (_cjs && _cjs.default && _cjs.default[name]) ? _cjs.default[name] : undefined;
|
|
72
|
+
if (!_actual){
|
|
73
|
+
throw new Error("Native export " + JSON.stringify(name) + " is not available from ./build/cjs/index.js");
|
|
74
|
+
}
|
|
75
|
+
_cached = _actual;
|
|
76
|
+
return _cached;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const target = function(...args)
|
|
80
|
+
{
|
|
81
|
+
const _actual = loadActual();
|
|
82
|
+
return _actual.apply(this, args);
|
|
83
|
+
};
|
|
84
|
+
|
|
85
|
+
const handler = {
|
|
86
|
+
apply(_t, thisArg, args) {
|
|
87
|
+
const _actual = loadActual();
|
|
88
|
+
return _actual.apply(thisArg, args);
|
|
89
|
+
},
|
|
90
|
+
construct(_t, args, newTarget) {
|
|
91
|
+
const _actual = loadActual();
|
|
92
|
+
return Reflect.construct(_actual, args, newTarget);
|
|
93
|
+
},
|
|
94
|
+
get(_t, prop, receiver) {
|
|
95
|
+
const _actual = loadActual();
|
|
96
|
+
return Reflect.get(_actual, prop, receiver);
|
|
97
|
+
},
|
|
98
|
+
set(_t, prop, value, receiver) {
|
|
99
|
+
const _actual = loadActual();
|
|
100
|
+
return Reflect.set(_actual, prop, value, receiver);
|
|
101
|
+
},
|
|
102
|
+
has(_t, prop) {
|
|
103
|
+
const _actual = loadActual();
|
|
104
|
+
return prop in _actual;
|
|
105
|
+
},
|
|
106
|
+
ownKeys(_t) {
|
|
107
|
+
const _actual = loadActual();
|
|
108
|
+
return Reflect.ownKeys(_actual);
|
|
109
|
+
},
|
|
110
|
+
getOwnPropertyDescriptor(_t, prop) {
|
|
111
|
+
const _actual = loadActual();
|
|
112
|
+
return Object.getOwnPropertyDescriptor(_actual, prop) || undefined;
|
|
113
|
+
},
|
|
114
|
+
getPrototypeOf(_t) {
|
|
115
|
+
const _actual = loadActual();
|
|
116
|
+
return Object.getPrototypeOf(_actual);
|
|
117
|
+
},
|
|
118
|
+
setPrototypeOf(_t, proto) {
|
|
119
|
+
const _actual = loadActual();
|
|
120
|
+
return Object.setPrototypeOf(_actual, proto);
|
|
121
|
+
},
|
|
122
|
+
defineProperty(_t, prop, descriptor) {
|
|
123
|
+
const _actual = loadActual();
|
|
124
|
+
return Reflect.defineProperty(_actual, prop, descriptor);
|
|
125
|
+
},
|
|
126
|
+
deleteProperty(_t, prop) {
|
|
127
|
+
const _actual = loadActual();
|
|
128
|
+
return Reflect.deleteProperty(_actual, prop);
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
return new Proxy(target, handler);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
//
|
|
136
|
+
// Export named lazy-callable proxies
|
|
137
|
+
//
|
|
138
|
+
export const K2hdkcNode = createLazyExport('K2hdkcNode');
|
|
139
|
+
|
|
140
|
+
export default k2hdkcFactory;
|
|
141
|
+
|
|
142
|
+
/*
|
|
143
|
+
* Local variables:
|
|
144
|
+
* tab-width: 4
|
|
145
|
+
* c-basic-offset: 4
|
|
146
|
+
* End:
|
|
147
|
+
* vim600: noexpandtab sw=4 ts=4 fdm=marker
|
|
148
|
+
* vim<600: noexpandtab sw=4 ts=4
|
|
149
|
+
*/
|
package/package.json
CHANGED
|
@@ -1,31 +1,75 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "k2hdkc",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "K2HDKC 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.8",
|
|
39
|
+
"chai": "^6.2.2",
|
|
40
|
+
"mocha": "^11.7.5",
|
|
41
|
+
"node-gyp": "^12.1.0",
|
|
42
|
+
"prebuild": "^13.0.1",
|
|
43
|
+
"rollup": "^4.55.1",
|
|
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
|
-
"
|
|
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:k2hdkc\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 && npm run test:k2hdkc && 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:k2hdkc": "export NPM_CONFIG_LOGLEVEL=silent && echo '[START] Test:k2hdkc' && tests/test.sh k2hdkc && echo '-> [DONE] Test:k2hdkc\n'"
|
|
29
73
|
},
|
|
30
74
|
"repository": {
|
|
31
75
|
"type": "git",
|
|
@@ -43,15 +87,27 @@
|
|
|
43
87
|
"transaction",
|
|
44
88
|
"database",
|
|
45
89
|
"queue",
|
|
46
|
-
"in-memory"
|
|
90
|
+
"in-memory",
|
|
91
|
+
"n-api",
|
|
92
|
+
"native",
|
|
93
|
+
"addon"
|
|
47
94
|
],
|
|
48
95
|
"bugs": {
|
|
49
96
|
"url": "http://github.com/yahoojapan/k2hdkc_nodejs/issues",
|
|
50
|
-
"email": "antpickax-support@
|
|
97
|
+
"email": "ml-antpickax-support@lycorp.co.jp"
|
|
51
98
|
},
|
|
52
99
|
"author": "Takeshi Nakatani <ggtakec@gmail.com> (https://github.com/ggtakec)",
|
|
53
100
|
"contributors": [
|
|
54
101
|
"Hirotaka Wakabayashi <hiwakaba@lycorp.co.jp> (https://github.com/hiwakaba)"
|
|
55
102
|
],
|
|
56
|
-
"license": "MIT"
|
|
103
|
+
"license": "MIT",
|
|
104
|
+
"exports": {
|
|
105
|
+
".": {
|
|
106
|
+
"import": "./index.mjs",
|
|
107
|
+
"require": "./index.js"
|
|
108
|
+
}
|
|
109
|
+
},
|
|
110
|
+
"engines": {
|
|
111
|
+
"node": ">=14"
|
|
112
|
+
}
|
|
57
113
|
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* K2HDKC
|
|
3
|
+
*
|
|
4
|
+
* Copyright 2017 Yahoo Japan Corporation.
|
|
5
|
+
*
|
|
6
|
+
* K2HDKC is k2hash based distributed KVS cluster.
|
|
7
|
+
* K2HDKC uses K2HASH, CHMPX, FULLOCK libraries. K2HDKC supports
|
|
8
|
+
* distributed KVS cluster server program and client libraries.
|
|
9
|
+
*
|
|
10
|
+
* For the full copyright and license information, please view
|
|
11
|
+
* the license file that was distributed with this source code.
|
|
12
|
+
*
|
|
13
|
+
* AUTHOR: Takeshi Nakatani
|
|
14
|
+
* CREATE: Fri 9 Nov 2018
|
|
15
|
+
* REVISION:
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
//---------------------------------------------------------
|
|
19
|
+
// High-level TypeScript wrapper for the native k2hdkc addon
|
|
20
|
+
//
|
|
21
|
+
// [NOTE]
|
|
22
|
+
// Implementation intentionally uses `any` for the native
|
|
23
|
+
// binding because detailed types are provided in the
|
|
24
|
+
// hand-written types/index.d.ts which will be included in
|
|
25
|
+
// the package.
|
|
26
|
+
//
|
|
27
|
+
// Lazy-loading, compatibility-preserving implementation for
|
|
28
|
+
// the k2hdkc package.
|
|
29
|
+
// - ensureNative() loads the native binding on first use.
|
|
30
|
+
// - copyPropsToFactory preserves callable default + named
|
|
31
|
+
// properties.
|
|
32
|
+
// - createLazyProxy provides callable/constructible named
|
|
33
|
+
// exports.
|
|
34
|
+
//
|
|
35
|
+
//---------------------------------------------------------
|
|
36
|
+
// How to call this module supported(index.js/index.mjs)
|
|
37
|
+
//---------------------------------------------------------
|
|
38
|
+
// - CommonJS
|
|
39
|
+
// const k2hdkc = require('k2hdkc');
|
|
40
|
+
// const k2hdkcobj = k2hdkc();
|
|
41
|
+
//
|
|
42
|
+
// - CommonJS(reference constuctor directly)
|
|
43
|
+
// const k2hdkc = require('k2hdkc');
|
|
44
|
+
// const k2hdkcNode = k2hdkc.K2hdkcNode;
|
|
45
|
+
// const k2hdkcobj = k2hdkc();
|
|
46
|
+
//
|
|
47
|
+
// - TypeScript(1)
|
|
48
|
+
// import k2hdkc from 'k2hdkc';
|
|
49
|
+
// const k2hdkcobj = k2hdkc();
|
|
50
|
+
//
|
|
51
|
+
// - TypeScript(2)
|
|
52
|
+
// import k2hdkc from 'k2hdkc';
|
|
53
|
+
// const k2hdkcobj = new k2hdkc();
|
|
54
|
+
//
|
|
55
|
+
// - TypeScript(3: compatible calling)
|
|
56
|
+
// import k2hdkc = require('k2hdkc');
|
|
57
|
+
// const k2hdkcobj = k2hdkc();
|
|
58
|
+
//
|
|
59
|
+
// - TypeScript(reference constuctor directly)
|
|
60
|
+
// import k2hdkc from 'k2hdkc';
|
|
61
|
+
// const k2hdkcNode = k2hdkc.K2hdkcNode;
|
|
62
|
+
// const k2hdkcobj = k2hdkc();
|
|
63
|
+
//
|
|
64
|
+
// - ESM(pure ES module files: guaranteed version)
|
|
65
|
+
// import { createRequire } from 'module';
|
|
66
|
+
// const require = createRequire(import.meta.url);
|
|
67
|
+
// const k2hdkc = require('k2hdkc');
|
|
68
|
+
// const k2hdkcobj = k2hdkc();
|
|
69
|
+
//---------------------------------------------------------
|
|
70
|
+
|
|
71
|
+
type AnyFn = (...args: any[]) => any;
|
|
72
|
+
|
|
73
|
+
let _native: any = undefined;
|
|
74
|
+
let _nativeLoaded = false;
|
|
75
|
+
|
|
76
|
+
// [NOTE]
|
|
77
|
+
// Copy properties from native onto the factory(mirrors original runtime
|
|
78
|
+
// normalization)
|
|
79
|
+
// We try to preserve descriptors when possible.
|
|
80
|
+
//
|
|
81
|
+
function copyPropsToFactory(k2hdkcFactory: AnyFn, factory_native: any)
|
|
82
|
+
{
|
|
83
|
+
if(!factory_native || (typeof factory_native !== 'object' && typeof factory_native !== 'function')){
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
try{
|
|
88
|
+
Object.getOwnPropertyNames(factory_native).forEach((name) => {
|
|
89
|
+
if(name === 'prototype'){
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
try{
|
|
93
|
+
const desc = Object.getOwnPropertyDescriptor(factory_native, name);
|
|
94
|
+
if(desc){
|
|
95
|
+
Object.defineProperty(k2hdkcFactory, name, desc);
|
|
96
|
+
}
|
|
97
|
+
}catch{
|
|
98
|
+
try{
|
|
99
|
+
(k2hdkcFactory as any)[name] = factory_native[name];
|
|
100
|
+
}catch{
|
|
101
|
+
// ignore
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
Object.getOwnPropertySymbols(factory_native).forEach((sym) => {
|
|
107
|
+
try{
|
|
108
|
+
const desc = Object.getOwnPropertyDescriptor(factory_native, sym as any);
|
|
109
|
+
if(desc){
|
|
110
|
+
Object.defineProperty(k2hdkcFactory, sym as any, desc);
|
|
111
|
+
}
|
|
112
|
+
}catch{
|
|
113
|
+
try{
|
|
114
|
+
(k2hdkcFactory as any)[sym as any] = factory_native[sym as any];
|
|
115
|
+
}catch{
|
|
116
|
+
// ignore
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
});
|
|
120
|
+
}catch{
|
|
121
|
+
// ignore odd cases(native undefined or primitive)
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
try{
|
|
125
|
+
if(factory_native && factory_native.K2hdkcNode){
|
|
126
|
+
(k2hdkcFactory as any).K2hdkcNode = factory_native.K2hdkcNode;
|
|
127
|
+
}
|
|
128
|
+
}catch{
|
|
129
|
+
// ignore
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// [NOTE]
|
|
134
|
+
// Load native on first need. Also call copyPropsToFactory once after
|
|
135
|
+
// loading.
|
|
136
|
+
// require('bindings') may throw if native not present at build/test time
|
|
137
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
138
|
+
//
|
|
139
|
+
function ensureNative(): any
|
|
140
|
+
{
|
|
141
|
+
if(_nativeLoaded){
|
|
142
|
+
return _native;
|
|
143
|
+
}
|
|
144
|
+
_nativeLoaded = true;
|
|
145
|
+
|
|
146
|
+
try{
|
|
147
|
+
const bindings = require('bindings');
|
|
148
|
+
_native = bindings('k2hdkc');
|
|
149
|
+
}catch{
|
|
150
|
+
_native = undefined;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// [NOTE]
|
|
154
|
+
// If we successfully loaded native, copy properties onto the factory so
|
|
155
|
+
// default export retains the same shape as before (callable + named
|
|
156
|
+
// properties).
|
|
157
|
+
//
|
|
158
|
+
if(_native){
|
|
159
|
+
try{
|
|
160
|
+
// [NOTE]
|
|
161
|
+
// k2hdkcFactory is hoisted(function declaration), safe to
|
|
162
|
+
// reference here
|
|
163
|
+
copyPropsToFactory(k2hdkcFactory as AnyFn, _native);
|
|
164
|
+
}catch{
|
|
165
|
+
// swallow copy errors to preserve robustness
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
return _native;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
// [NOTE]
|
|
172
|
+
// Default factory that mirrors previous behavior
|
|
173
|
+
//
|
|
174
|
+
function k2hdkcFactory(...args: any[]): any
|
|
175
|
+
{
|
|
176
|
+
const _factory_native = ensureNative();
|
|
177
|
+
if(typeof _factory_native === 'function'){
|
|
178
|
+
try{
|
|
179
|
+
const retobj = (_factory_native as AnyFn).apply(null, args);
|
|
180
|
+
if(retobj !== undefined){
|
|
181
|
+
return retobj;
|
|
182
|
+
}
|
|
183
|
+
}catch{
|
|
184
|
+
// fallthrough to constructor fallback
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
if(_factory_native && typeof _factory_native.K2hdkcNode === 'function'){
|
|
189
|
+
try{
|
|
190
|
+
return new _factory_native.K2hdkcNode(...args);
|
|
191
|
+
}catch{
|
|
192
|
+
// fallthrough
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// fallback: return native itself (could be an object with properties)
|
|
197
|
+
return _factory_native;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// [NOTE]
|
|
201
|
+
// Returns a callable & constructible Proxy that forwards to native export
|
|
202
|
+
//
|
|
203
|
+
function createLazyProxy(name: string): AnyFn
|
|
204
|
+
{
|
|
205
|
+
let _cached: any = undefined;
|
|
206
|
+
|
|
207
|
+
function loadActual()
|
|
208
|
+
{
|
|
209
|
+
if(_cached !== undefined){
|
|
210
|
+
return _cached;
|
|
211
|
+
}
|
|
212
|
+
const _lazy_native = ensureNative();
|
|
213
|
+
const _actual = _lazy_native && _lazy_native[name] ? _lazy_native[name] : undefined;
|
|
214
|
+
if(!_actual){
|
|
215
|
+
throw new Error("Native export " + JSON.stringify(name) + " is not available");
|
|
216
|
+
}
|
|
217
|
+
_cached = _actual;
|
|
218
|
+
return _cached;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
const target = function (this: any, ...args: any[])
|
|
222
|
+
{
|
|
223
|
+
const _actual = loadActual();
|
|
224
|
+
return _actual.apply(this, args);
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
const handler: ProxyHandler<any> = {
|
|
228
|
+
apply(_t, thisArg, args) {
|
|
229
|
+
const _actual = loadActual();
|
|
230
|
+
return _actual.apply(thisArg, args);
|
|
231
|
+
},
|
|
232
|
+
construct(_t, args, newTarget) {
|
|
233
|
+
const _actual = loadActual();
|
|
234
|
+
return Reflect.construct(_actual, args, newTarget);
|
|
235
|
+
},
|
|
236
|
+
get(_t, prop, receiver) {
|
|
237
|
+
const _actual = loadActual();
|
|
238
|
+
return Reflect.get(_actual, prop, receiver);
|
|
239
|
+
},
|
|
240
|
+
set(_t, prop, value, receiver) {
|
|
241
|
+
const _actual = loadActual();
|
|
242
|
+
return Reflect.set(_actual, prop, value, receiver);
|
|
243
|
+
},
|
|
244
|
+
has(_t, prop) {
|
|
245
|
+
const _actual = loadActual();
|
|
246
|
+
return prop in _actual;
|
|
247
|
+
},
|
|
248
|
+
ownKeys(_t) {
|
|
249
|
+
const _actual = loadActual();
|
|
250
|
+
return Reflect.ownKeys(_actual);
|
|
251
|
+
},
|
|
252
|
+
getOwnPropertyDescriptor(_t, prop) {
|
|
253
|
+
const _actual = loadActual();
|
|
254
|
+
return Object.getOwnPropertyDescriptor(_actual, prop) || undefined;
|
|
255
|
+
},
|
|
256
|
+
getPrototypeOf(_t) {
|
|
257
|
+
const _actual = loadActual();
|
|
258
|
+
return Object.getPrototypeOf(_actual);
|
|
259
|
+
},
|
|
260
|
+
setPrototypeOf(_t, proto) {
|
|
261
|
+
const _actual = loadActual();
|
|
262
|
+
return Object.setPrototypeOf(_actual, proto);
|
|
263
|
+
},
|
|
264
|
+
defineProperty(_t, prop, descriptor) {
|
|
265
|
+
const _actual = loadActual();
|
|
266
|
+
return Reflect.defineProperty(_actual, prop, descriptor);
|
|
267
|
+
},
|
|
268
|
+
deleteProperty(_t, prop) {
|
|
269
|
+
const _actual = loadActual();
|
|
270
|
+
return Reflect.deleteProperty(_actual, prop);
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
return new Proxy(target as AnyFn, handler) as AnyFn;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
//
|
|
278
|
+
// Export named proxies to keep compatibility with existing consumers
|
|
279
|
+
//
|
|
280
|
+
// Named convenience exports (runtime values).
|
|
281
|
+
// Types are provided by types/index.d.ts.
|
|
282
|
+
//
|
|
283
|
+
export const K2hdkcNode = createLazyProxy('K2hdkcNode');
|
|
284
|
+
|
|
285
|
+
export default k2hdkcFactory;
|
|
286
|
+
|
|
287
|
+
//
|
|
288
|
+
// Compatibility normalization for CommonJS output
|
|
289
|
+
//
|
|
290
|
+
// [NOTE]
|
|
291
|
+
// When TypeScript/packager emits CommonJS, it can produce "module.exports = { default: ..., ... }"
|
|
292
|
+
// which causes ESM consumers to get an object whose "default" is the callable factory.
|
|
293
|
+
// Normalize module.exports so that "require(...)" yields a callable function while
|
|
294
|
+
// preserving named properties.
|
|
295
|
+
// This runs only in CommonJS environments and is intentionally defensive.
|
|
296
|
+
//
|
|
297
|
+
declare const module: any;
|
|
298
|
+
|
|
299
|
+
try{
|
|
300
|
+
if(typeof module !== 'undefined' && module && module.exports){
|
|
301
|
+
const own_module_export = module.exports as any;
|
|
302
|
+
|
|
303
|
+
//
|
|
304
|
+
// If module.exports is exactly { default: fn }, replace module.exports with fn.
|
|
305
|
+
//
|
|
306
|
+
if( own_module_export &&
|
|
307
|
+
typeof own_module_export === 'object' &&
|
|
308
|
+
Object.prototype.hasOwnProperty.call(own_module_export, 'default') &&
|
|
309
|
+
typeof own_module_export.default === 'function' &&
|
|
310
|
+
Object.keys(own_module_export).length === 1 )
|
|
311
|
+
{
|
|
312
|
+
module.exports = own_module_export.default;
|
|
313
|
+
|
|
314
|
+
}else if(own_module_export && typeof own_module_export === 'object' && typeof own_module_export.default === 'function'){
|
|
315
|
+
//
|
|
316
|
+
// If default is a function but other named exports exist,
|
|
317
|
+
// prefer a top-level callable while preserving named props.
|
|
318
|
+
//
|
|
319
|
+
try{
|
|
320
|
+
const defaultFn = own_module_export.default as Function;
|
|
321
|
+
|
|
322
|
+
// If top-level is not already callable, make it so.
|
|
323
|
+
if(typeof own_module_export !== 'function'){
|
|
324
|
+
// create a callable wrapper that forwards to defaultFn
|
|
325
|
+
const callable = function(this: any, ...args: any[]){
|
|
326
|
+
return defaultFn.apply(this, args);
|
|
327
|
+
};
|
|
328
|
+
|
|
329
|
+
// copy named properties from original exports except 'default'
|
|
330
|
+
Object.keys(own_module_export).forEach((key) => {
|
|
331
|
+
if(key === 'default'){
|
|
332
|
+
return;
|
|
333
|
+
}
|
|
334
|
+
try{
|
|
335
|
+
(callable as any)[key] = own_module_export[key];
|
|
336
|
+
}catch{
|
|
337
|
+
// ignore
|
|
338
|
+
}
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
// preserve reference to original module
|
|
342
|
+
try{
|
|
343
|
+
(callable as any).__orig_module = own_module_export;
|
|
344
|
+
}catch{
|
|
345
|
+
// ignore
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
// replace module.exports with callable that also carries named props
|
|
349
|
+
module.exports = callable;
|
|
350
|
+
}
|
|
351
|
+
}catch{
|
|
352
|
+
// swallow normalization errors - not critical
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
}catch{
|
|
357
|
+
// ignore
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
/*
|
|
361
|
+
* Local variables:
|
|
362
|
+
* tab-width: 4
|
|
363
|
+
* c-basic-offset: 4
|
|
364
|
+
* End:
|
|
365
|
+
* vim600: noexpandtab sw=4 ts=4 fdm=marker
|
|
366
|
+
* vim<600: noexpandtab sw=4 ts=4
|
|
367
|
+
*/
|
package/src/k2hdkc.cc
CHANGED
|
@@ -15,25 +15,38 @@
|
|
|
15
15
|
* REVISION:
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
+
#include <napi.h>
|
|
18
19
|
#include "k2hdkc_node.h"
|
|
19
20
|
|
|
20
|
-
using namespace v8 ;
|
|
21
|
-
|
|
22
21
|
//---------------------------------------------------------
|
|
23
22
|
// k2hdkc node object
|
|
24
23
|
//---------------------------------------------------------
|
|
25
|
-
|
|
24
|
+
// [NOTE]
|
|
25
|
+
// The logic for receiving arguments when switching to N-API has been removed.
|
|
26
|
+
// This is because the arguments were not used in the first place and did not
|
|
27
|
+
// need to be defined.
|
|
28
|
+
//
|
|
29
|
+
Napi::Value CreateObject(const Napi::CallbackInfo& info)
|
|
26
30
|
{
|
|
27
|
-
K2hdkcNode::NewInstance(info);
|
|
31
|
+
return K2hdkcNode::NewInstance(info);
|
|
28
32
|
}
|
|
29
33
|
|
|
30
|
-
|
|
34
|
+
Napi::Object InitAll(Napi::Env env, Napi::Object exports)
|
|
31
35
|
{
|
|
32
|
-
|
|
33
|
-
|
|
36
|
+
// Class registration (creating a constructor)
|
|
37
|
+
K2hdkcNode::Init(env, exports);
|
|
38
|
+
|
|
39
|
+
// Create a factory function that returns module.exports
|
|
40
|
+
Napi::Function createFn = Napi::Function::New(env, CreateObject, "k2hdkc");
|
|
41
|
+
|
|
42
|
+
// Allow to use "require('k2hdkc').K2hdkcNode"
|
|
43
|
+
createFn.Set("K2hdkcNode", K2hdkcNode::constructor.Value());
|
|
44
|
+
|
|
45
|
+
// Replace module.exports with this function (does not break existing "require('k2hdkc')()".)
|
|
46
|
+
return createFn;
|
|
34
47
|
}
|
|
35
48
|
|
|
36
|
-
|
|
49
|
+
NODE_API_MODULE(k2hdkc, InitAll)
|
|
37
50
|
|
|
38
51
|
/*
|
|
39
52
|
* Local variables:
|