@mks2508/hyperdiff-napi 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/Release/hyperdiff.node +0 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +100 -0
- package/dist/index.js.map +1 -0
- package/package.json +34 -0
|
Binary file
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type IFFIAdapter } from '@mks2508/hyperdiff-utils';
|
|
2
|
+
/**
|
|
3
|
+
* Create an N-API adapter for the Hyperdiff engine.
|
|
4
|
+
*
|
|
5
|
+
* Loads the precompiled hyperdiff.node addon.
|
|
6
|
+
* The addon handles all struct parsing in C — no JS pointer arithmetic needed.
|
|
7
|
+
*
|
|
8
|
+
* @returns IFFIAdapter implementation backed by .node addon
|
|
9
|
+
*/
|
|
10
|
+
export declare function createNapiAdapter(): IFFIAdapter;
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
import { dirname, join } from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import "@mks2508/hyperdiff-utils";
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
/**
|
|
7
|
+
* N-API adapter for the Hyperdiff Zig engine.
|
|
8
|
+
*
|
|
9
|
+
* Loads the compiled .node addon (which statically links libhyperdiff).
|
|
10
|
+
* Works in both Node.js and Bun.
|
|
11
|
+
*
|
|
12
|
+
* The .node addon handles struct reading in C — so compute() returns
|
|
13
|
+
* fully parsed JS objects directly (no pointer reading in JS).
|
|
14
|
+
*/
|
|
15
|
+
/**
|
|
16
|
+
* Create an N-API adapter for the Hyperdiff engine.
|
|
17
|
+
*
|
|
18
|
+
* Loads the precompiled hyperdiff.node addon.
|
|
19
|
+
* The addon handles all struct parsing in C — no JS pointer arithmetic needed.
|
|
20
|
+
*
|
|
21
|
+
* @returns IFFIAdapter implementation backed by .node addon
|
|
22
|
+
*/
|
|
23
|
+
function createNapiAdapter() {
|
|
24
|
+
const require = createRequire(import.meta.url);
|
|
25
|
+
let addon;
|
|
26
|
+
try {
|
|
27
|
+
addon = require(join(dirname(fileURLToPath(import.meta.url)), "..", "build", "Release", "hyperdiff.node"));
|
|
28
|
+
} catch {
|
|
29
|
+
throw new Error("@mks2508/hyperdiff-napi: Failed to load hyperdiff.node. Run `node-gyp rebuild` in core/packages/napi/ first. Requires: Zig build (libhyperdiff_static.a) + C compiler.");
|
|
30
|
+
}
|
|
31
|
+
let lastEdits = [];
|
|
32
|
+
let lastHunks = [];
|
|
33
|
+
let lastContents = [];
|
|
34
|
+
return {
|
|
35
|
+
runtime: "napi",
|
|
36
|
+
compute(oldText, newText, algorithm) {
|
|
37
|
+
const oldBuf = Buffer.from(oldText, "utf-8");
|
|
38
|
+
const newBuf = Buffer.from(newText, "utf-8");
|
|
39
|
+
const result = addon.compute(oldBuf, newBuf, algorithm);
|
|
40
|
+
lastEdits = result.edits;
|
|
41
|
+
return {
|
|
42
|
+
editsPtr: 0,
|
|
43
|
+
editCount: result.editCount,
|
|
44
|
+
errorCode: result.errorCode
|
|
45
|
+
};
|
|
46
|
+
},
|
|
47
|
+
free(_resultPtr) {},
|
|
48
|
+
ping() {
|
|
49
|
+
return addon.ping();
|
|
50
|
+
},
|
|
51
|
+
ceditSize() {
|
|
52
|
+
return addon.ceditSize();
|
|
53
|
+
},
|
|
54
|
+
abiVersion() {
|
|
55
|
+
return addon.abiVersion();
|
|
56
|
+
},
|
|
57
|
+
readEdits(_editsPtr, _editCount) {
|
|
58
|
+
return lastEdits;
|
|
59
|
+
},
|
|
60
|
+
metadata(oldText, newText, algorithm, contextLines, flags = 0) {
|
|
61
|
+
const oldBuf = Buffer.from(oldText, "utf-8");
|
|
62
|
+
const newBuf = Buffer.from(newText, "utf-8");
|
|
63
|
+
const result = addon.metadata(oldBuf, newBuf, algorithm, contextLines, flags);
|
|
64
|
+
lastHunks = result.hunks;
|
|
65
|
+
lastContents = result.contents;
|
|
66
|
+
return {
|
|
67
|
+
hunksPtr: 0,
|
|
68
|
+
hunkCount: result.hunkCount,
|
|
69
|
+
contentsPtr: 0,
|
|
70
|
+
contentCount: result.contentCount,
|
|
71
|
+
splitLineCount: result.splitLineCount,
|
|
72
|
+
unifiedLineCount: result.unifiedLineCount,
|
|
73
|
+
oldLineCount: result.oldLineCount,
|
|
74
|
+
newLineCount: result.newLineCount,
|
|
75
|
+
errorCode: result.errorCode
|
|
76
|
+
};
|
|
77
|
+
},
|
|
78
|
+
readHunks(_hunksPtr, _hunkCount) {
|
|
79
|
+
return lastHunks;
|
|
80
|
+
},
|
|
81
|
+
readContents(_contentsPtr, _contentCount) {
|
|
82
|
+
return lastContents;
|
|
83
|
+
},
|
|
84
|
+
metadataFree(_hunksPtr, _hunkCount, _contentsPtr, _contentCount) {},
|
|
85
|
+
patch(oldText, newText, algorithm, contextLines) {
|
|
86
|
+
const oldBuf = Buffer.from(oldText, "utf-8");
|
|
87
|
+
const newBuf = Buffer.from(newText, "utf-8");
|
|
88
|
+
return addon.patch(oldBuf, newBuf, algorithm, contextLines);
|
|
89
|
+
},
|
|
90
|
+
inlineDiff(oldLine, newLine, mode) {
|
|
91
|
+
const oldBuf = Buffer.from(oldLine, "utf-8");
|
|
92
|
+
const newBuf = Buffer.from(newLine, "utf-8");
|
|
93
|
+
return addon.inlineDiff(oldBuf, newBuf, mode);
|
|
94
|
+
}
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
//#endregion
|
|
98
|
+
export { createNapiAdapter };
|
|
99
|
+
|
|
100
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/**\n * N-API adapter for the Hyperdiff Zig engine.\n *\n * Loads the compiled .node addon (which statically links libhyperdiff).\n * Works in both Node.js and Bun.\n *\n * The .node addon handles struct reading in C — so compute() returns\n * fully parsed JS objects directly (no pointer reading in JS).\n */\nimport { createRequire } from 'node:module';\nimport { join, dirname } from 'node:path';\nimport { fileURLToPath } from 'node:url';\nimport {\n type IRawDiffEdit,\n type IRawDiffResult,\n type IRawMetadataResult,\n type IRawHunk,\n type IRawContent,\n type IFFIAdapter,\n} from '@mks2508/hyperdiff-utils';\n\n/** Native addon exports. */\ninterface INativeAddon {\n compute(oldBuf: Buffer, newBuf: Buffer, algorithm: number): {\n edits: IRawDiffEdit[];\n editCount: number;\n errorCode: number;\n };\n patch(oldBuf: Buffer, newBuf: Buffer, algorithm: number, contextLines: number): string;\n inlineDiff(oldBuf: Buffer, newBuf: Buffer, mode: number): IRawDiffEdit[];\n metadata(oldBuf: Buffer, newBuf: Buffer, algorithm: number, contextLines: number, flags: number): {\n hunks: IRawHunk[];\n contents: IRawContent[];\n hunkCount: number;\n contentCount: number;\n splitLineCount: number;\n unifiedLineCount: number;\n oldLineCount: number;\n newLineCount: number;\n errorCode: number;\n };\n ping(): number;\n ceditSize(): number;\n abiVersion(): number;\n}\n\n/**\n * Create an N-API adapter for the Hyperdiff engine.\n *\n * Loads the precompiled hyperdiff.node addon.\n * The addon handles all struct parsing in C — no JS pointer arithmetic needed.\n *\n * @returns IFFIAdapter implementation backed by .node addon\n */\nexport function createNapiAdapter(): IFFIAdapter {\n const require = createRequire(import.meta.url);\n\n let addon: INativeAddon;\n try {\n // node-gyp outputs to build/Release/hyperdiff.node\n const __dir = dirname(fileURLToPath(import.meta.url));\n addon = require(join(__dir, '..', 'build', 'Release', 'hyperdiff.node'));\n } catch {\n throw new Error(\n '@mks2508/hyperdiff-napi: Failed to load hyperdiff.node. ' +\n 'Run `node-gyp rebuild` in core/packages/napi/ first. ' +\n 'Requires: Zig build (libhyperdiff_static.a) + C compiler.',\n );\n }\n\n // The N-API addon does struct parsing in C and returns JS objects directly.\n // Cache last results for read* methods.\n let lastEdits: IRawDiffEdit[] = [];\n let lastHunks: IRawHunk[] = [];\n let lastContents: IRawContent[] = [];\n\n return {\n runtime: 'napi',\n\n compute(oldText: string, newText: string, algorithm: number): IRawDiffResult {\n const oldBuf = Buffer.from(oldText, 'utf-8');\n const newBuf = Buffer.from(newText, 'utf-8');\n\n const result = addon.compute(oldBuf, newBuf, algorithm);\n lastEdits = result.edits;\n\n // N-API addon returns parsed objects (no raw pointer).\n // editsPtr is not meaningful here — adapter handles it.\n return {\n editsPtr: 0,\n editCount: result.editCount,\n errorCode: result.errorCode,\n };\n },\n\n free(_resultPtr: number): void {\n // N-API addon frees Zig memory in C before returning. No-op here.\n },\n\n ping(): number {\n return addon.ping();\n },\n\n ceditSize(): number {\n return addon.ceditSize();\n },\n\n abiVersion(): number {\n return addon.abiVersion();\n },\n\n readEdits(_editsPtr: number, _editCount: number): IRawDiffEdit[] {\n // Already parsed by the C addon during compute().\n return lastEdits;\n },\n\n metadata(oldText: string, newText: string, algorithm: number, contextLines: number, flags: number = 0): IRawMetadataResult {\n const oldBuf = Buffer.from(oldText, 'utf-8');\n const newBuf = Buffer.from(newText, 'utf-8');\n\n const result = addon.metadata(oldBuf, newBuf, algorithm, contextLines, flags);\n\n // N-API addon returns fully parsed JS objects + frees Zig memory in C.\n // Cache hunks/contents for readHunks/readContents.\n lastHunks = result.hunks;\n lastContents = result.contents;\n\n return {\n hunksPtr: 0,\n hunkCount: result.hunkCount,\n contentsPtr: 0,\n contentCount: result.contentCount,\n splitLineCount: result.splitLineCount,\n unifiedLineCount: result.unifiedLineCount,\n oldLineCount: result.oldLineCount,\n newLineCount: result.newLineCount,\n errorCode: result.errorCode,\n };\n },\n\n readHunks(_hunksPtr: number, _hunkCount: number): IRawHunk[] {\n return lastHunks;\n },\n\n readContents(_contentsPtr: number, _contentCount: number): IRawContent[] {\n return lastContents;\n },\n\n metadataFree(_hunksPtr: number, _hunkCount: number, _contentsPtr: number, _contentCount: number): void {\n // N-API addon frees Zig memory in C before returning. No-op here.\n },\n\n patch(oldText: string, newText: string, algorithm: number, contextLines: number): string {\n const oldBuf = Buffer.from(oldText, 'utf-8');\n const newBuf = Buffer.from(newText, 'utf-8');\n return addon.patch(oldBuf, newBuf, algorithm, contextLines);\n },\n\n inlineDiff(oldLine: string, newLine: string, mode: number): IRawDiffEdit[] {\n const oldBuf = Buffer.from(oldLine, 'utf-8');\n const newBuf = Buffer.from(newLine, 'utf-8');\n return addon.inlineDiff(oldBuf, newBuf, mode);\n },\n };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsDA,SAAgB,oBAAiC;CAC/C,MAAM,UAAU,cAAc,OAAO,KAAK,IAAI;CAE9C,IAAI;AACJ,KAAI;AAGF,UAAQ,QAAQ,KADF,QAAQ,cAAc,OAAO,KAAK,IAAI,CAAC,EACzB,MAAM,SAAS,WAAW,iBAAiB,CAAC;SAClE;AACN,QAAM,IAAI,MACR,yKAGD;;CAKH,IAAI,YAA4B,EAAE;CAClC,IAAI,YAAwB,EAAE;CAC9B,IAAI,eAA8B,EAAE;AAEpC,QAAO;EACL,SAAS;EAET,QAAQ,SAAiB,SAAiB,WAAmC;GAC3E,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;GAC5C,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;GAE5C,MAAM,SAAS,MAAM,QAAQ,QAAQ,QAAQ,UAAU;AACvD,eAAY,OAAO;AAInB,UAAO;IACL,UAAU;IACV,WAAW,OAAO;IAClB,WAAW,OAAO;IACnB;;EAGH,KAAK,YAA0B;EAI/B,OAAe;AACb,UAAO,MAAM,MAAM;;EAGrB,YAAoB;AAClB,UAAO,MAAM,WAAW;;EAG1B,aAAqB;AACnB,UAAO,MAAM,YAAY;;EAG3B,UAAU,WAAmB,YAAoC;AAE/D,UAAO;;EAGT,SAAS,SAAiB,SAAiB,WAAmB,cAAsB,QAAgB,GAAuB;GACzH,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;GAC5C,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;GAE5C,MAAM,SAAS,MAAM,SAAS,QAAQ,QAAQ,WAAW,cAAc,MAAM;AAI7E,eAAY,OAAO;AACnB,kBAAe,OAAO;AAEtB,UAAO;IACL,UAAU;IACV,WAAW,OAAO;IAClB,aAAa;IACb,cAAc,OAAO;IACrB,gBAAgB,OAAO;IACvB,kBAAkB,OAAO;IACzB,cAAc,OAAO;IACrB,cAAc,OAAO;IACrB,WAAW,OAAO;IACnB;;EAGH,UAAU,WAAmB,YAAgC;AAC3D,UAAO;;EAGT,aAAa,cAAsB,eAAsC;AACvE,UAAO;;EAGT,aAAa,WAAmB,YAAoB,cAAsB,eAA6B;EAIvG,MAAM,SAAiB,SAAiB,WAAmB,cAA8B;GACvF,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;GAC5C,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;AAC5C,UAAO,MAAM,MAAM,QAAQ,QAAQ,WAAW,aAAa;;EAG7D,WAAW,SAAiB,SAAiB,MAA8B;GACzE,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;GAC5C,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;AAC5C,UAAO,MAAM,WAAW,QAAQ,QAAQ,KAAK;;EAEhD"}
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@mks2508/hyperdiff-napi",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist",
|
|
9
|
+
"build/Release/hyperdiff.node"
|
|
10
|
+
],
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"import": "./dist/index.js",
|
|
14
|
+
"types": "./dist/index.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"publishConfig": {
|
|
18
|
+
"access": "public"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"prebuild": "node scripts/configure.mjs",
|
|
22
|
+
"build:native": "node-gyp rebuild",
|
|
23
|
+
"build": "rm -rf dist && ../../../node_modules/.bin/rolldown --config rolldown.config.ts && ../../../node_modules/.bin/tsc --emitDeclarationOnly",
|
|
24
|
+
"typecheck": "tsc --noEmit"
|
|
25
|
+
},
|
|
26
|
+
"dependencies": {
|
|
27
|
+
"@mks2508/hyperdiff-utils": "workspace:*",
|
|
28
|
+
"node-gyp": "^10.2.0"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@types/node": "^22.0.0"
|
|
32
|
+
},
|
|
33
|
+
"gypfile": true
|
|
34
|
+
}
|