1- import * as path from "jsr:@std/path" ;
1+ const BRAND = Symbol ( "divvun-runtime" )
22
3- let libPath : string | null = null ;
3+ let libPath : string | null = await findLib ( ) ;
4+
5+ export function getLibPath ( ) : string | null {
6+ return libPath ;
7+ }
8+
9+ export async function findLib ( ) : Promise < string | null > {
10+ const name = "divvun-runtime"
11+ let pathEnv
12+ try {
13+ pathEnv = Deno . env . get ( "PATH" ) ?? "" ;
14+ } catch ( e ) {
15+ pathEnv = "" ;
16+ }
17+ const paths = pathEnv . split ( Deno . build . os === "windows" ? ";" : ":" ) ;
18+
19+ const exts = Deno . build . os === "windows"
20+ ? ( Deno . env . get ( "PATHEXT" ) ?. split ( ";" ) ?? [ ".EXE" , ".CMD" , ".BAT" ] )
21+ : [ "" ] ;
22+
23+ for ( const dir of paths ) {
24+ for ( const ext of exts ) {
25+ const full = `${ dir } /${ name } ${ ext } ` ;
26+ try {
27+ const info = await Deno . stat ( full ) ;
28+ if ( info . isFile ) return full ;
29+ } catch {
30+ // ignore ENOENT
31+ }
32+ }
33+ }
34+ return null ;
35+ }
436
537export function setLibPath ( newPath : string ) {
638 libPath = newPath ;
@@ -11,24 +43,11 @@ let dylib: Deno.DynamicLibrary<Record<string, Deno.ForeignFunction>>;
1143const RustSliceT = { "struct" : [ "pointer" , "usize" ] } as const ;
1244
1345function loadDylib ( ) {
14- let libSuffix = "" ;
15-
16- switch ( Deno . build . os ) {
17- case "windows" :
18- libSuffix = "dll" ;
19- break ;
20- case "darwin" :
21- libSuffix = "dylib" ;
22- break ;
23- default :
24- libSuffix = "so" ;
25- break ;
46+ if ( libPath == null ) {
47+ throw new Error ( "Could not find divvun-runtime library. Please set the path using setLibPath()." ) ;
2648 }
2749
28- const libName = `libdivvun_runtime.${ libSuffix } ` ;
29- const fullLibPath = libPath ? path . join ( libPath , libName ) : libName ;
30-
31- dylib = Deno . dlopen ( fullLibPath , {
50+ dylib = Deno . dlopen ( libPath , {
3251 DRT_Bundle_fromBundle : {
3352 parameters : [ RustSliceT , "function" ] ,
3453 result : "pointer" ,
@@ -93,7 +112,7 @@ export class Bundle {
93112 errCallback . pointer ,
94113 ) as Deno . PointerValue < Bundle > ;
95114
96- return new Bundle ( bundleRawPtr ) ;
115+ return new Bundle ( bundleRawPtr , BRAND ) ;
97116 } catch ( e ) {
98117 throw e ;
99118 }
@@ -112,13 +131,16 @@ export class Bundle {
112131 errCallback . pointer ,
113132 ) as Deno . PointerValue < Bundle > ;
114133
115- return new Bundle ( bundleRawPtr ) ;
134+ return new Bundle ( bundleRawPtr , BRAND ) ;
116135 } catch ( e ) {
117136 throw e ;
118137 }
119138 }
120139
121- private constructor ( ptr : Deno . PointerValue ) {
140+ private constructor ( ptr : Deno . PointerValue , brand : symbol ) {
141+ if ( brand !== BRAND ) {
142+ throw new TypeError ( "Bundle must be constructed via fromPath or fromBundle" ) ;
143+ }
122144 this . #ptr = ptr ;
123145 }
124146
@@ -145,7 +167,7 @@ export class Bundle {
145167 errCallback . pointer ,
146168 ) as Deno . PointerValue < PipelineHandle > ;
147169
148- return new PipelineHandle ( pipeRawPtr ) ;
170+ return new PipelineHandle ( pipeRawPtr , BRAND ) ;
149171 } catch ( e ) {
150172 throw e ;
151173 }
@@ -157,7 +179,11 @@ class PipelineResponse {
157179 #ptr: Deno . PointerValue ;
158180 #len: number ;
159181
160- constructor ( buf : Uint8Array ) {
182+ constructor ( buf : Uint8Array , brand : symbol ) {
183+ if ( brand !== BRAND ) {
184+ throw new TypeError ( "PipelineResponse cannot be constructed directly" ) ;
185+ }
186+
161187 this . #buf = buf ;
162188
163189 const ptr = Deno . UnsafePointer . of ( buf ) ;
@@ -220,7 +246,11 @@ class PipelineResponse {
220246export class PipelineHandle {
221247 #ptr: Deno . PointerValue ;
222248
223- constructor ( ptr : Deno . PointerValue ) {
249+ constructor ( ptr : Deno . PointerValue , brand : symbol ) {
250+ if ( brand !== BRAND ) {
251+ throw new TypeError ( "PipelineHandle cannot be constructed directly" ) ;
252+ }
253+
224254 this . #ptr = ptr ;
225255 }
226256
@@ -244,7 +274,7 @@ export class PipelineHandle {
244274 rsInput ,
245275 errCallback . pointer ,
246276 ) as Uint8Array ;
247- return new PipelineResponse ( outputSlice ) ;
277+ return new PipelineResponse ( outputSlice , BRAND ) ;
248278 } catch ( e ) {
249279 throw e ;
250280 }
0 commit comments