@steerprotocol/app-loader 3.0.0 → 3.0.1

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/README.md CHANGED
@@ -113,6 +113,10 @@ npm run build
113
113
  npm test
114
114
  ```
115
115
 
116
+ An env-gated live repro for the deprecated Sushi Polygon v2 connector is enabled when
117
+ `STEER_SUBGRAPH_STUDIO_KEY` is set (or `STEER_SUBGRAPH_GATEWAY_KEY` for local debugging). This connector is kept as historical evidence of a
118
+ known-broken path and is not part of the supported execution contract.
119
+
116
120
  ### Packed Consumer Smoke Tests
117
121
 
118
122
  These tests validate the packed artifact in real consumer fixtures for:
@@ -1,10 +1,22 @@
1
+ /**
2
+ * Trade point model used as candle-generation input.
3
+ */
1
4
  declare class RawTradeData {
2
5
  timestamp: number;
3
6
  price: number;
4
7
  volume: number;
8
+ /**
9
+ * Creates a raw trade data point.
10
+ * @param timestamp - Trade timestamp.
11
+ * @param price - Trade price.
12
+ * @param volume - Trade volume.
13
+ */
5
14
  constructor(timestamp: number, price: number, volume: number);
6
15
  }
7
16
 
17
+ /**
18
+ * OHLCV candle model.
19
+ */
8
20
  declare class Candle {
9
21
  timestamp: number;
10
22
  high: number;
@@ -12,20 +24,39 @@ declare class Candle {
12
24
  open: number;
13
25
  close: number;
14
26
  volume: number;
27
+ /**
28
+ * Creates a candle instance.
29
+ * @param timestamp - Candle open timestamp in milliseconds.
30
+ * @param high - Highest traded price.
31
+ * @param low - Lowest traded price.
32
+ * @param open - Opening price.
33
+ * @param close - Closing price.
34
+ * @param volume - Total traded volume.
35
+ */
15
36
  constructor(timestamp: number, high: number, low: number, open: number, close: number, volume: number);
37
+ /**
38
+ * Serializes the candle as JSON.
39
+ * @returns The candle as a JSON string.
40
+ */
16
41
  toString(): string;
17
42
  }
18
43
 
44
+ /**
45
+ * Type declarations for the wasm exports surfaced by this package.
46
+ */
19
47
  declare function responseHandler(body: ArrayBuffer, statusCode: number, redirected: number, callbackID: number): void;
20
- declare function initialize(config: string): void;
48
+ declare function initialize(config: string): boolean;
21
49
  declare function config(): string;
22
50
  declare function version(): number;
23
51
  declare function transform(): string;
24
- declare function execute(...params: number[] | string[] | ArrayBuffer[] | null[]): string;
52
+ declare function execute(...params: Array<number | string | ArrayBuffer | null>): Promise<string | null>;
25
53
  declare function __new(size: number, id: number): number;
26
54
  declare function __pin(ptr: number): number;
27
55
  declare function __unpin(ptr: number): number;
28
56
  declare function reset(): void;
57
+ /**
58
+ * Public shape of the wrapped wasm exports.
59
+ */
29
60
  type WasmModule = {
30
61
  responseHandler: typeof responseHandler;
31
62
  initialize: typeof initialize;
@@ -1,10 +1,22 @@
1
+ /**
2
+ * Trade point model used as candle-generation input.
3
+ */
1
4
  declare class RawTradeData {
2
5
  timestamp: number;
3
6
  price: number;
4
7
  volume: number;
8
+ /**
9
+ * Creates a raw trade data point.
10
+ * @param timestamp - Trade timestamp.
11
+ * @param price - Trade price.
12
+ * @param volume - Trade volume.
13
+ */
5
14
  constructor(timestamp: number, price: number, volume: number);
6
15
  }
7
16
 
17
+ /**
18
+ * OHLCV candle model.
19
+ */
8
20
  declare class Candle {
9
21
  timestamp: number;
10
22
  high: number;
@@ -12,20 +24,39 @@ declare class Candle {
12
24
  open: number;
13
25
  close: number;
14
26
  volume: number;
27
+ /**
28
+ * Creates a candle instance.
29
+ * @param timestamp - Candle open timestamp in milliseconds.
30
+ * @param high - Highest traded price.
31
+ * @param low - Lowest traded price.
32
+ * @param open - Opening price.
33
+ * @param close - Closing price.
34
+ * @param volume - Total traded volume.
35
+ */
15
36
  constructor(timestamp: number, high: number, low: number, open: number, close: number, volume: number);
37
+ /**
38
+ * Serializes the candle as JSON.
39
+ * @returns The candle as a JSON string.
40
+ */
16
41
  toString(): string;
17
42
  }
18
43
 
44
+ /**
45
+ * Type declarations for the wasm exports surfaced by this package.
46
+ */
19
47
  declare function responseHandler(body: ArrayBuffer, statusCode: number, redirected: number, callbackID: number): void;
20
- declare function initialize(config: string): void;
48
+ declare function initialize(config: string): boolean;
21
49
  declare function config(): string;
22
50
  declare function version(): number;
23
51
  declare function transform(): string;
24
- declare function execute(...params: number[] | string[] | ArrayBuffer[] | null[]): string;
52
+ declare function execute(...params: Array<number | string | ArrayBuffer | null>): Promise<string | null>;
25
53
  declare function __new(size: number, id: number): number;
26
54
  declare function __pin(ptr: number): number;
27
55
  declare function __unpin(ptr: number): number;
28
56
  declare function reset(): void;
57
+ /**
58
+ * Public shape of the wrapped wasm exports.
59
+ */
29
60
  type WasmModule = {
30
61
  responseHandler: typeof responseHandler;
31
62
  initialize: typeof initialize;
package/lib/browser.mjs CHANGED
@@ -83,6 +83,15 @@ function convert(value, unit, unitValues) {
83
83
 
84
84
  // src/Candle.ts
85
85
  var Candle = class {
86
+ /**
87
+ * Creates a candle instance.
88
+ * @param timestamp - Candle open timestamp in milliseconds.
89
+ * @param high - Highest traded price.
90
+ * @param low - Lowest traded price.
91
+ * @param open - Opening price.
92
+ * @param close - Closing price.
93
+ * @param volume - Total traded volume.
94
+ */
86
95
  constructor(timestamp, high, low, open, close, volume) {
87
96
  this.timestamp = timestamp;
88
97
  this.high = high;
@@ -91,6 +100,10 @@ var Candle = class {
91
100
  this.close = close;
92
101
  this.volume = volume;
93
102
  }
103
+ /**
104
+ * Serializes the candle as JSON.
105
+ * @returns The candle as a JSON string.
106
+ */
94
107
  toString() {
95
108
  return JSON.stringify(this);
96
109
  }
@@ -102,7 +115,7 @@ function generateCandles(data, candleSize) {
102
115
  }
103
116
  const _data = data.map((point) => {
104
117
  return Object.assign(Object.assign({}, point), {
105
- // This will convert the timestamp to milliseconds if it's in seconds
118
+ // Older inputs may still provide 10-digit second timestamps instead of milliseconds.
106
119
  timestamp: point.timestamp && String(point.timestamp).length == 10 ? point.timestamp * 1e3 : point.timestamp
107
120
  });
108
121
  });
@@ -147,6 +160,12 @@ function generateCandles(data, candleSize) {
147
160
 
148
161
  // src/RawTradeData.ts
149
162
  var RawTradeData = class {
163
+ /**
164
+ * Creates a raw trade data point.
165
+ * @param timestamp - Trade timestamp.
166
+ * @param price - Trade price.
167
+ * @param volume - Trade volume.
168
+ */
150
169
  constructor(timestamp, price, volume) {
151
170
  this.timestamp = timestamp;
152
171
  this.price = price;
@@ -165,32 +184,60 @@ function instantiate(module, imports = {}, runtime = {}) {
165
184
  let fetchFn = null;
166
185
  let ccxtFn = null;
167
186
  let detachedValue = null;
187
+ let executeInFlight = false;
188
+ const pinScopes = [];
168
189
  const adaptedImports = Object.assign(
169
190
  {
170
191
  console: {
192
+ /**
193
+ * Logs a lifted AssemblyScript string.
194
+ * @param text - Pointer to the message string.
195
+ */
171
196
  log(text) {
172
197
  console.log(__liftString(text));
173
198
  }
174
199
  },
175
200
  ethers: {
201
+ /**
202
+ * Hashes a lifted string with `keccak256`.
203
+ * @param str_ptr - Pointer to the input string.
204
+ * @returns Pointer to the hashed string result.
205
+ */
176
206
  keccak256_str(str_ptr) {
177
207
  const str = __liftString(str_ptr);
178
208
  const hash = ethers.keccak256(str);
179
- return __lowerString(hash);
209
+ return withAutoPinScope(() => __lowerString(hash));
180
210
  },
211
+ /**
212
+ * Hashes a lifted buffer with `keccak256`.
213
+ * @param buf_ptr - Pointer to the input buffer.
214
+ * @returns Pointer to the hashed string result.
215
+ */
181
216
  keccak256_buf(buf_ptr) {
182
217
  const buf = __liftBuffer(buf_ptr);
183
218
  const hash = ethers.keccak256(new Uint8Array(buf));
184
- return __lowerString(hash);
219
+ return withAutoPinScope(() => __lowerString(hash));
185
220
  }
186
221
  },
187
222
  // @ts-ignore
188
223
  env: {
224
+ /**
225
+ * Raises a JavaScript error for an AssemblyScript abort.
226
+ * @param message - Pointer to the abort message.
227
+ * @param fileName - Pointer to the source filename.
228
+ * @param lineNumber - Source line number.
229
+ * @param columnNumber - Source column number.
230
+ */
189
231
  abort(message, fileName, lineNumber, columnNumber) {
190
232
  (() => {
191
233
  throw Error(`${__liftString(message)} in ${__liftString(fileName)}:${lineNumber}:${columnNumber}`);
192
234
  })();
193
235
  },
236
+ /**
237
+ * Initializes Asyncify bookkeeping for host callbacks.
238
+ * @param frame_ptr - Asyncify frame pointer.
239
+ * @param stack_ptr - Asyncify stack pointer.
240
+ */
194
241
  _initAsyncify(frame_ptr, stack_ptr) {
195
242
  if (!WASM_EXPORTS["asyncify_get_state"])
196
243
  throw new Error(
@@ -202,15 +249,34 @@ function instantiate(module, imports = {}, runtime = {}) {
202
249
  ASYNCIFY_MEM[ASYNCIFY_PTR + 4 >> 2] = stack_ptr;
203
250
  ASYNCIFY_INITIALIZED = true;
204
251
  },
252
+ /**
253
+ * Aggregates lifted trade data into candles.
254
+ * @param data - Pointer to the serialized trade array.
255
+ * @param candleSize - Pointer to the candle size string.
256
+ * @returns Pointer to the serialized candle array.
257
+ */
205
258
  generateCandles(data, candleSize) {
206
259
  const _data = __liftString(data) || "[]";
207
260
  const _candleSize = __liftString(candleSize) || "69m";
208
261
  const candles = generateCandles(JSON.parse(_data), _candleSize);
209
- return __lowerString(JSON.stringify(candles));
262
+ return withAutoPinScope(() => __lowerString(JSON.stringify(candles)));
210
263
  },
264
+ /**
265
+ * Logs a lifted AssemblyScript string.
266
+ * @param text - Pointer to the message string.
267
+ */
211
268
  "console.log": (text) => {
212
269
  console.log(__liftString(text));
213
270
  },
271
+ /**
272
+ * Schedules an async OHLCV request for asyncified execution.
273
+ * @param exchangeId - Pointer to the exchange id string.
274
+ * @param symbol - Pointer to the market symbol string.
275
+ * @param timeframe - Pointer to the timeframe string.
276
+ * @param limit - Maximum number of rows.
277
+ * @param since - Optional start timestamp.
278
+ * @returns Pointer to the rewound OHLCV matrix when replaying.
279
+ */
214
280
  ccxt_fetchOHLCV: (exchangeId, symbol, timeframe, limit, since) => {
215
281
  const currentState = WASM_EXPORTS.asyncify_get_state();
216
282
  if (currentState === 2 /* Rewinding */) {
@@ -242,6 +308,11 @@ function instantiate(module, imports = {}, runtime = {}) {
242
308
  }
243
309
  },
244
310
  "as-fetch": {
311
+ /**
312
+ * Initializes Asyncify bookkeeping for as-fetch host calls.
313
+ * @param frame_ptr - Asyncify frame pointer.
314
+ * @param stack_ptr - Asyncify stack pointer.
315
+ */
245
316
  _initAsyncify(frame_ptr, stack_ptr) {
246
317
  if (!WASM_EXPORTS["asyncify_get_state"])
247
318
  throw new Error(
@@ -253,6 +324,14 @@ function instantiate(module, imports = {}, runtime = {}) {
253
324
  ASYNCIFY_MEM[ASYNCIFY_PTR + 4 >> 2] = stack_ptr;
254
325
  ASYNCIFY_INITIALIZED = true;
255
326
  },
327
+ /**
328
+ * Executes a synchronous asyncified POST request.
329
+ * @param url - Pointer to the request URL.
330
+ * @param mode - Numeric fetch mode.
331
+ * @param headers - Pointer to the header array.
332
+ * @param body - Pointer to the request body.
333
+ * @returns Pointer to the response body when replaying.
334
+ */
256
335
  _fetchPOSTSync(url, mode, headers, body) {
257
336
  const currentState = WASM_EXPORTS.asyncify_get_state();
258
337
  if (currentState === 2 /* Rewinding */) {
@@ -278,6 +357,13 @@ function instantiate(module, imports = {}, runtime = {}) {
278
357
  };
279
358
  WASM_EXPORTS.asyncify_start_unwind(ASYNCIFY_PTR);
280
359
  },
360
+ /**
361
+ * Executes a synchronous asyncified GET request.
362
+ * @param url - Pointer to the request URL.
363
+ * @param mode - Numeric fetch mode.
364
+ * @param headers - Pointer to the header array.
365
+ * @returns Pointer to the response body when replaying.
366
+ */
281
367
  _fetchGETSync(url, mode, headers) {
282
368
  const currentState = WASM_EXPORTS.asyncify_get_state();
283
369
  if (currentState === 2 /* Rewinding */) {
@@ -302,37 +388,60 @@ function instantiate(module, imports = {}, runtime = {}) {
302
388
  };
303
389
  WASM_EXPORTS.asyncify_start_unwind(ASYNCIFY_PTR);
304
390
  },
391
+ /**
392
+ * Executes an asynchronous GET request and forwards the response to wasm.
393
+ * @param url - Pointer to the request URL.
394
+ * @param mode - Numeric fetch mode.
395
+ * @param headers - Pointer to the header array.
396
+ * @param callbackID - Wasm callback identifier.
397
+ */
305
398
  _fetchGET(url, mode, headers, callbackID) {
306
399
  void (async () => {
307
- const fetchImpl = await getFetchOrThrow(runtime);
308
- const res = await fetchImpl(__liftString(url) || "", {
309
- method: "GET",
310
- mode: modeToString(mode) || "cors",
311
- headers: __liftArray(
312
- (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
313
- 2,
314
- headers
315
- ) || []
316
- });
317
- const body = await res.arrayBuffer();
318
- WASM_EXPORTS.responseHandler(body, res.status, res.redirected ? 1 : 0, callbackID);
400
+ try {
401
+ const fetchImpl = await getFetchOrThrow(runtime);
402
+ const res = await fetchImpl(__liftString(url) || "", {
403
+ method: "GET",
404
+ mode: modeToString(mode) || "cors",
405
+ headers: __liftArray(
406
+ (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
407
+ 2,
408
+ headers
409
+ ) || []
410
+ });
411
+ const body = await res.arrayBuffer();
412
+ WASM_EXPORTS.responseHandler(body, res.status, res.redirected ? 1 : 0, callbackID);
413
+ } catch (error) {
414
+ console.error(error);
415
+ }
319
416
  })();
320
417
  },
418
+ /**
419
+ * Executes an asynchronous POST request and forwards the response to wasm.
420
+ * @param url - Pointer to the request URL.
421
+ * @param mode - Numeric fetch mode.
422
+ * @param headers - Pointer to the header array.
423
+ * @param body - Request body.
424
+ * @param callbackID - Wasm callback identifier.
425
+ */
321
426
  _fetchPOST(url, mode, headers, body, callbackID) {
322
427
  void (async () => {
323
- const fetchImpl = await getFetchOrThrow(runtime);
324
- const res = await fetchImpl(__liftString(url) || "", {
325
- method: "POST",
326
- mode: modeToString(mode) || "cors",
327
- body,
328
- headers: __liftArray(
329
- (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
330
- 2,
331
- headers
332
- ) || []
333
- });
334
- const responseBody = await res.arrayBuffer();
335
- WASM_EXPORTS.responseHandler(responseBody, res.status, res.redirected ? 1 : 0, callbackID);
428
+ try {
429
+ const fetchImpl = await getFetchOrThrow(runtime);
430
+ const res = await fetchImpl(__liftString(url) || "", {
431
+ method: "POST",
432
+ mode: modeToString(mode) || "cors",
433
+ body,
434
+ headers: __liftArray(
435
+ (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
436
+ 2,
437
+ headers
438
+ ) || []
439
+ });
440
+ const responseBody = await res.arrayBuffer();
441
+ WASM_EXPORTS.responseHandler(responseBody, res.status, res.redirected ? 1 : 0, callbackID);
442
+ } catch (error) {
443
+ console.error(error);
444
+ }
336
445
  })();
337
446
  }
338
447
  }
@@ -345,63 +454,110 @@ function instantiate(module, imports = {}, runtime = {}) {
345
454
  ASYNCIFY_MEM = new Uint32Array(WASM_MEMORY.buffer);
346
455
  const handledExports = Object.setPrototypeOf(
347
456
  {
457
+ /**
458
+ * Forwards an HTTP response body into the wasm export.
459
+ * @param body - Response body.
460
+ * @param statusCode - HTTP status code.
461
+ * @param redirected - Whether the request redirected.
462
+ * @param callbackID - Wasm callback identifier.
463
+ */
348
464
  responseHandler(body, statusCode, redirected, callbackID) {
349
465
  if (!WASM_EXPORTS["responseHandler"])
350
466
  throw new Error(
351
467
  'Unable to call .responseHandler on wasm module. Add the line export { responseHandler } from "as-fetch/assembly" to your entry file.'
352
468
  );
353
- WASM_EXPORTS.responseHandler(__lowerBuffer(body), statusCode, redirected ? 1 : 0, callbackID);
469
+ withPinScope(() => {
470
+ WASM_EXPORTS.responseHandler(__lowerBuffer(body), statusCode, redirected ? 1 : 0, callbackID);
471
+ });
354
472
  },
473
+ /**
474
+ * Initializes the wasm module with a JSON configuration payload.
475
+ * @param config - Serialized connector configuration.
476
+ * @returns `true` when initialization succeeds.
477
+ */
355
478
  initialize(config) {
356
479
  if (!WASM_EXPORTS["initialize"])
357
480
  throw new Error("Unable to call .initialize on wasm module. Are you sure this is a data connector?");
358
481
  try {
359
- WASM_EXPORTS.initialize(__lowerString(config));
482
+ withPinScope(() => {
483
+ WASM_EXPORTS.initialize(__lowerString(config));
484
+ });
360
485
  return true;
361
486
  } catch (e) {
362
487
  console.error(e);
363
488
  return false;
364
489
  }
365
490
  },
491
+ /**
492
+ * Executes the wasm module, replaying arguments across asyncify rewinds.
493
+ * @param params - Logical execute arguments.
494
+ * @returns The lifted execute result.
495
+ */
366
496
  async execute(...params) {
367
497
  if (!WASM_EXPORTS["execute"])
368
498
  throw new Error("Unable to call .execute on wasm module. Are you sure this is a data connector?");
369
- const loweredArgs = new Array(params.length);
370
- for (let i = 0; i < params.length; i++) {
371
- loweredArgs[i] = __lower(params[i]);
499
+ if (executeInFlight) {
500
+ throw new Error("Concurrent execute calls are not supported on the same wasm instance.");
372
501
  }
373
- let result;
502
+ executeInFlight = true;
503
+ const replayArgs = snapshotLogicalArgs(params);
374
504
  try {
375
- result = WASM_EXPORTS.execute(...loweredArgs);
376
- } catch (error) {
377
- if (params.length !== 0) {
378
- throw error;
505
+ let result;
506
+ try {
507
+ result = executeWithReplayArgs(replayArgs);
508
+ } catch (error) {
509
+ if (params.length !== 0) {
510
+ throw error;
511
+ }
512
+ replayArgs.splice(0, replayArgs.length, "");
513
+ result = executeWithReplayArgs(replayArgs);
379
514
  }
380
- result = WASM_EXPORTS.execute(__lowerString(""));
381
- }
382
- if (ASYNCIFY_INITIALIZED) {
383
- while (WASM_EXPORTS.asyncify_get_state() === 1 /* Unwinding */) {
384
- WASM_EXPORTS.asyncify_stop_unwind();
385
- if (fetchFn) detachedValue = await fetchFn();
386
- if (ccxtFn) detachedValue = await ccxtFn();
387
- WASM_EXPORTS.asyncify_start_rewind(ASYNCIFY_PTR);
388
- result = WASM_EXPORTS.execute();
515
+ if (ASYNCIFY_INITIALIZED) {
516
+ while (WASM_EXPORTS.asyncify_get_state() === 1 /* Unwinding */) {
517
+ WASM_EXPORTS.asyncify_stop_unwind();
518
+ if (fetchFn) {
519
+ const pendingFetch = fetchFn;
520
+ fetchFn = null;
521
+ detachedValue = await pendingFetch();
522
+ }
523
+ if (ccxtFn) {
524
+ const pendingCcxt = ccxtFn;
525
+ ccxtFn = null;
526
+ detachedValue = await pendingCcxt();
527
+ }
528
+ WASM_EXPORTS.asyncify_start_rewind(ASYNCIFY_PTR);
529
+ result = executeWithReplayArgs(replayArgs);
530
+ }
389
531
  }
532
+ return __liftString(result);
533
+ } finally {
534
+ fetchFn = null;
535
+ ccxtFn = null;
536
+ detachedValue = null;
537
+ executeInFlight = false;
390
538
  }
391
- if (fetchFn) fetchFn = null;
392
- if (ccxtFn) ccxtFn = null;
393
- return __liftString(result);
394
539
  },
540
+ /**
541
+ * Reads the connector configuration schema from wasm.
542
+ * @returns The lifted configuration payload.
543
+ */
395
544
  config() {
396
545
  if (!WASM_EXPORTS["config"])
397
546
  throw new Error("Unable to call .config on wasm module. Are you sure this is a data connector?");
398
- return __liftString(WASM_EXPORTS.config());
547
+ return withPinScope(() => __liftString(WASM_EXPORTS.config()));
399
548
  },
549
+ /**
550
+ * Reads the connector transform from wasm.
551
+ * @returns The lifted transform payload.
552
+ */
400
553
  transform() {
401
554
  if (!WASM_EXPORTS["transform"])
402
555
  throw new Error("Unable to call .transform on wasm module. Are you sure this is a data connector?");
403
- return __liftString(WASM_EXPORTS.transform());
556
+ return withPinScope(() => __liftString(WASM_EXPORTS.transform()));
404
557
  },
558
+ /**
559
+ * Resets wasm module state when supported.
560
+ */
405
561
  reset() {
406
562
  if (WASM_EXPORTS["reset"]) WASM_EXPORTS.reset();
407
563
  }
@@ -420,6 +576,48 @@ function instantiate(module, imports = {}, runtime = {}) {
420
576
  return 0;
421
577
  }
422
578
  }
579
+ function lowerArgs(values) {
580
+ const loweredArgs = new Array(values.length);
581
+ for (let i = 0; i < values.length; i++) {
582
+ loweredArgs[i] = __lower(values[i]);
583
+ }
584
+ return loweredArgs;
585
+ }
586
+ function snapshotLogicalArgs(values) {
587
+ return values.map((value) => {
588
+ if (value instanceof ArrayBuffer) {
589
+ return value.slice(0);
590
+ }
591
+ return value;
592
+ });
593
+ }
594
+ function executeWithReplayArgs(values) {
595
+ return withPinScope(() => WASM_EXPORTS.execute(...lowerArgs(values)));
596
+ }
597
+ function withPinScope(fn) {
598
+ pinScopes.push([]);
599
+ try {
600
+ return fn();
601
+ } finally {
602
+ const scope = pinScopes.pop() || [];
603
+ for (let i = scope.length - 1; i >= 0; i--) {
604
+ WASM_EXPORTS.__unpin(scope[i]);
605
+ }
606
+ }
607
+ }
608
+ function withAutoPinScope(fn) {
609
+ if (pinScopes.length > 0) {
610
+ return fn();
611
+ }
612
+ return withPinScope(fn);
613
+ }
614
+ function trackPinnedPointer(ptr) {
615
+ const scope = pinScopes[pinScopes.length - 1];
616
+ if (scope) {
617
+ scope.push(ptr);
618
+ }
619
+ return ptr;
620
+ }
423
621
  function __liftString(ptr) {
424
622
  if (!ptr) return null;
425
623
  const end = ptr + new Uint32Array(WASM_MEMORY.buffer)[ptr - 4 >>> 2] >>> 1;
@@ -432,7 +630,7 @@ function instantiate(module, imports = {}, runtime = {}) {
432
630
  function __lowerString(value) {
433
631
  if (value == null) return 0;
434
632
  const length = value.length;
435
- const ptr = WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << 1, 2) >>> 0);
633
+ const ptr = trackPinnedPointer(WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << 1, 2) >>> 0));
436
634
  const memoryU16 = new Uint16Array(WASM_MEMORY.buffer);
437
635
  for (let i = 0; i < length; ++i) memoryU16[(ptr >>> 1) + i] = value.charCodeAt(i);
438
636
  return ptr;
@@ -443,7 +641,7 @@ function instantiate(module, imports = {}, runtime = {}) {
443
641
  }
444
642
  function __lowerBuffer(value) {
445
643
  if (value == null) return 0;
446
- const ptr = WASM_EXPORTS.__pin(WASM_EXPORTS.__new(value.byteLength, 1) >>> 0);
644
+ const ptr = trackPinnedPointer(WASM_EXPORTS.__pin(WASM_EXPORTS.__new(value.byteLength, 1) >>> 0));
447
645
  new Uint8Array(WASM_MEMORY.buffer).set(new Uint8Array(value), ptr);
448
646
  return ptr;
449
647
  }
@@ -458,7 +656,7 @@ function instantiate(module, imports = {}, runtime = {}) {
458
656
  function __lowerStaticArray(lowerElement, id, align, values, typedConstructor = null) {
459
657
  if (values == null) return 0;
460
658
  const length = values.length;
461
- const buffer = WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << align, id)) >>> 0;
659
+ const buffer = trackPinnedPointer(WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << align, id)) >>> 0) >>> 0;
462
660
  if (typedConstructor) {
463
661
  new typedConstructor(WASM_MEMORY.buffer, buffer, length).set(values);
464
662
  } else {