99
1010namespace Motely . BrowserWasm ;
1111
12+ /// <summary>
13+ /// Static [JSExport] dispatch layer. Instance methods route through an int handle.
14+ /// JS callers: createInstance() → id, then pass id to search/analyze/stop/destroy.
15+ /// </summary>
1216[ SupportedOSPlatform ( "browser" ) ]
1317public static partial class MotelyWasmExports
1418{
15- private static CancellationTokenSource ? _activeCts ;
19+ // ── Instance lifecycle ──
1620
17- // ── SEARCH ──
21+ [ JSExport ]
22+ public static int CreateInstance ( ) => MotelyInstance . Create ( ) ;
23+
24+ [ JSExport ]
25+ public static void DestroyInstance ( int id ) => MotelyInstance . Destroy ( id ) ;
26+
27+ // ── Search (all instance-scoped) ──
1828
1929 [ JSExport ]
2030 public static Task < string > StartJamlSearch (
21- string jamlContent , int threadCount , int batchCharCount ,
31+ int instanceId , string jamlContent , int threadCount , int batchCharCount ,
2232 int startBatch , int endBatch ,
2333 [ JSMarshalAs < JSType . Function < JSType . Number , JSType . Number , JSType . Number > > ] Action < long , long , long > onProgress ,
2434 [ JSMarshalAs < JSType . Function < JSType . String , JSType . Number > > ] Action < string , int > onResult )
25- => RunSearch ( jamlContent , new MotelySearchRequest
35+ => RunSearch ( instanceId , jamlContent , new MotelySearchRequest
2636 {
2737 ThreadCount = ResolveThreads ( threadCount ) ,
2838 BatchCharCount = ResolveBatch ( batchCharCount ) ,
@@ -32,11 +42,11 @@ public static Task<string> StartJamlSearch(
3242
3343 [ JSExport ]
3444 public static Task < string > StartSeedListSearch (
35- string jamlContent , int threadCount , int batchCharCount ,
45+ int instanceId , string jamlContent , int threadCount , int batchCharCount ,
3646 [ JSMarshalAs < JSType . Array < JSType . String > > ] string [ ] seeds ,
3747 [ JSMarshalAs < JSType . Function < JSType . Number , JSType . Number , JSType . Number > > ] Action < long , long , long > onProgress ,
3848 [ JSMarshalAs < JSType . Function < JSType . String , JSType . Number > > ] Action < string , int > onResult )
39- => RunSearch ( jamlContent , new MotelySearchRequest
49+ => RunSearch ( instanceId , jamlContent , new MotelySearchRequest
4050 {
4151 ThreadCount = ResolveThreads ( threadCount ) ,
4252 BatchCharCount = ResolveBatch ( batchCharCount ) ,
@@ -45,11 +55,11 @@ public static Task<string> StartSeedListSearch(
4555
4656 [ JSExport ]
4757 public static Task < string > StartKeywordSearch (
48- string jamlContent , int threadCount , int batchCharCount ,
58+ int instanceId , string jamlContent , int threadCount , int batchCharCount ,
4959 [ JSMarshalAs < JSType . Array < JSType . String > > ] string [ ] keywords , string padding ,
5060 [ JSMarshalAs < JSType . Function < JSType . Number , JSType . Number , JSType . Number > > ] Action < long , long , long > onProgress ,
5161 [ JSMarshalAs < JSType . Function < JSType . String , JSType . Number > > ] Action < string , int > onResult )
52- => RunSearch ( jamlContent , new MotelySearchRequest
62+ => RunSearch ( instanceId , jamlContent , new MotelySearchRequest
5363 {
5464 ThreadCount = ResolveThreads ( threadCount ) ,
5565 BatchCharCount = ResolveBatch ( batchCharCount ) ,
@@ -59,10 +69,10 @@ public static Task<string> StartKeywordSearch(
5969
6070 [ JSExport ]
6171 public static Task < string > StartRandomSearch (
62- string jamlContent , int threadCount , int batchCharCount , int count ,
72+ int instanceId , string jamlContent , int threadCount , int batchCharCount , int count ,
6373 [ JSMarshalAs < JSType . Function < JSType . Number , JSType . Number , JSType . Number > > ] Action < long , long , long > onProgress ,
6474 [ JSMarshalAs < JSType . Function < JSType . String , JSType . Number > > ] Action < string , int > onResult )
65- => RunSearch ( jamlContent , new MotelySearchRequest
75+ => RunSearch ( instanceId , jamlContent , new MotelySearchRequest
6676 {
6777 ThreadCount = ResolveThreads ( threadCount ) ,
6878 BatchCharCount = ResolveBatch ( batchCharCount ) ,
@@ -71,28 +81,29 @@ public static Task<string> StartRandomSearch(
7181
7282 [ JSExport ]
7383 public static Task < string > StartPalindromeSearch (
74- string jamlContent , int threadCount , int batchCharCount ,
84+ int instanceId , string jamlContent , int threadCount , int batchCharCount ,
7585 [ JSMarshalAs < JSType . Function < JSType . Number , JSType . Number , JSType . Number > > ] Action < long , long , long > onProgress ,
7686 [ JSMarshalAs < JSType . Function < JSType . String , JSType . Number > > ] Action < string , int > onResult )
77- => RunSearch ( jamlContent , new MotelySearchRequest
87+ => RunSearch ( instanceId , jamlContent , new MotelySearchRequest
7888 {
7989 ThreadCount = ResolveThreads ( threadCount ) ,
8090 BatchCharCount = ResolveBatch ( batchCharCount ) ,
8191 Palindrome = true ,
8292 } , onProgress , onResult ) ;
8393
8494 [ JSExport ]
85- public static Task StopSearch ( )
95+ public static Task StopSearch ( int instanceId )
8696 {
87- try { _activeCts ? . Cancel ( ) ; } catch { }
97+ MotelyInstance . Get ( instanceId ) . CancelSearch ( ) ;
8898 return Task . CompletedTask ;
8999 }
90100
91- // ── ANALYZE ──
101+ // ── Analyze (instance-scoped for future streaming) ──
92102
93103 [ JSExport ]
94- public static Task < string > AnalyzeSeed ( string seed , string deck , string stake )
104+ public static Task < string > AnalyzeSeed ( int instanceId , string seed , string deck , string stake )
95105 {
106+ // instanceId reserved for future per-instance state (streaming analysis, caching)
96107 try
97108 {
98109 var dto = MotelySeedAnalyzer . AnalyzeToDto ( seed , deck , stake ) ;
@@ -106,7 +117,7 @@ public static Task<string> AnalyzeSeed(string seed, string deck, string stake)
106117 }
107118 }
108119
109- // ── GETTERS ──
120+ // ── Global (no instance needed) ──
110121
111122 [ JSExport ]
112123 public static Task < string > GetVersion ( ) => Task . FromResult ( MotelyBuildVersion . For ( typeof ( MotelyCore ) . Assembly ) ) ;
@@ -134,23 +145,22 @@ public static Task<string> ValidateJamlWithError(string jamlContent)
134145 private static int ResolveBatch ( int b ) => b is >= 1 and <= 7 ? b : 4 ;
135146
136147 private static async Task < string > RunSearch (
137- string jamlContent , MotelySearchRequest request ,
148+ int instanceId , string jamlContent , MotelySearchRequest request ,
138149 Action < long , long , long > onProgress , Action < string , int > onResult )
139150 {
140- if ( _activeCts != null )
141- return "error: search already running" ;
142-
143- var cts = new CancellationTokenSource ( ) ;
144- _activeCts = cts ;
151+ var instance = MotelyInstance . Get ( instanceId ) ;
152+ if ( instance . IsSearchActive )
153+ return "error: search already running on this instance" ;
145154
155+ var token = instance . BeginSearch ( ) ;
146156 try
147157 {
148158 var ( status , _, _) = await Task . Run ( ( ) =>
149- MotelySearchOrchestrator . RunSearch ( jamlContent , request , onProgress , onResult , cts . Token ) ) ;
159+ MotelySearchOrchestrator . RunSearch ( jamlContent , request , onProgress , onResult , token ) ) ;
150160 return status ;
151161 }
152162 catch ( OperationCanceledException ) { return "cancelled" ; }
153163 catch ( Exception ex ) { return $ "error: { ex . Message } "; }
154- finally { _activeCts = null ; }
164+ finally { instance . EndSearch ( ) ; }
155165 }
156166}
0 commit comments