@gajae-code/natives 0.11.6 → 0.11.8
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/native/index.d.ts +115 -7
- package/native/index.js +4 -1
- package/native/loader-state.d.ts +25 -1
- package/native/loader-state.js +80 -68
- package/package.json +6 -6
package/native/index.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
/* auto-generated by NAPI-RS */
|
|
2
2
|
/* eslint-disable */
|
|
3
|
+
/**
|
|
4
|
+
* macOS computer-use controller.
|
|
5
|
+
*
|
|
6
|
+
* This declaration and the named JS export are available on every platform so
|
|
7
|
+
* consumers can import them portably; the native controller itself is built
|
|
8
|
+
* only on macOS.
|
|
9
|
+
*/
|
|
3
10
|
export declare class ComputerController {
|
|
4
11
|
constructor()
|
|
5
12
|
screenshot(): ComputerScreenshot
|
|
@@ -201,6 +208,11 @@ export declare class NotificationServer {
|
|
|
201
208
|
* Fails if not started or `frame_json` is not a valid `ServerMessage`.
|
|
202
209
|
*/
|
|
203
210
|
pushFrame(frameJson: string): void
|
|
211
|
+
/**
|
|
212
|
+
* Deliver a frame through every authenticated connection and wait for each
|
|
213
|
+
* socket writer to settle within `timeout_ms`.
|
|
214
|
+
*/
|
|
215
|
+
pushFrameAndWait(frameJson: string, timeoutMs: number): Promise<boolean>
|
|
204
216
|
/**
|
|
205
217
|
* Broadcast a TypeScript-constructed turn frame without re-parsing JSON.
|
|
206
218
|
* External frames must continue through [`Self::push_frame`] for serde
|
|
@@ -386,7 +398,7 @@ export declare class RecoveryFsRoot {
|
|
|
386
398
|
*/
|
|
387
399
|
appendManaged(relativePath: string, data: Uint8Array, expectedDev: string, expectedIno: string, expectedSize: string, expectedMtimeNs: string, expectedCtimeNs: string, expectedSha256: string): RecoveryFsResult
|
|
388
400
|
/** Remove one exact managed regular file through retained authority. */
|
|
389
|
-
removeManaged(relativePath: string, expectedDev: string, expectedIno: string, expectedSize: string, expectedMtimeNs: string, expectedCtimeNs: string, expectedSha256: string):
|
|
401
|
+
removeManaged(relativePath: string, expectedDev: string, expectedIno: string, expectedSize: string, expectedMtimeNs: string, expectedCtimeNs: string, expectedSha256: string): RecoveryFsRetainedCleanupResult
|
|
390
402
|
/**
|
|
391
403
|
* Create each absent directory component beneath the retained root with
|
|
392
404
|
* owner-only security. Existing components are re-opened no-follow.
|
|
@@ -397,22 +409,22 @@ export declare class RecoveryFsRoot {
|
|
|
397
409
|
* retained root. The source identity is rechecked after the no-replace
|
|
398
410
|
* rename, and the move is rolled back on a mismatch.
|
|
399
411
|
*/
|
|
400
|
-
renameManagedFileNoReplace(sourceRelativePath: string, destinationRelativePath: string, expectedDev: string, expectedIno: string, expectedSize: string, expectedMtimeNs: string, expectedCtimeNs: string, expectedSha256: string):
|
|
412
|
+
renameManagedFileNoReplace(sourceRelativePath: string, destinationRelativePath: string, expectedDev: string, expectedIno: string, expectedSize: string, expectedMtimeNs: string, expectedCtimeNs: string, expectedSha256: string): RecoveryFsPublishResult
|
|
401
413
|
/** Snapshot a managed directory tree entirely through the retained root. */
|
|
402
414
|
snapshotManagedTree(relativePath: string): NativeDirectoryTreeResult
|
|
403
415
|
/**
|
|
404
416
|
* Move an exact managed directory tree to an absent name through retained
|
|
405
417
|
* authority.
|
|
406
418
|
*/
|
|
407
|
-
renameManagedTreeNoReplace(sourceRelativePath: string, destinationRelativePath: string, expected: NativeDirectoryTreeSnapshot):
|
|
419
|
+
renameManagedTreeNoReplace(sourceRelativePath: string, destinationRelativePath: string, expected: NativeDirectoryTreeSnapshot): RecoveryFsPublishResult
|
|
408
420
|
/** Remove an exact managed directory tree through retained authority. */
|
|
409
|
-
removeManagedTree(relativePath: string, expected: NativeDirectoryTreeSnapshot):
|
|
421
|
+
removeManagedTree(relativePath: string, expected: NativeDirectoryTreeSnapshot): RecoveryFsRetainedCleanupResult
|
|
410
422
|
/**
|
|
411
423
|
* Atomically install an already-created regular file at an absent name.
|
|
412
424
|
* Both names remain relative to this retained root and are never resolved
|
|
413
425
|
* through a pathname after their parent descriptors are acquired.
|
|
414
426
|
*/
|
|
415
|
-
install(sourceRelativePath: string, destinationRelativePath: string):
|
|
427
|
+
install(sourceRelativePath: string, destinationRelativePath: string): RecoveryFsPublishResult
|
|
416
428
|
/**
|
|
417
429
|
* Synchronize the retained root directory, making a preceding create or
|
|
418
430
|
* install durable when the filesystem supports directory fsync.
|
|
@@ -452,6 +464,15 @@ export declare class Shell {
|
|
|
452
464
|
abort(): Promise<void>
|
|
453
465
|
}
|
|
454
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Publish-result wire-contract sentinel.
|
|
469
|
+
*
|
|
470
|
+
* The loader requires this in addition to the release sentinel, so a
|
|
471
|
+
* same-version modern artifact built before the retained-publish contract
|
|
472
|
+
* cannot be selected over a compatible baseline.
|
|
473
|
+
*/
|
|
474
|
+
export declare function __piNativesPublishOutcomeV1(): void
|
|
475
|
+
|
|
455
476
|
/**
|
|
456
477
|
* Version sentinel — exists solely so the JS loader can prove at load time
|
|
457
478
|
* that the `.node` file on disk is from the same package release as the
|
|
@@ -470,7 +491,7 @@ export declare class Shell {
|
|
|
470
491
|
* `packages/natives/native/index.js` (which derives the name from
|
|
471
492
|
* `package.json#version`).
|
|
472
493
|
*/
|
|
473
|
-
export declare function
|
|
494
|
+
export declare function __piNativesV0_11_8(): void
|
|
474
495
|
|
|
475
496
|
/**
|
|
476
497
|
* Apply conservative pre-execution rewrites to a bash command.
|
|
@@ -1720,6 +1741,18 @@ export interface NativeExactUnlinkResult {
|
|
|
1720
1741
|
retainedUnknownPath?: string
|
|
1721
1742
|
}
|
|
1722
1743
|
|
|
1744
|
+
/** Dedicated result for an atomic no-replace namespace publication. */
|
|
1745
|
+
export interface NativeNoReplaceResult {
|
|
1746
|
+
ok: boolean
|
|
1747
|
+
code?: string
|
|
1748
|
+
mutationState: string
|
|
1749
|
+
durabilityState: string
|
|
1750
|
+
reason: string
|
|
1751
|
+
primitive: string
|
|
1752
|
+
phase: string
|
|
1753
|
+
diagnostic: NativePublishDiagnostic
|
|
1754
|
+
}
|
|
1755
|
+
|
|
1723
1756
|
/** Result of applying or checking owner-only path security. */
|
|
1724
1757
|
export type NativeOwnerOnlySecurityResult =
|
|
1725
1758
|
| {
|
|
@@ -1950,6 +1983,38 @@ export interface RecoveryFsIdentity {
|
|
|
1950
1983
|
sha256?: string
|
|
1951
1984
|
}
|
|
1952
1985
|
|
|
1986
|
+
/** Bounded, path-free diagnostic evidence for one retained publication. */
|
|
1987
|
+
export interface RecoveryFsPublishDiagnostic {
|
|
1988
|
+
schemaVersion: number
|
|
1989
|
+
collectionState: string
|
|
1990
|
+
osCode?: number
|
|
1991
|
+
syncFailures?: Array<RecoveryFsPublishSyncFailure>
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1994
|
+
/**
|
|
1995
|
+
* Explicit mutation and durability outcome for retained no-replace
|
|
1996
|
+
* publication.
|
|
1997
|
+
*/
|
|
1998
|
+
export interface RecoveryFsPublishResult {
|
|
1999
|
+
ok: boolean
|
|
2000
|
+
code?: string
|
|
2001
|
+
identity?: RecoveryFsIdentity
|
|
2002
|
+
mutationState: string
|
|
2003
|
+
durabilityState: string
|
|
2004
|
+
reason: string
|
|
2005
|
+
primitive: string
|
|
2006
|
+
phase: string
|
|
2007
|
+
diagnostic: RecoveryFsPublishDiagnostic
|
|
2008
|
+
}
|
|
2009
|
+
|
|
2010
|
+
/** Bounded, path-free diagnostic evidence for one retained publication. */
|
|
2011
|
+
export interface RecoveryFsPublishSyncFailure {
|
|
2012
|
+
phase: string
|
|
2013
|
+
parentRole: string
|
|
2014
|
+
osCode?: number
|
|
2015
|
+
kind: string
|
|
2016
|
+
}
|
|
2017
|
+
|
|
1953
2018
|
export interface RecoveryFsResult {
|
|
1954
2019
|
ok: boolean
|
|
1955
2020
|
code?: string
|
|
@@ -1957,7 +2022,28 @@ export interface RecoveryFsResult {
|
|
|
1957
2022
|
data?: Uint8Array
|
|
1958
2023
|
}
|
|
1959
2024
|
|
|
1960
|
-
|
|
2025
|
+
/**
|
|
2026
|
+
* Fail-closed outcome for a removal whose detached object remains retained.
|
|
2027
|
+
* `recovery_path` identifies evidence only; it grants no authority to replay
|
|
2028
|
+
* or delete the retained object.
|
|
2029
|
+
*/
|
|
2030
|
+
export interface RecoveryFsRetainedCleanupResult {
|
|
2031
|
+
ok: boolean
|
|
2032
|
+
code?: string
|
|
2033
|
+
recoveryPath?: string
|
|
2034
|
+
identity?: RecoveryFsIdentity
|
|
2035
|
+
treeSnapshot?: NativeDirectoryTreeSnapshot
|
|
2036
|
+
}
|
|
2037
|
+
|
|
2038
|
+
export declare function renameNoReplacePath(sourcePath: string, destinationPath: string): NativeNoReplaceResult
|
|
2039
|
+
|
|
2040
|
+
/**
|
|
2041
|
+
* Repair an owner-only ACL on a retained expected path.
|
|
2042
|
+
*
|
|
2043
|
+
* Its no-follow handle must still identify the expected object before repair
|
|
2044
|
+
* and again after final ACL verification.
|
|
2045
|
+
*/
|
|
2046
|
+
export declare function repairOwnerOnlyPathSecurityExpected(path: string, kind: "directory" | "file", expectedDev: bigint, expectedIno: bigint): NativeOwnerOnlySecurityResult
|
|
1961
2047
|
|
|
1962
2048
|
/** A client reply forwarded to the TypeScript host for gate resolution. */
|
|
1963
2049
|
export interface ReplyEvent {
|
|
@@ -2187,6 +2273,12 @@ export declare function verifyOwnerOnlyFdSecurity(path: string, kind: "directory
|
|
|
2187
2273
|
|
|
2188
2274
|
export declare function verifyOwnerOnlyPathSecurity(path: string, kind: "directory" | "file"): NativeOwnerOnlySecurityResult
|
|
2189
2275
|
|
|
2276
|
+
/**
|
|
2277
|
+
* Verify owner-only ACL security without mutation only when the retained
|
|
2278
|
+
* no-follow handle identifies the expected object before and after inspection.
|
|
2279
|
+
*/
|
|
2280
|
+
export declare function verifyOwnerOnlyPathSecurityExpected(path: string, kind: "directory" | "file", expectedDev: bigint, expectedIno: bigint): NativeOwnerOnlySecurityResult
|
|
2281
|
+
|
|
2190
2282
|
/**
|
|
2191
2283
|
* Calculate visible width of text, excluding ANSI escape sequences.
|
|
2192
2284
|
*
|
|
@@ -2218,3 +2310,19 @@ export interface WorkProfile {
|
|
|
2218
2310
|
* Returns UTF-16 lines with active SGR codes carried across line boundaries.
|
|
2219
2311
|
*/
|
|
2220
2312
|
export declare function wrapTextWithAnsi(text: string, width: number, tabWidth: number): Array<string>
|
|
2313
|
+
|
|
2314
|
+
/** Bounded, path-free evidence for a parent-directory durability failure. */
|
|
2315
|
+
export interface NativePublishSyncFailure {
|
|
2316
|
+
phase: string
|
|
2317
|
+
parentRole: string
|
|
2318
|
+
osCode: number
|
|
2319
|
+
kind: string
|
|
2320
|
+
}
|
|
2321
|
+
|
|
2322
|
+
/** Bounded, path-free evidence for one atomic publication. */
|
|
2323
|
+
export interface NativePublishDiagnostic {
|
|
2324
|
+
schemaVersion: number
|
|
2325
|
+
collectionState: string
|
|
2326
|
+
osCode?: number
|
|
2327
|
+
syncFailures?: Array<NativePublishSyncFailure>
|
|
2328
|
+
}
|
package/native/index.js
CHANGED
|
@@ -29,7 +29,8 @@ export const RecoveryFsRoot = nativeBindings.RecoveryFsRoot;
|
|
|
29
29
|
export const Shell = nativeBindings.Shell;
|
|
30
30
|
|
|
31
31
|
// functions
|
|
32
|
-
export const
|
|
32
|
+
export const __piNativesPublishOutcomeV1 = nativeBindings.__piNativesPublishOutcomeV1;
|
|
33
|
+
export const __piNativesV0_11_8 = nativeBindings.__piNativesV0_11_8;
|
|
33
34
|
export const applyBashFixups = nativeBindings.applyBashFixups;
|
|
34
35
|
export const applyOwnerOnlyFdSecurity = nativeBindings.applyOwnerOnlyFdSecurity;
|
|
35
36
|
export const applyOwnerOnlyPathSecurity = nativeBindings.applyOwnerOnlyPathSecurity;
|
|
@@ -77,6 +78,7 @@ export const parseKittySequence = nativeBindings.parseKittySequence;
|
|
|
77
78
|
export const ptyTimeoutCount = nativeBindings.ptyTimeoutCount;
|
|
78
79
|
export const readImageFromClipboard = nativeBindings.readImageFromClipboard;
|
|
79
80
|
export const renameNoReplacePath = nativeBindings.renameNoReplacePath;
|
|
81
|
+
export const repairOwnerOnlyPathSecurityExpected = nativeBindings.repairOwnerOnlyPathSecurityExpected;
|
|
80
82
|
export const retainBrokerPublication = nativeBindings.retainBrokerPublication;
|
|
81
83
|
export const search = nativeBindings.search;
|
|
82
84
|
export const sliceWithWidth = nativeBindings.sliceWithWidth;
|
|
@@ -87,6 +89,7 @@ export const truncateLinesToWidth = nativeBindings.truncateLinesToWidth;
|
|
|
87
89
|
export const truncateToWidth = nativeBindings.truncateToWidth;
|
|
88
90
|
export const verifyOwnerOnlyFdSecurity = nativeBindings.verifyOwnerOnlyFdSecurity;
|
|
89
91
|
export const verifyOwnerOnlyPathSecurity = nativeBindings.verifyOwnerOnlyPathSecurity;
|
|
92
|
+
export const verifyOwnerOnlyPathSecurityExpected = nativeBindings.verifyOwnerOnlyPathSecurityExpected;
|
|
90
93
|
export const visibleWidth = nativeBindings.visibleWidth;
|
|
91
94
|
export const visibleWidths = nativeBindings.visibleWidths;
|
|
92
95
|
export const wrapTextWithAnsi = nativeBindings.wrapTextWithAnsi;
|
package/native/loader-state.d.ts
CHANGED
|
@@ -79,4 +79,28 @@ export interface CachedEmbeddedExtractionIsFreshInput {
|
|
|
79
79
|
|
|
80
80
|
export function cachedEmbeddedExtractionIsFresh(input: CachedEmbeddedExtractionIsFreshInput): boolean;
|
|
81
81
|
|
|
82
|
-
export
|
|
82
|
+
export interface LoaderContext {
|
|
83
|
+
isCompiledBinary: boolean;
|
|
84
|
+
platformTag: string;
|
|
85
|
+
packageVersion?: string;
|
|
86
|
+
addonLabel?: string;
|
|
87
|
+
addonFilenames?: string[];
|
|
88
|
+
versionedDir?: string;
|
|
89
|
+
candidates?: string[];
|
|
90
|
+
selectedVariant?: "modern" | "baseline" | null;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function embeddedAddonIsAuthoritative(
|
|
94
|
+
ctx: LoaderContext,
|
|
95
|
+
addon?: EmbeddedAddon | null,
|
|
96
|
+
): boolean;
|
|
97
|
+
|
|
98
|
+
export interface LoadNativeOptions {
|
|
99
|
+
context?: LoaderContext;
|
|
100
|
+
extractEmbeddedAddons?: (ctx: LoaderContext) => string[];
|
|
101
|
+
stageNodeModulesAddon?: () => string | null;
|
|
102
|
+
requireCandidate?: (candidate: string) => Record<string, unknown>;
|
|
103
|
+
validateCandidate?: (bindings: Record<string, unknown>) => void;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function loadNative(options?: LoadNativeOptions): Record<string, unknown>;
|
package/native/loader-state.js
CHANGED
|
@@ -306,64 +306,56 @@ function resolveCpuVariant(override) {
|
|
|
306
306
|
return detectAvx2Support() ? "modern" : "baseline";
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
function
|
|
310
|
-
if (!embeddedAddon) return
|
|
311
|
-
const
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
return embeddedAddon.files.find(file => file.variant === "baseline") || null;
|
|
309
|
+
function embeddedAddonCandidates(selectedVariant) {
|
|
310
|
+
if (!embeddedAddon) return [];
|
|
311
|
+
const files = embeddedAddon.files;
|
|
312
|
+
const candidates = process.arch !== "x64"
|
|
313
|
+
? [files.find(file => file.variant === "default"), ...files]
|
|
314
|
+
: selectedVariant === "modern"
|
|
315
|
+
? [files.find(file => file.variant === "modern"), files.find(file => file.variant === "baseline")]
|
|
316
|
+
: [files.find(file => file.variant === "baseline")];
|
|
317
|
+
return [...new Set(candidates.filter(Boolean))];
|
|
321
318
|
}
|
|
322
319
|
|
|
323
|
-
function
|
|
324
|
-
if (!ctx.isCompiledBinary || !embeddedAddon) return
|
|
325
|
-
if (embeddedAddon.platformTag !== ctx.platformTag || embeddedAddon.version !== ctx.packageVersion) return
|
|
326
|
-
|
|
327
|
-
const
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
320
|
+
function maybeExtractEmbeddedAddons(ctx, errors) {
|
|
321
|
+
if (!ctx.isCompiledBinary || !embeddedAddon) return [];
|
|
322
|
+
if (embeddedAddon.platformTag !== ctx.platformTag || embeddedAddon.version !== ctx.packageVersion) return [];
|
|
323
|
+
|
|
324
|
+
const extracted = [];
|
|
325
|
+
for (const embeddedFile of embeddedAddonCandidates(ctx.selectedVariant)) {
|
|
326
|
+
const targetPath = path.join(ctx.versionedDir, embeddedFile.filename);
|
|
327
|
+
if (fs.existsSync(targetPath)) {
|
|
328
|
+
// Guard against intra-version drift: a cached extraction written by an earlier
|
|
329
|
+
// build of the same version carries the same version sentinel but can expose a
|
|
330
|
+
// different native surface (e.g. a symbol added mid-cycle). The embedded addon
|
|
331
|
+
// is the source of truth, so reuse the cached file only when it matches the
|
|
332
|
+
// embedded payload size and re-extract otherwise.
|
|
333
|
+
const sizeOf = candidate => {
|
|
334
|
+
try {
|
|
335
|
+
return fs.statSync(candidate).size;
|
|
336
|
+
} catch {
|
|
337
|
+
return null;
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
if (cachedEmbeddedExtractionIsFresh({ targetPath, embeddedPath: embeddedFile.filePath, sizeOf })) {
|
|
341
|
+
extracted.push(targetPath);
|
|
342
|
+
continue;
|
|
341
343
|
}
|
|
342
|
-
};
|
|
343
|
-
if (cachedEmbeddedExtractionIsFresh({ targetPath, embeddedPath: selectedEmbeddedFile.filePath, sizeOf })) {
|
|
344
|
-
return targetPath;
|
|
345
344
|
}
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
try {
|
|
349
|
-
fs.mkdirSync(ctx.versionedDir, { recursive: true });
|
|
350
|
-
} catch (err) {
|
|
351
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
352
|
-
errors.push(`embedded addon dir: ${message}`);
|
|
353
|
-
return null;
|
|
354
|
-
}
|
|
355
345
|
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
346
|
+
try {
|
|
347
|
+
fs.mkdirSync(ctx.versionedDir, { recursive: true });
|
|
348
|
+
const buffer = fs.readFileSync(embeddedFile.filePath);
|
|
349
|
+
const tempPath = `${targetPath}.tmp.${process.pid}`;
|
|
350
|
+
fs.writeFileSync(tempPath, buffer);
|
|
351
|
+
fs.renameSync(tempPath, targetPath);
|
|
352
|
+
extracted.push(targetPath);
|
|
353
|
+
} catch (err) {
|
|
354
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
355
|
+
errors.push(`embedded addon write (${embeddedFile.filename}): ${message}`);
|
|
356
|
+
}
|
|
366
357
|
}
|
|
358
|
+
return extracted;
|
|
367
359
|
}
|
|
368
360
|
|
|
369
361
|
/**
|
|
@@ -410,12 +402,22 @@ function maybeStageNodeModulesAddon(ctx, errors) {
|
|
|
410
402
|
}
|
|
411
403
|
|
|
412
404
|
function validateLoadedBindings(ctx, bindings, candidate) {
|
|
413
|
-
if (typeof bindings[ctx.versionSentinelExport]
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
405
|
+
if (typeof bindings[ctx.versionSentinelExport] !== "function") {
|
|
406
|
+
throw new Error(
|
|
407
|
+
`Loaded ${candidate} but it does not expose the @gajae-code/natives@${ctx.packageVersion} ` +
|
|
408
|
+
`version sentinel \`${ctx.versionSentinelExport}\`. The .node file on disk is from a different ` +
|
|
409
|
+
"release than this loader — reinstall to re-sync.",
|
|
410
|
+
);
|
|
411
|
+
}
|
|
412
|
+
if (typeof bindings.__piNativesPublishOutcomeV1 !== "function") {
|
|
413
|
+
throw new Error(
|
|
414
|
+
`Loaded ${candidate} but it lacks retained-publish capability sentinel ` +
|
|
415
|
+
"`__piNativesPublishOutcomeV1`; trying the next compatible artifact.",
|
|
416
|
+
);
|
|
417
|
+
}
|
|
418
|
+
if (typeof bindings.renameNoReplacePath !== "function") {
|
|
419
|
+
throw new Error(`Loaded ${candidate} but it lacks required atomic publish capability \`renameNoReplacePath\`.`);
|
|
420
|
+
}
|
|
419
421
|
}
|
|
420
422
|
|
|
421
423
|
function buildHelpMessage(ctx) {
|
|
@@ -516,20 +518,30 @@ function initLoaderContext(require_) {
|
|
|
516
518
|
};
|
|
517
519
|
}
|
|
518
520
|
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
521
|
+
/** Embedded standalone payloads are the complete trust boundary for their matching build. */
|
|
522
|
+
export function embeddedAddonIsAuthoritative(ctx, addon = embeddedAddon) {
|
|
523
|
+
return (
|
|
524
|
+
ctx.isCompiledBinary && addon?.platformTag === ctx.platformTag && addon.version === ctx.packageVersion
|
|
525
|
+
);
|
|
526
|
+
}
|
|
522
527
|
|
|
523
|
-
|
|
524
|
-
const
|
|
525
|
-
const
|
|
526
|
-
const prepended = [embeddedCandidate, stagedCandidate].filter(c => typeof c === "string");
|
|
527
|
-
const runtimeCandidates = prepended.length > 0 ? [...prepended, ...ctx.candidates] : ctx.candidates;
|
|
528
|
+
export function loadNative(options = {}) {
|
|
529
|
+
const require_ = options.requireCandidate ? null : createRequire(import.meta.url);
|
|
530
|
+
const ctx = options.context ?? initLoaderContext(require_);
|
|
528
531
|
|
|
532
|
+
const errors = [];
|
|
533
|
+
const embeddedCandidates = (options.extractEmbeddedAddons ?? maybeExtractEmbeddedAddons)(ctx, errors);
|
|
534
|
+
const embeddedIsAuthoritative = embeddedAddonIsAuthoritative(ctx);
|
|
535
|
+
const stagedCandidate =
|
|
536
|
+
embeddedCandidates.length > 0 || embeddedIsAuthoritative
|
|
537
|
+
? null
|
|
538
|
+
: (options.stageNodeModulesAddon ?? maybeStageNodeModulesAddon)(ctx, errors);
|
|
539
|
+
const prepended = [...embeddedCandidates, stagedCandidate].filter(c => typeof c === "string");
|
|
540
|
+
const runtimeCandidates = embeddedIsAuthoritative ? prepended : prepended.length > 0 ? [...prepended, ...ctx.candidates] : ctx.candidates;
|
|
529
541
|
const loaded = loadFromCandidates({
|
|
530
542
|
candidates: runtimeCandidates,
|
|
531
|
-
requireCandidate: candidate => require_(candidate),
|
|
532
|
-
validateCandidate: (bindings, candidate) => validateLoadedBindings(ctx, bindings, candidate),
|
|
543
|
+
requireCandidate: options.requireCandidate ?? (candidate => require_(candidate)),
|
|
544
|
+
validateCandidate: options.validateCandidate ?? ((bindings, candidate) => validateLoadedBindings(ctx, bindings, candidate)),
|
|
533
545
|
describeCandidate: candidate => candidate,
|
|
534
546
|
});
|
|
535
547
|
if (loaded.bindings) return loaded.bindings;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gajae-code/natives",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.8",
|
|
4
4
|
"description": "Native Rust bindings for grep, clipboard, image processing, syntax highlighting, PTY, and shell operations via N-API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"homepage": "https://gajae-code.com",
|
|
@@ -61,11 +61,11 @@
|
|
|
61
61
|
"README.md"
|
|
62
62
|
],
|
|
63
63
|
"optionalDependencies": {
|
|
64
|
-
"@gajae-code/natives-darwin-arm64": "0.11.
|
|
65
|
-
"@gajae-code/natives-darwin-x64": "0.11.
|
|
66
|
-
"@gajae-code/natives-linux-arm64": "0.11.
|
|
67
|
-
"@gajae-code/natives-linux-x64": "0.11.
|
|
68
|
-
"@gajae-code/natives-win32-x64": "0.11.
|
|
64
|
+
"@gajae-code/natives-darwin-arm64": "0.11.8",
|
|
65
|
+
"@gajae-code/natives-darwin-x64": "0.11.8",
|
|
66
|
+
"@gajae-code/natives-linux-arm64": "0.11.8",
|
|
67
|
+
"@gajae-code/natives-linux-x64": "0.11.8",
|
|
68
|
+
"@gajae-code/natives-win32-x64": "0.11.8"
|
|
69
69
|
},
|
|
70
70
|
"exports": {
|
|
71
71
|
".": {
|