@n2world/core 1.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.
- package/index.d.ts +65 -0
- package/index.js +325 -0
- package/n2world-core.darwin-arm64.node +0 -0
- package/n2world-core.linux-x64-gnu.node +0 -0
- package/n2world-core.win32-x64-msvc.node +0 -0
- package/package.json +47 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
export declare function helloWorld(input: string): string
|
|
7
|
+
export declare function lockSharedBuffer(buf: Uint8Array): boolean
|
|
8
|
+
export declare function unlockSharedBuffer(buf: Uint8Array): boolean
|
|
9
|
+
export declare function computeCosineSimilarity(buf: Uint8Array, offsetA: number, offsetB: number, dimensions: number): number
|
|
10
|
+
export declare function readMetaTuple(buf: Uint8Array): string
|
|
11
|
+
export declare function pruneActions(actions: Array<string>, invalidPatterns: Array<string>): Array<string>
|
|
12
|
+
/**
|
|
13
|
+
* cgroups v2 `cpu.weight` 실제 기입(Linux). 경로가 없거나 권한이 없으면 false 를 반환한다.
|
|
14
|
+
* 정직 원칙: 비-Linux/비-cgroup 환경에서 "거짓 true"를 돌려주지 않는다(거짓 폴백 금지).
|
|
15
|
+
* 유효 범위는 cgroups v2 규격상 1..=10000.
|
|
16
|
+
*/
|
|
17
|
+
export declare function setCgroupCpuWeight(cgroupPath: string, weight: number): boolean
|
|
18
|
+
/** 이 시스템에 cgroups v2 단일 계층이 마운트되어 있는가(Linux). 호출자는 이걸로 폴백을 결정한다. */
|
|
19
|
+
export declare function cgroupV2Available(): boolean
|
|
20
|
+
export declare class MctsEngine {
|
|
21
|
+
constructor(goalX: number, goalY: number)
|
|
22
|
+
/** 탐험/활용 상수 c_puct 조정(이후 스윕 대상). */
|
|
23
|
+
setCPuct(c: number): void
|
|
24
|
+
/** 사전확률 모드: 0 = L0(균등, UCT 퇴화 베이스라인), 1 = L1(휴리스틱). */
|
|
25
|
+
setPriorMode(mode: number): void
|
|
26
|
+
/** 동기 MCTS: 진짜 트리를 세워 simulations 회 탐색 후 최선 행동을 반환. */
|
|
27
|
+
search(startX: number, startY: number, simulations: number): number
|
|
28
|
+
/** 루트 정규화 가치 v∈[0,1] (스케줄러로 흘려보낼 가치 신호의 발원). */
|
|
29
|
+
rootValue(): number
|
|
30
|
+
/** 7-0a top-k 노출(P1 투기적 선실행용): 방문수 상위 행동을 JSON 배열로. */
|
|
31
|
+
topActionsJson(): string
|
|
32
|
+
/** 탐색 시작: 영속 트리 초기화(Freeze 대상 상태를 struct에 보존). */
|
|
33
|
+
begin(startX: number, startY: number): void
|
|
34
|
+
/**
|
|
35
|
+
* 1단계(g_fast) 시뮬레이션을 budget회 수행하되, 1·2위 가치차가 margin 미만으로
|
|
36
|
+
* 불확실해지면 그 리프를 동결(Freeze)하고 제어권을 양보(Yield) — JSON 요청 반환.
|
|
37
|
+
* 스레드를 블로킹하지 않는다. {"yield":true,...} 또는 {"done":true,...}.
|
|
38
|
+
*/
|
|
39
|
+
stepUntilYield(budget: number, margin: number): string
|
|
40
|
+
/** 2단계(LLM) 결과 value∈[0,1]를 받아 동결됐던 리프부터 백업하고 탐색 재개(Resume). */
|
|
41
|
+
resume(value: number): boolean
|
|
42
|
+
/**
|
|
43
|
+
* 비동기 탐색: 진짜 MCTS를 워커 스레드에서 수행하고 실제 최선 행동을 콜백으로 전달
|
|
44
|
+
* (기존 sleep+문자열 스텁 제거).
|
|
45
|
+
*/
|
|
46
|
+
searchAsync(startX: number, startY: number, callback: (err: Error | null, arg: string) => any): void
|
|
47
|
+
}
|
|
48
|
+
export declare class HnswIndex {
|
|
49
|
+
constructor()
|
|
50
|
+
addItem(filePath: string, vector: Array<number>): void
|
|
51
|
+
/** 진짜 HNSW 탐색: 상위층 강하 후 층0 빔서치 → top-k 파일 경로. */
|
|
52
|
+
search(queryVector: Array<number>, topK: number): Array<string>
|
|
53
|
+
/** 탐색 + 방문 노드 수(JSON). visited << N 이면 전수 스캔이 아님을 증명. */
|
|
54
|
+
searchWithStats(queryVector: Array<number>, topK: number): string
|
|
55
|
+
/** recall 비교용 기준선(전수 코사인). HNSW 가 아님 — 정확도 평가에만 사용. */
|
|
56
|
+
searchBruteforce(queryVector: Array<number>, topK: number): Array<string>
|
|
57
|
+
len(): number
|
|
58
|
+
}
|
|
59
|
+
export declare class EbpfMapScheduler {
|
|
60
|
+
constructor()
|
|
61
|
+
/** MCTS 가치 v 를 thread_id 키로 BPF 맵에 실제 주입. 맵 비활성이면 false. */
|
|
62
|
+
updateEbpfMap(threadId: number, mctsV: number): boolean
|
|
63
|
+
/** 실제 BPF 맵이 활성인가(Linux + CAP_BPF). 비-Linux/비-권한이면 false. */
|
|
64
|
+
mapActive(): boolean
|
|
65
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* prettier-ignore */
|
|
4
|
+
|
|
5
|
+
/* auto-generated by NAPI-RS */
|
|
6
|
+
|
|
7
|
+
const { existsSync, readFileSync } = require('fs')
|
|
8
|
+
const { join } = require('path')
|
|
9
|
+
|
|
10
|
+
const { platform, arch } = process
|
|
11
|
+
|
|
12
|
+
let nativeBinding = null
|
|
13
|
+
let localFileExisted = false
|
|
14
|
+
let loadError = null
|
|
15
|
+
|
|
16
|
+
function isMusl() {
|
|
17
|
+
// For Node 10
|
|
18
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
19
|
+
try {
|
|
20
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
27
|
+
return !glibcVersionRuntime
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
switch (platform) {
|
|
32
|
+
case 'android':
|
|
33
|
+
switch (arch) {
|
|
34
|
+
case 'arm64':
|
|
35
|
+
localFileExisted = existsSync(join(__dirname, 'n2world-core.android-arm64.node'))
|
|
36
|
+
try {
|
|
37
|
+
if (localFileExisted) {
|
|
38
|
+
nativeBinding = require('./n2world-core.android-arm64.node')
|
|
39
|
+
} else {
|
|
40
|
+
nativeBinding = require('@n2world/core-android-arm64')
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
loadError = e
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
case 'arm':
|
|
47
|
+
localFileExisted = existsSync(join(__dirname, 'n2world-core.android-arm-eabi.node'))
|
|
48
|
+
try {
|
|
49
|
+
if (localFileExisted) {
|
|
50
|
+
nativeBinding = require('./n2world-core.android-arm-eabi.node')
|
|
51
|
+
} else {
|
|
52
|
+
nativeBinding = require('@n2world/core-android-arm-eabi')
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
loadError = e
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Unsupported architecture on Android ${arch}`)
|
|
60
|
+
}
|
|
61
|
+
break
|
|
62
|
+
case 'win32':
|
|
63
|
+
switch (arch) {
|
|
64
|
+
case 'x64':
|
|
65
|
+
localFileExisted = existsSync(
|
|
66
|
+
join(__dirname, 'n2world-core.win32-x64-msvc.node')
|
|
67
|
+
)
|
|
68
|
+
try {
|
|
69
|
+
if (localFileExisted) {
|
|
70
|
+
nativeBinding = require('./n2world-core.win32-x64-msvc.node')
|
|
71
|
+
} else {
|
|
72
|
+
nativeBinding = require('@n2world/core-win32-x64-msvc')
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadError = e
|
|
76
|
+
}
|
|
77
|
+
break
|
|
78
|
+
case 'ia32':
|
|
79
|
+
localFileExisted = existsSync(
|
|
80
|
+
join(__dirname, 'n2world-core.win32-ia32-msvc.node')
|
|
81
|
+
)
|
|
82
|
+
try {
|
|
83
|
+
if (localFileExisted) {
|
|
84
|
+
nativeBinding = require('./n2world-core.win32-ia32-msvc.node')
|
|
85
|
+
} else {
|
|
86
|
+
nativeBinding = require('@n2world/core-win32-ia32-msvc')
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
loadError = e
|
|
90
|
+
}
|
|
91
|
+
break
|
|
92
|
+
case 'arm64':
|
|
93
|
+
localFileExisted = existsSync(
|
|
94
|
+
join(__dirname, 'n2world-core.win32-arm64-msvc.node')
|
|
95
|
+
)
|
|
96
|
+
try {
|
|
97
|
+
if (localFileExisted) {
|
|
98
|
+
nativeBinding = require('./n2world-core.win32-arm64-msvc.node')
|
|
99
|
+
} else {
|
|
100
|
+
nativeBinding = require('@n2world/core-win32-arm64-msvc')
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
loadError = e
|
|
104
|
+
}
|
|
105
|
+
break
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
108
|
+
}
|
|
109
|
+
break
|
|
110
|
+
case 'darwin':
|
|
111
|
+
localFileExisted = existsSync(join(__dirname, 'n2world-core.darwin-universal.node'))
|
|
112
|
+
try {
|
|
113
|
+
if (localFileExisted) {
|
|
114
|
+
nativeBinding = require('./n2world-core.darwin-universal.node')
|
|
115
|
+
} else {
|
|
116
|
+
nativeBinding = require('@n2world/core-darwin-universal')
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
} catch {}
|
|
120
|
+
switch (arch) {
|
|
121
|
+
case 'x64':
|
|
122
|
+
localFileExisted = existsSync(join(__dirname, 'n2world-core.darwin-x64.node'))
|
|
123
|
+
try {
|
|
124
|
+
if (localFileExisted) {
|
|
125
|
+
nativeBinding = require('./n2world-core.darwin-x64.node')
|
|
126
|
+
} else {
|
|
127
|
+
nativeBinding = require('@n2world/core-darwin-x64')
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
loadError = e
|
|
131
|
+
}
|
|
132
|
+
break
|
|
133
|
+
case 'arm64':
|
|
134
|
+
localFileExisted = existsSync(
|
|
135
|
+
join(__dirname, 'n2world-core.darwin-arm64.node')
|
|
136
|
+
)
|
|
137
|
+
try {
|
|
138
|
+
if (localFileExisted) {
|
|
139
|
+
nativeBinding = require('./n2world-core.darwin-arm64.node')
|
|
140
|
+
} else {
|
|
141
|
+
nativeBinding = require('@n2world/core-darwin-arm64')
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
loadError = e
|
|
145
|
+
}
|
|
146
|
+
break
|
|
147
|
+
default:
|
|
148
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case 'freebsd':
|
|
152
|
+
if (arch !== 'x64') {
|
|
153
|
+
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
|
154
|
+
}
|
|
155
|
+
localFileExisted = existsSync(join(__dirname, 'n2world-core.freebsd-x64.node'))
|
|
156
|
+
try {
|
|
157
|
+
if (localFileExisted) {
|
|
158
|
+
nativeBinding = require('./n2world-core.freebsd-x64.node')
|
|
159
|
+
} else {
|
|
160
|
+
nativeBinding = require('@n2world/core-freebsd-x64')
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
loadError = e
|
|
164
|
+
}
|
|
165
|
+
break
|
|
166
|
+
case 'linux':
|
|
167
|
+
switch (arch) {
|
|
168
|
+
case 'x64':
|
|
169
|
+
if (isMusl()) {
|
|
170
|
+
localFileExisted = existsSync(
|
|
171
|
+
join(__dirname, 'n2world-core.linux-x64-musl.node')
|
|
172
|
+
)
|
|
173
|
+
try {
|
|
174
|
+
if (localFileExisted) {
|
|
175
|
+
nativeBinding = require('./n2world-core.linux-x64-musl.node')
|
|
176
|
+
} else {
|
|
177
|
+
nativeBinding = require('@n2world/core-linux-x64-musl')
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadError = e
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
localFileExisted = existsSync(
|
|
184
|
+
join(__dirname, 'n2world-core.linux-x64-gnu.node')
|
|
185
|
+
)
|
|
186
|
+
try {
|
|
187
|
+
if (localFileExisted) {
|
|
188
|
+
nativeBinding = require('./n2world-core.linux-x64-gnu.node')
|
|
189
|
+
} else {
|
|
190
|
+
nativeBinding = require('@n2world/core-linux-x64-gnu')
|
|
191
|
+
}
|
|
192
|
+
} catch (e) {
|
|
193
|
+
loadError = e
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break
|
|
197
|
+
case 'arm64':
|
|
198
|
+
if (isMusl()) {
|
|
199
|
+
localFileExisted = existsSync(
|
|
200
|
+
join(__dirname, 'n2world-core.linux-arm64-musl.node')
|
|
201
|
+
)
|
|
202
|
+
try {
|
|
203
|
+
if (localFileExisted) {
|
|
204
|
+
nativeBinding = require('./n2world-core.linux-arm64-musl.node')
|
|
205
|
+
} else {
|
|
206
|
+
nativeBinding = require('@n2world/core-linux-arm64-musl')
|
|
207
|
+
}
|
|
208
|
+
} catch (e) {
|
|
209
|
+
loadError = e
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
localFileExisted = existsSync(
|
|
213
|
+
join(__dirname, 'n2world-core.linux-arm64-gnu.node')
|
|
214
|
+
)
|
|
215
|
+
try {
|
|
216
|
+
if (localFileExisted) {
|
|
217
|
+
nativeBinding = require('./n2world-core.linux-arm64-gnu.node')
|
|
218
|
+
} else {
|
|
219
|
+
nativeBinding = require('@n2world/core-linux-arm64-gnu')
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadError = e
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
break
|
|
226
|
+
case 'arm':
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'n2world-core.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
231
|
+
try {
|
|
232
|
+
if (localFileExisted) {
|
|
233
|
+
nativeBinding = require('./n2world-core.linux-arm-musleabihf.node')
|
|
234
|
+
} else {
|
|
235
|
+
nativeBinding = require('@n2world/core-linux-arm-musleabihf')
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
loadError = e
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'n2world-core.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./n2world-core.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@n2world/core-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'n2world-core.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./n2world-core.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@n2world/core-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'n2world-core.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./n2world-core.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@n2world/core-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
285
|
+
localFileExisted = existsSync(
|
|
286
|
+
join(__dirname, 'n2world-core.linux-s390x-gnu.node')
|
|
287
|
+
)
|
|
288
|
+
try {
|
|
289
|
+
if (localFileExisted) {
|
|
290
|
+
nativeBinding = require('./n2world-core.linux-s390x-gnu.node')
|
|
291
|
+
} else {
|
|
292
|
+
nativeBinding = require('@n2world/core-linux-s390x-gnu')
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadError = e
|
|
296
|
+
}
|
|
297
|
+
break
|
|
298
|
+
default:
|
|
299
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
300
|
+
}
|
|
301
|
+
break
|
|
302
|
+
default:
|
|
303
|
+
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!nativeBinding) {
|
|
307
|
+
if (loadError) {
|
|
308
|
+
throw loadError
|
|
309
|
+
}
|
|
310
|
+
throw new Error(`Failed to load native binding`)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const { helloWorld, lockSharedBuffer, unlockSharedBuffer, computeCosineSimilarity, readMetaTuple, MctsEngine, pruneActions, HnswIndex, setCgroupCpuWeight, cgroupV2Available, EbpfMapScheduler } = nativeBinding
|
|
314
|
+
|
|
315
|
+
module.exports.helloWorld = helloWorld
|
|
316
|
+
module.exports.lockSharedBuffer = lockSharedBuffer
|
|
317
|
+
module.exports.unlockSharedBuffer = unlockSharedBuffer
|
|
318
|
+
module.exports.computeCosineSimilarity = computeCosineSimilarity
|
|
319
|
+
module.exports.readMetaTuple = readMetaTuple
|
|
320
|
+
module.exports.MctsEngine = MctsEngine
|
|
321
|
+
module.exports.pruneActions = pruneActions
|
|
322
|
+
module.exports.HnswIndex = HnswIndex
|
|
323
|
+
module.exports.setCgroupCpuWeight = setCgroupCpuWeight
|
|
324
|
+
module.exports.cgroupV2Available = cgroupV2Available
|
|
325
|
+
module.exports.EbpfMapScheduler = EbpfMapScheduler
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/package.json
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@n2world/core",
|
|
3
|
+
"version": "1.1.0",
|
|
4
|
+
"description": "N2World 네이티브 코어 — MCTS·HNSW·코루틴·cgroups/eBPF (napi-rs)",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"main": "index.js",
|
|
7
|
+
"types": "index.d.ts",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/suhopark1-tech/n2world.git",
|
|
11
|
+
"directory": "packages/core"
|
|
12
|
+
},
|
|
13
|
+
"files": [
|
|
14
|
+
"index.js",
|
|
15
|
+
"index.d.ts",
|
|
16
|
+
"*.node"
|
|
17
|
+
],
|
|
18
|
+
"engines": {
|
|
19
|
+
"node": ">=18"
|
|
20
|
+
},
|
|
21
|
+
"napi": {
|
|
22
|
+
"name": "n2world-core",
|
|
23
|
+
"triples": {
|
|
24
|
+
"defaults": true,
|
|
25
|
+
"additional": [
|
|
26
|
+
"x86_64-unknown-linux-gnu",
|
|
27
|
+
"aarch64-unknown-linux-gnu",
|
|
28
|
+
"x86_64-apple-darwin",
|
|
29
|
+
"aarch64-apple-darwin",
|
|
30
|
+
"x86_64-pc-windows-msvc",
|
|
31
|
+
"aarch64-pc-windows-msvc"
|
|
32
|
+
]
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"napi": "napi",
|
|
37
|
+
"build": "napi build --platform --release",
|
|
38
|
+
"build:debug": "napi build --platform",
|
|
39
|
+
"prepublishOnly": "node -e \"if(!require('fs').readdirSync('.').some(f=>f.endsWith('.node')))throw new Error('publish 거부: .node 프리빌트가 없습니다(번들 전략). release.yml가 전 플랫폼 .node를 수집한 뒤 publish해야 합니다.')\"",
|
|
40
|
+
"artifacts": "napi artifacts",
|
|
41
|
+
"universal": "napi universal",
|
|
42
|
+
"version": "napi version"
|
|
43
|
+
},
|
|
44
|
+
"devDependencies": {
|
|
45
|
+
"@napi-rs/cli": "^2.18.4"
|
|
46
|
+
}
|
|
47
|
+
}
|