@f5-sales-demo/pi-natives 19.51.2

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.
@@ -0,0 +1,348 @@
1
+ /**
2
+ * Native addon loader and bindings.
3
+ *
4
+ * Types are auto-generated by napi-rs in `native/index.d.ts`.
5
+ */
6
+ const fs = require("node:fs");
7
+ const { createRequire } = require("node:module");
8
+ const os = require("node:os");
9
+ const path = require("node:path");
10
+
11
+ function getNativesDir() {
12
+ const xdgDataHome = process.env.XDG_DATA_HOME;
13
+ if (xdgDataHome && fs.existsSync(path.join(xdgDataHome, "xcsh"))) {
14
+ return path.join(xdgDataHome, "xcsh", "natives");
15
+ }
16
+ return path.join(os.homedir(), ".xcsh", "natives");
17
+ }
18
+ const packageJson = require("../package.json");
19
+ let embeddedAddon = null;
20
+
21
+ const require_ = createRequire(__filename);
22
+ const platformTag = `${process.platform}-${process.arch}`;
23
+ const packageVersion = packageJson.version;
24
+ const nativeDir = path.join(__dirname, "..", "native");
25
+ const execDir = path.dirname(process.execPath);
26
+ const versionedDir = path.join(getNativesDir(), packageVersion);
27
+ const userDataDir =
28
+ process.platform === "win32"
29
+ ? path.join(process.env.LOCALAPPDATA || path.join(os.homedir(), "AppData", "Local"), "xcsh")
30
+ : path.join(os.homedir(), ".local", "bin");
31
+ // PI_COMPILED is replaced with `true` at compile time by bun build --define PI_COMPILED=true.
32
+ // In non-compiled contexts the identifier is undefined, so wrap in try-catch.
33
+ // The __filename checks are kept as a secondary heuristic but are unreliable
34
+ // in Bun compiled binaries where __filename resolves to the original build path.
35
+ let _piCompiledFlag = false;
36
+ try {
37
+ _piCompiledFlag = !!PI_COMPILED;
38
+ } catch {
39
+ // Not a compiled binary (PI_COMPILED is not defined)
40
+ }
41
+ const isCompiledBinary =
42
+ _piCompiledFlag ||
43
+ process.env.PI_COMPILED ||
44
+ __filename.includes("$bunfs") ||
45
+ __filename.includes("~BUN") ||
46
+ __filename.includes("%7EBUN");
47
+
48
+ if (isCompiledBinary) {
49
+ try {
50
+ ({ embeddedAddon } = require("./embedded-addon"));
51
+ } catch {
52
+ embeddedAddon = null;
53
+ }
54
+ }
55
+ const SUPPORTED_PLATFORMS = ["linux-x64", "linux-arm64", "darwin-x64", "darwin-arm64", "win32-x64"];
56
+
57
+ function getVariantOverride() {
58
+ const value = process.env.PI_NATIVE_VARIANT;
59
+ if (!value) return null;
60
+ if (value === "modern" || value === "baseline") return value;
61
+ return null;
62
+ }
63
+
64
+ function detectAvx2Support() {
65
+ if (process.arch !== "x64") {
66
+ return false;
67
+ }
68
+
69
+ if (process.platform === "linux") {
70
+ try {
71
+ const cpuInfo = fs.readFileSync("/proc/cpuinfo", "utf8");
72
+ return /\bavx2\b/i.test(cpuInfo);
73
+ } catch {
74
+ return false;
75
+ }
76
+ }
77
+
78
+ if (process.platform === "darwin") {
79
+ const leaf7 = runCommand("sysctl", ["-n", "machdep.cpu.leaf7_features"]);
80
+ if (leaf7 && /\bAVX2\b/i.test(leaf7)) {
81
+ return true;
82
+ }
83
+ const features = runCommand("sysctl", ["-n", "machdep.cpu.features"]);
84
+ return Boolean(features && /\bAVX2\b/i.test(features));
85
+ }
86
+
87
+ if (process.platform === "win32") {
88
+ const output = runCommand("powershell.exe", [
89
+ "-NoProfile",
90
+ "-NonInteractive",
91
+ "-Command",
92
+ "[System.Runtime.Intrinsics.X86.Avx2]::IsSupported",
93
+ ]);
94
+ return output && output.toLowerCase() === "true";
95
+ }
96
+
97
+ return false;
98
+ }
99
+
100
+ function resolveCpuVariant(override) {
101
+ if (process.arch !== "x64") return null;
102
+ if (override) return override;
103
+ return detectAvx2Support() ? "modern" : "baseline";
104
+ }
105
+
106
+ function getAddonFilenames(tag, variant) {
107
+ const defaultFilename = `pi_natives.${tag}.node`;
108
+ if (process.arch !== "x64" || !variant) return [defaultFilename];
109
+ const baselineFilename = `pi_natives.${tag}-baseline.node`;
110
+ const modernFilename = `pi_natives.${tag}-modern.node`;
111
+ if (variant === "modern") {
112
+ return [modernFilename, baselineFilename, defaultFilename];
113
+ }
114
+ return [baselineFilename, defaultFilename];
115
+ }
116
+
117
+ const variantOverride = getVariantOverride();
118
+ const selectedVariant = resolveCpuVariant(variantOverride);
119
+ const addonFilenames = getAddonFilenames(platformTag, selectedVariant);
120
+ const addonLabel = selectedVariant ? `${platformTag} (${selectedVariant})` : platformTag;
121
+
122
+ // Map platform tags to platform package names (optionalDependencies)
123
+ const PLATFORM_PACKAGE_MAP = {
124
+ "linux-x64": "@f5xc-salesdemos/pi-natives-linux-x64-gnu",
125
+ "linux-arm64": "@f5xc-salesdemos/pi-natives-linux-arm64-gnu",
126
+ "darwin-x64": "@f5xc-salesdemos/pi-natives-darwin-x64",
127
+ "darwin-arm64": "@f5xc-salesdemos/pi-natives-darwin-arm64",
128
+ "win32-x64": "@f5xc-salesdemos/pi-natives-win32-x64-msvc",
129
+ };
130
+
131
+ function resolvePlatformPackageCandidates() {
132
+ const pkgName = PLATFORM_PACKAGE_MAP[platformTag];
133
+ if (!pkgName) return [];
134
+ try {
135
+ const pkgJsonPath = require_.resolve(`${pkgName}/package.json`);
136
+ const pkgDir = path.dirname(pkgJsonPath);
137
+ return addonFilenames.map(filename => path.join(pkgDir, filename));
138
+ } catch {
139
+ return [];
140
+ }
141
+ }
142
+
143
+ const platformPackageCandidates = resolvePlatformPackageCandidates();
144
+ const baseReleaseCandidates = [
145
+ ...platformPackageCandidates,
146
+ ...addonFilenames.flatMap(filename => [
147
+ path.join(nativeDir, filename),
148
+ path.join(execDir, filename),
149
+ ]),
150
+ ];
151
+ const compiledCandidates = addonFilenames.flatMap(filename => [
152
+ path.join(versionedDir, filename),
153
+ path.join(userDataDir, filename),
154
+ ]);
155
+ const releaseCandidates = isCompiledBinary ? [...compiledCandidates, ...baseReleaseCandidates] : baseReleaseCandidates;
156
+ const dedupedCandidates = [...new Set(releaseCandidates)];
157
+
158
+ function runCommand(command, args) {
159
+ // removed logger.time
160
+ try {
161
+ const { spawnSync } = require("child_process");
162
+ const result = spawnSync(command, args, { encoding: "utf-8" });
163
+ if (result.error) return null;
164
+ if (result.status !== 0) return null;
165
+ return (result.stdout || "").trim();
166
+ } catch {
167
+ return null;
168
+ }
169
+ }
170
+
171
+ function selectEmbeddedAddonFile() {
172
+ if (!embeddedAddon) return null;
173
+ const defaultFile = embeddedAddon.files.find(file => file.variant === "default") || null;
174
+ if (process.arch !== "x64") return defaultFile || embeddedAddon.files[0] || null;
175
+ if (selectedVariant === "modern") {
176
+ return (
177
+ embeddedAddon.files.find(file => file.variant === "modern") ||
178
+ embeddedAddon.files.find(file => file.variant === "baseline") ||
179
+ null
180
+ );
181
+ }
182
+ return embeddedAddon.files.find(file => file.variant === "baseline") || null;
183
+ }
184
+
185
+ function maybeExtractEmbeddedAddon(errors) {
186
+ if (!isCompiledBinary || !embeddedAddon) return null;
187
+ if (embeddedAddon.platformTag !== platformTag || embeddedAddon.version !== packageVersion) return null;
188
+
189
+ const selectedEmbeddedFile = selectEmbeddedAddonFile();
190
+ if (!selectedEmbeddedFile) return null;
191
+ const targetPath = path.join(versionedDir, selectedEmbeddedFile.filename);
192
+
193
+ try {
194
+ fs.mkdirSync(versionedDir, { recursive: true });
195
+ } catch (err) {
196
+ const message = err instanceof Error ? err.message : String(err);
197
+ errors.push(`embedded addon dir: ${message}`);
198
+ return null;
199
+ }
200
+
201
+ if (fs.existsSync(targetPath)) {
202
+ return targetPath;
203
+ }
204
+
205
+ try {
206
+ const buffer = fs.readFileSync(selectedEmbeddedFile.filePath);
207
+ fs.writeFileSync(targetPath, buffer);
208
+ return targetPath;
209
+ } catch (err) {
210
+ const message = err instanceof Error ? err.message : String(err);
211
+ errors.push(`embedded addon write (${selectedEmbeddedFile.filename}): ${message}`);
212
+ return null;
213
+ }
214
+ }
215
+
216
+ function loadNative() {
217
+ const errors = [];
218
+ const embeddedCandidate = maybeExtractEmbeddedAddon(errors);
219
+ const runtimeCandidates = embeddedCandidate ? [embeddedCandidate, ...dedupedCandidates] : dedupedCandidates;
220
+ for (const candidate of runtimeCandidates) {
221
+ try {
222
+ const bindings = require_(candidate);
223
+ if (process.env.PI_DEV) {
224
+ console.log(`Loaded native addon from ${candidate}`);
225
+ }
226
+ return bindings;
227
+ } catch (err) {
228
+ if (process.env.PI_DEV) {
229
+ console.error(`Error loading native addon from ${candidate}:`, err);
230
+ }
231
+ const message = err instanceof Error ? err.message : String(err);
232
+ errors.push(`${candidate}: ${message}`);
233
+ }
234
+ }
235
+ // Check if this is an unsupported platform
236
+ if (!SUPPORTED_PLATFORMS.includes(platformTag)) {
237
+ throw new Error(
238
+ `Unsupported platform: ${platformTag}\n` +
239
+ `Supported platforms: ${SUPPORTED_PLATFORMS.join(", ")}\n` +
240
+ "If you need support for this platform, please open an issue.",
241
+ );
242
+ }
243
+ const details = errors.map(error => `- ${error}`).join("\n");
244
+ let helpMessage;
245
+ if (isCompiledBinary) {
246
+ const expectedPaths = addonFilenames.map(filename => ` ${path.join(versionedDir, filename)}`).join("\n");
247
+ const downloadHints = addonFilenames
248
+ .map(filename => {
249
+ const downloadUrl = `https://github.com/f5xc-salesdemos/xcsh/releases/latest/download/${filename}`;
250
+ const targetPath = path.join(versionedDir, filename);
251
+ return ` curl -fsSL "${downloadUrl}" -o "${targetPath}"`;
252
+ })
253
+ .join("\n");
254
+ helpMessage =
255
+ `The compiled binary should extract one of:\n${expectedPaths}\n\n` +
256
+ `If missing, delete ${versionedDir} and re-run, or download manually:\n${downloadHints}`;
257
+ } else {
258
+ const platformPkg = PLATFORM_PACKAGE_MAP[platformTag] || `@f5xc-salesdemos/pi-natives-${platformTag}`;
259
+ helpMessage =
260
+ `If installed via npm/bun, ensure the platform package is present:\n` +
261
+ ` npm install ${platformPkg}\n` +
262
+ "If developing locally, build with: bun --cwd=packages/natives run build\n" +
263
+ "Optional x64 variants: TARGET_VARIANT=baseline|modern bun --cwd=packages/natives run build";
264
+ }
265
+
266
+ throw new Error(`Failed to load pi_natives native addon for ${addonLabel}.\n\nTried:\n${details}\n\n${helpMessage}`);
267
+ }
268
+
269
+ module.exports = loadNative();
270
+
271
+ // --- generated const enum exports (do not edit) ---
272
+ module.exports.AstMatchStrictness = {
273
+ Cst: 'cst',
274
+ Smart: 'smart',
275
+ Ast: 'ast',
276
+ Relaxed: 'relaxed',
277
+ Signature: 'signature',
278
+ Template: 'template',
279
+ };
280
+ module.exports.ChunkAnchorStyle = {
281
+ Full: 'full',
282
+ Kind: 'kind',
283
+ Bare: 'bare',
284
+ FullOmit: 'full-omit',
285
+ KindOmit: 'kind-omit',
286
+ None: 'none',
287
+ };
288
+ module.exports.ChunkEditOp = {
289
+ Put: 'put',
290
+ Replace: 'replace',
291
+ Delete: 'delete',
292
+ Before: 'before',
293
+ After: 'after',
294
+ Prepend: 'prepend',
295
+ Append: 'append',
296
+ };
297
+ module.exports.ChunkFocusMode = {
298
+ Expanded: 'expanded',
299
+ Collapsed: 'collapsed',
300
+ Container: 'container',
301
+ };
302
+ module.exports.ChunkReadStatus = {
303
+ Ok: 'ok',
304
+ NotFound: 'not_found',
305
+ UnsupportedRegion: 'unsupported_region',
306
+ };
307
+ module.exports.ChunkRegion = {
308
+ Head: '^',
309
+ Body: '~',
310
+ };
311
+ module.exports.Ellipsis = {
312
+ Unicode: 0,
313
+ Ascii: 1,
314
+ Omit: 2,
315
+ };
316
+ module.exports.FileType = {
317
+ File: 1,
318
+ Dir: 2,
319
+ Symlink: 3,
320
+ };
321
+ module.exports.GrepOutputMode = {
322
+ Content: 'content',
323
+ Count: 'count',
324
+ FilesWithMatches: 'filesWithMatches',
325
+ };
326
+ module.exports.ImageFormat = {
327
+ PNG: 0,
328
+ JPEG: 1,
329
+ WEBP: 2,
330
+ GIF: 3,
331
+ };
332
+ module.exports.KeyEventType = {
333
+ Press: 1,
334
+ Repeat: 2,
335
+ Release: 3,
336
+ };
337
+ module.exports.MacOSAppearance = {
338
+ Dark: 'dark',
339
+ Light: 'light',
340
+ };
341
+ module.exports.SamplingFilter = {
342
+ Nearest: 1,
343
+ Triangle: 2,
344
+ CatmullRom: 3,
345
+ Gaussian: 4,
346
+ Lanczos3: 5,
347
+ };
348
+ // --- end generated const enum exports ---
package/package.json ADDED
@@ -0,0 +1,75 @@
1
+ {
2
+ "name": "@f5-sales-demo/pi-natives",
3
+ "version": "19.51.2",
4
+ "description": "Native Rust bindings for grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
5
+ "homepage": "https://github.com/f5-sales-demo/xcsh",
6
+ "author": "Can Boluk",
7
+ "license": "MIT",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/f5-sales-demo/xcsh.git",
11
+ "directory": "packages/natives"
12
+ },
13
+ "bugs": {
14
+ "url": "https://github.com/f5-sales-demo/xcsh/issues"
15
+ },
16
+ "keywords": [
17
+ "napi",
18
+ "rust",
19
+ "native",
20
+ "grep",
21
+ "text-processing",
22
+ "clipboard",
23
+ "image",
24
+ "pty",
25
+ "shell",
26
+ "syntax-highlighting"
27
+ ],
28
+ "main": "./native/index.js",
29
+ "types": "./native/index.d.ts",
30
+ "scripts": {
31
+ "build": "bun scripts/build-native.ts",
32
+ "check": "biome check . && bun run check:types",
33
+ "check:types": "tsgo -p tsconfig.json --noEmit",
34
+ "lint": "biome lint .",
35
+ "test": "bun run build && bun test",
36
+ "fix": "biome check --write --unsafe .",
37
+ "fmt": "biome format --write .",
38
+ "embed:native": "bun scripts/embed-native.ts",
39
+ "bench": "bun bench/grep.ts"
40
+ },
41
+ "devDependencies": {
42
+ "@napi-rs/cli": "3.6.0",
43
+ "@types/bun": "^1.3"
44
+ },
45
+ "engines": {
46
+ "bun": ">=1.3.7"
47
+ },
48
+ "napi": {
49
+ "binaryName": "pi_natives",
50
+ "triples": {
51
+ "x86_64-unknown-linux-gnu": { "platformArchABI": "linux-x64-gnu" },
52
+ "aarch64-unknown-linux-gnu": { "platformArchABI": "linux-arm64-gnu" },
53
+ "x86_64-apple-darwin": { "platformArchABI": "darwin-x64" },
54
+ "aarch64-apple-darwin": { "platformArchABI": "darwin-arm64" },
55
+ "x86_64-pc-windows-msvc": { "platformArchABI": "win32-x64-msvc" }
56
+ }
57
+ },
58
+ "optionalDependencies": {
59
+ "@f5-sales-demo/pi-natives-linux-x64-gnu": "19.51.2",
60
+ "@f5-sales-demo/pi-natives-linux-arm64-gnu": "19.51.2",
61
+ "@f5-sales-demo/pi-natives-darwin-x64": "19.51.2",
62
+ "@f5-sales-demo/pi-natives-darwin-arm64": "19.51.2",
63
+ "@f5-sales-demo/pi-natives-win32-x64-msvc": "19.51.2"
64
+ },
65
+ "files": [
66
+ "native",
67
+ "README.md"
68
+ ],
69
+ "exports": {
70
+ ".": {
71
+ "types": "./native/index.d.ts",
72
+ "import": "./native/index.js"
73
+ }
74
+ }
75
+ }