@steerprotocol/app-loader 3.0.0 → 3.0.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.
package/lib/node.cjs CHANGED
@@ -122,6 +122,15 @@ function convert(value, unit, unitValues) {
122
122
 
123
123
  // src/Candle.ts
124
124
  var Candle = class {
125
+ /**
126
+ * Creates a candle instance.
127
+ * @param timestamp - Candle open timestamp in milliseconds.
128
+ * @param high - Highest traded price.
129
+ * @param low - Lowest traded price.
130
+ * @param open - Opening price.
131
+ * @param close - Closing price.
132
+ * @param volume - Total traded volume.
133
+ */
125
134
  constructor(timestamp, high, low, open, close, volume) {
126
135
  this.timestamp = timestamp;
127
136
  this.high = high;
@@ -130,6 +139,10 @@ var Candle = class {
130
139
  this.close = close;
131
140
  this.volume = volume;
132
141
  }
142
+ /**
143
+ * Serializes the candle as JSON.
144
+ * @returns The candle as a JSON string.
145
+ */
133
146
  toString() {
134
147
  return JSON.stringify(this);
135
148
  }
@@ -141,7 +154,7 @@ function generateCandles(data, candleSize) {
141
154
  }
142
155
  const _data = data.map((point) => {
143
156
  return Object.assign(Object.assign({}, point), {
144
- // This will convert the timestamp to milliseconds if it's in seconds
157
+ // Older inputs may still provide 10-digit second timestamps instead of milliseconds.
145
158
  timestamp: point.timestamp && String(point.timestamp).length == 10 ? point.timestamp * 1e3 : point.timestamp
146
159
  });
147
160
  });
@@ -186,6 +199,12 @@ function generateCandles(data, candleSize) {
186
199
 
187
200
  // src/RawTradeData.ts
188
201
  var RawTradeData = class {
202
+ /**
203
+ * Creates a raw trade data point.
204
+ * @param timestamp - Trade timestamp.
205
+ * @param price - Trade price.
206
+ * @param volume - Trade volume.
207
+ */
189
208
  constructor(timestamp, price, volume) {
190
209
  this.timestamp = timestamp;
191
210
  this.price = price;
@@ -204,32 +223,60 @@ function instantiate(module2, imports = {}, runtime = {}) {
204
223
  let fetchFn = null;
205
224
  let ccxtFn = null;
206
225
  let detachedValue = null;
226
+ let executeInFlight = false;
227
+ const pinScopes = [];
207
228
  const adaptedImports = Object.assign(
208
229
  {
209
230
  console: {
231
+ /**
232
+ * Logs a lifted AssemblyScript string.
233
+ * @param text - Pointer to the message string.
234
+ */
210
235
  log(text) {
211
236
  console.log(__liftString(text));
212
237
  }
213
238
  },
214
239
  ethers: {
240
+ /**
241
+ * Hashes a lifted string with `keccak256`.
242
+ * @param str_ptr - Pointer to the input string.
243
+ * @returns Pointer to the hashed string result.
244
+ */
215
245
  keccak256_str(str_ptr) {
216
246
  const str = __liftString(str_ptr);
217
247
  const hash = import_ethers.ethers.keccak256(str);
218
- return __lowerString(hash);
248
+ return withAutoPinScope(() => __lowerString(hash));
219
249
  },
250
+ /**
251
+ * Hashes a lifted buffer with `keccak256`.
252
+ * @param buf_ptr - Pointer to the input buffer.
253
+ * @returns Pointer to the hashed string result.
254
+ */
220
255
  keccak256_buf(buf_ptr) {
221
256
  const buf = __liftBuffer(buf_ptr);
222
257
  const hash = import_ethers.ethers.keccak256(new Uint8Array(buf));
223
- return __lowerString(hash);
258
+ return withAutoPinScope(() => __lowerString(hash));
224
259
  }
225
260
  },
226
261
  // @ts-ignore
227
262
  env: {
263
+ /**
264
+ * Raises a JavaScript error for an AssemblyScript abort.
265
+ * @param message - Pointer to the abort message.
266
+ * @param fileName - Pointer to the source filename.
267
+ * @param lineNumber - Source line number.
268
+ * @param columnNumber - Source column number.
269
+ */
228
270
  abort(message, fileName, lineNumber, columnNumber) {
229
271
  (() => {
230
272
  throw Error(`${__liftString(message)} in ${__liftString(fileName)}:${lineNumber}:${columnNumber}`);
231
273
  })();
232
274
  },
275
+ /**
276
+ * Initializes Asyncify bookkeeping for host callbacks.
277
+ * @param frame_ptr - Asyncify frame pointer.
278
+ * @param stack_ptr - Asyncify stack pointer.
279
+ */
233
280
  _initAsyncify(frame_ptr, stack_ptr) {
234
281
  if (!WASM_EXPORTS["asyncify_get_state"])
235
282
  throw new Error(
@@ -241,15 +288,34 @@ function instantiate(module2, imports = {}, runtime = {}) {
241
288
  ASYNCIFY_MEM[ASYNCIFY_PTR + 4 >> 2] = stack_ptr;
242
289
  ASYNCIFY_INITIALIZED = true;
243
290
  },
291
+ /**
292
+ * Aggregates lifted trade data into candles.
293
+ * @param data - Pointer to the serialized trade array.
294
+ * @param candleSize - Pointer to the candle size string.
295
+ * @returns Pointer to the serialized candle array.
296
+ */
244
297
  generateCandles(data, candleSize) {
245
298
  const _data = __liftString(data) || "[]";
246
299
  const _candleSize = __liftString(candleSize) || "69m";
247
300
  const candles = generateCandles(JSON.parse(_data), _candleSize);
248
- return __lowerString(JSON.stringify(candles));
301
+ return withAutoPinScope(() => __lowerString(JSON.stringify(candles)));
249
302
  },
303
+ /**
304
+ * Logs a lifted AssemblyScript string.
305
+ * @param text - Pointer to the message string.
306
+ */
250
307
  "console.log": (text) => {
251
308
  console.log(__liftString(text));
252
309
  },
310
+ /**
311
+ * Schedules an async OHLCV request for asyncified execution.
312
+ * @param exchangeId - Pointer to the exchange id string.
313
+ * @param symbol - Pointer to the market symbol string.
314
+ * @param timeframe - Pointer to the timeframe string.
315
+ * @param limit - Maximum number of rows.
316
+ * @param since - Optional start timestamp.
317
+ * @returns Pointer to the rewound OHLCV matrix when replaying.
318
+ */
253
319
  ccxt_fetchOHLCV: (exchangeId, symbol, timeframe, limit, since) => {
254
320
  const currentState = WASM_EXPORTS.asyncify_get_state();
255
321
  if (currentState === 2 /* Rewinding */) {
@@ -281,6 +347,11 @@ function instantiate(module2, imports = {}, runtime = {}) {
281
347
  }
282
348
  },
283
349
  "as-fetch": {
350
+ /**
351
+ * Initializes Asyncify bookkeeping for as-fetch host calls.
352
+ * @param frame_ptr - Asyncify frame pointer.
353
+ * @param stack_ptr - Asyncify stack pointer.
354
+ */
284
355
  _initAsyncify(frame_ptr, stack_ptr) {
285
356
  if (!WASM_EXPORTS["asyncify_get_state"])
286
357
  throw new Error(
@@ -292,6 +363,14 @@ function instantiate(module2, imports = {}, runtime = {}) {
292
363
  ASYNCIFY_MEM[ASYNCIFY_PTR + 4 >> 2] = stack_ptr;
293
364
  ASYNCIFY_INITIALIZED = true;
294
365
  },
366
+ /**
367
+ * Executes a synchronous asyncified POST request.
368
+ * @param url - Pointer to the request URL.
369
+ * @param mode - Numeric fetch mode.
370
+ * @param headers - Pointer to the header array.
371
+ * @param body - Pointer to the request body.
372
+ * @returns Pointer to the response body when replaying.
373
+ */
295
374
  _fetchPOSTSync(url, mode, headers, body) {
296
375
  const currentState = WASM_EXPORTS.asyncify_get_state();
297
376
  if (currentState === 2 /* Rewinding */) {
@@ -317,6 +396,13 @@ function instantiate(module2, imports = {}, runtime = {}) {
317
396
  };
318
397
  WASM_EXPORTS.asyncify_start_unwind(ASYNCIFY_PTR);
319
398
  },
399
+ /**
400
+ * Executes a synchronous asyncified GET request.
401
+ * @param url - Pointer to the request URL.
402
+ * @param mode - Numeric fetch mode.
403
+ * @param headers - Pointer to the header array.
404
+ * @returns Pointer to the response body when replaying.
405
+ */
320
406
  _fetchGETSync(url, mode, headers) {
321
407
  const currentState = WASM_EXPORTS.asyncify_get_state();
322
408
  if (currentState === 2 /* Rewinding */) {
@@ -341,37 +427,60 @@ function instantiate(module2, imports = {}, runtime = {}) {
341
427
  };
342
428
  WASM_EXPORTS.asyncify_start_unwind(ASYNCIFY_PTR);
343
429
  },
430
+ /**
431
+ * Executes an asynchronous GET request and forwards the response to wasm.
432
+ * @param url - Pointer to the request URL.
433
+ * @param mode - Numeric fetch mode.
434
+ * @param headers - Pointer to the header array.
435
+ * @param callbackID - Wasm callback identifier.
436
+ */
344
437
  _fetchGET(url, mode, headers, callbackID) {
345
438
  void (async () => {
346
- const fetchImpl = await getFetchOrThrow(runtime);
347
- const res = await fetchImpl(__liftString(url) || "", {
348
- method: "GET",
349
- mode: modeToString(mode) || "cors",
350
- headers: __liftArray(
351
- (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
352
- 2,
353
- headers
354
- ) || []
355
- });
356
- const body = await res.arrayBuffer();
357
- WASM_EXPORTS.responseHandler(body, res.status, res.redirected ? 1 : 0, callbackID);
439
+ try {
440
+ const fetchImpl = await getFetchOrThrow(runtime);
441
+ const res = await fetchImpl(__liftString(url) || "", {
442
+ method: "GET",
443
+ mode: modeToString(mode) || "cors",
444
+ headers: __liftArray(
445
+ (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
446
+ 2,
447
+ headers
448
+ ) || []
449
+ });
450
+ const body = await res.arrayBuffer();
451
+ WASM_EXPORTS.responseHandler(body, res.status, res.redirected ? 1 : 0, callbackID);
452
+ } catch (error) {
453
+ console.error(error);
454
+ }
358
455
  })();
359
456
  },
457
+ /**
458
+ * Executes an asynchronous POST request and forwards the response to wasm.
459
+ * @param url - Pointer to the request URL.
460
+ * @param mode - Numeric fetch mode.
461
+ * @param headers - Pointer to the header array.
462
+ * @param body - Request body.
463
+ * @param callbackID - Wasm callback identifier.
464
+ */
360
465
  _fetchPOST(url, mode, headers, body, callbackID) {
361
466
  void (async () => {
362
- const fetchImpl = await getFetchOrThrow(runtime);
363
- const res = await fetchImpl(__liftString(url) || "", {
364
- method: "POST",
365
- mode: modeToString(mode) || "cors",
366
- body,
367
- headers: __liftArray(
368
- (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
369
- 2,
370
- headers
371
- ) || []
372
- });
373
- const responseBody = await res.arrayBuffer();
374
- WASM_EXPORTS.responseHandler(responseBody, res.status, res.redirected ? 1 : 0, callbackID);
467
+ try {
468
+ const fetchImpl = await getFetchOrThrow(runtime);
469
+ const res = await fetchImpl(__liftString(url) || "", {
470
+ method: "POST",
471
+ mode: modeToString(mode) || "cors",
472
+ body,
473
+ headers: __liftArray(
474
+ (pointer) => __liftArray((pointer2) => __liftString(__getU32(pointer2)), 2, __getU32(pointer)),
475
+ 2,
476
+ headers
477
+ ) || []
478
+ });
479
+ const responseBody = await res.arrayBuffer();
480
+ WASM_EXPORTS.responseHandler(responseBody, res.status, res.redirected ? 1 : 0, callbackID);
481
+ } catch (error) {
482
+ console.error(error);
483
+ }
375
484
  })();
376
485
  }
377
486
  }
@@ -384,63 +493,110 @@ function instantiate(module2, imports = {}, runtime = {}) {
384
493
  ASYNCIFY_MEM = new Uint32Array(WASM_MEMORY.buffer);
385
494
  const handledExports = Object.setPrototypeOf(
386
495
  {
496
+ /**
497
+ * Forwards an HTTP response body into the wasm export.
498
+ * @param body - Response body.
499
+ * @param statusCode - HTTP status code.
500
+ * @param redirected - Whether the request redirected.
501
+ * @param callbackID - Wasm callback identifier.
502
+ */
387
503
  responseHandler(body, statusCode, redirected, callbackID) {
388
504
  if (!WASM_EXPORTS["responseHandler"])
389
505
  throw new Error(
390
506
  'Unable to call .responseHandler on wasm module. Add the line export { responseHandler } from "as-fetch/assembly" to your entry file.'
391
507
  );
392
- WASM_EXPORTS.responseHandler(__lowerBuffer(body), statusCode, redirected ? 1 : 0, callbackID);
508
+ withPinScope(() => {
509
+ WASM_EXPORTS.responseHandler(__lowerBuffer(body), statusCode, redirected ? 1 : 0, callbackID);
510
+ });
393
511
  },
512
+ /**
513
+ * Initializes the wasm module with a JSON configuration payload.
514
+ * @param config - Serialized connector configuration.
515
+ * @returns `true` when initialization succeeds.
516
+ */
394
517
  initialize(config) {
395
518
  if (!WASM_EXPORTS["initialize"])
396
519
  throw new Error("Unable to call .initialize on wasm module. Are you sure this is a data connector?");
397
520
  try {
398
- WASM_EXPORTS.initialize(__lowerString(config));
521
+ withPinScope(() => {
522
+ WASM_EXPORTS.initialize(__lowerString(config));
523
+ });
399
524
  return true;
400
525
  } catch (e) {
401
526
  console.error(e);
402
527
  return false;
403
528
  }
404
529
  },
530
+ /**
531
+ * Executes the wasm module, replaying arguments across asyncify rewinds.
532
+ * @param params - Logical execute arguments.
533
+ * @returns The lifted execute result.
534
+ */
405
535
  async execute(...params) {
406
536
  if (!WASM_EXPORTS["execute"])
407
537
  throw new Error("Unable to call .execute on wasm module. Are you sure this is a data connector?");
408
- const loweredArgs = new Array(params.length);
409
- for (let i = 0; i < params.length; i++) {
410
- loweredArgs[i] = __lower(params[i]);
538
+ if (executeInFlight) {
539
+ throw new Error("Concurrent execute calls are not supported on the same wasm instance.");
411
540
  }
412
- let result;
541
+ executeInFlight = true;
542
+ const replayArgs = snapshotLogicalArgs(params);
413
543
  try {
414
- result = WASM_EXPORTS.execute(...loweredArgs);
415
- } catch (error) {
416
- if (params.length !== 0) {
417
- throw error;
544
+ let result;
545
+ try {
546
+ result = executeWithReplayArgs(replayArgs);
547
+ } catch (error) {
548
+ if (params.length !== 0) {
549
+ throw error;
550
+ }
551
+ replayArgs.splice(0, replayArgs.length, "");
552
+ result = executeWithReplayArgs(replayArgs);
418
553
  }
419
- result = WASM_EXPORTS.execute(__lowerString(""));
420
- }
421
- if (ASYNCIFY_INITIALIZED) {
422
- while (WASM_EXPORTS.asyncify_get_state() === 1 /* Unwinding */) {
423
- WASM_EXPORTS.asyncify_stop_unwind();
424
- if (fetchFn) detachedValue = await fetchFn();
425
- if (ccxtFn) detachedValue = await ccxtFn();
426
- WASM_EXPORTS.asyncify_start_rewind(ASYNCIFY_PTR);
427
- result = WASM_EXPORTS.execute();
554
+ if (ASYNCIFY_INITIALIZED) {
555
+ while (WASM_EXPORTS.asyncify_get_state() === 1 /* Unwinding */) {
556
+ WASM_EXPORTS.asyncify_stop_unwind();
557
+ if (fetchFn) {
558
+ const pendingFetch = fetchFn;
559
+ fetchFn = null;
560
+ detachedValue = await pendingFetch();
561
+ }
562
+ if (ccxtFn) {
563
+ const pendingCcxt = ccxtFn;
564
+ ccxtFn = null;
565
+ detachedValue = await pendingCcxt();
566
+ }
567
+ WASM_EXPORTS.asyncify_start_rewind(ASYNCIFY_PTR);
568
+ result = executeWithReplayArgs(replayArgs);
569
+ }
428
570
  }
571
+ return __liftString(result);
572
+ } finally {
573
+ fetchFn = null;
574
+ ccxtFn = null;
575
+ detachedValue = null;
576
+ executeInFlight = false;
429
577
  }
430
- if (fetchFn) fetchFn = null;
431
- if (ccxtFn) ccxtFn = null;
432
- return __liftString(result);
433
578
  },
579
+ /**
580
+ * Reads the connector configuration schema from wasm.
581
+ * @returns The lifted configuration payload.
582
+ */
434
583
  config() {
435
584
  if (!WASM_EXPORTS["config"])
436
585
  throw new Error("Unable to call .config on wasm module. Are you sure this is a data connector?");
437
- return __liftString(WASM_EXPORTS.config());
586
+ return withPinScope(() => __liftString(WASM_EXPORTS.config()));
438
587
  },
588
+ /**
589
+ * Reads the connector transform from wasm.
590
+ * @returns The lifted transform payload.
591
+ */
439
592
  transform() {
440
593
  if (!WASM_EXPORTS["transform"])
441
594
  throw new Error("Unable to call .transform on wasm module. Are you sure this is a data connector?");
442
- return __liftString(WASM_EXPORTS.transform());
595
+ return withPinScope(() => __liftString(WASM_EXPORTS.transform()));
443
596
  },
597
+ /**
598
+ * Resets wasm module state when supported.
599
+ */
444
600
  reset() {
445
601
  if (WASM_EXPORTS["reset"]) WASM_EXPORTS.reset();
446
602
  }
@@ -459,6 +615,48 @@ function instantiate(module2, imports = {}, runtime = {}) {
459
615
  return 0;
460
616
  }
461
617
  }
618
+ function lowerArgs(values) {
619
+ const loweredArgs = new Array(values.length);
620
+ for (let i = 0; i < values.length; i++) {
621
+ loweredArgs[i] = __lower(values[i]);
622
+ }
623
+ return loweredArgs;
624
+ }
625
+ function snapshotLogicalArgs(values) {
626
+ return values.map((value) => {
627
+ if (value instanceof ArrayBuffer) {
628
+ return value.slice(0);
629
+ }
630
+ return value;
631
+ });
632
+ }
633
+ function executeWithReplayArgs(values) {
634
+ return withPinScope(() => WASM_EXPORTS.execute(...lowerArgs(values)));
635
+ }
636
+ function withPinScope(fn) {
637
+ pinScopes.push([]);
638
+ try {
639
+ return fn();
640
+ } finally {
641
+ const scope = pinScopes.pop() || [];
642
+ for (let i = scope.length - 1; i >= 0; i--) {
643
+ WASM_EXPORTS.__unpin(scope[i]);
644
+ }
645
+ }
646
+ }
647
+ function withAutoPinScope(fn) {
648
+ if (pinScopes.length > 0) {
649
+ return fn();
650
+ }
651
+ return withPinScope(fn);
652
+ }
653
+ function trackPinnedPointer(ptr) {
654
+ const scope = pinScopes[pinScopes.length - 1];
655
+ if (scope) {
656
+ scope.push(ptr);
657
+ }
658
+ return ptr;
659
+ }
462
660
  function __liftString(ptr) {
463
661
  if (!ptr) return null;
464
662
  const end = ptr + new Uint32Array(WASM_MEMORY.buffer)[ptr - 4 >>> 2] >>> 1;
@@ -471,7 +669,7 @@ function instantiate(module2, imports = {}, runtime = {}) {
471
669
  function __lowerString(value) {
472
670
  if (value == null) return 0;
473
671
  const length = value.length;
474
- const ptr = WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << 1, 2) >>> 0);
672
+ const ptr = trackPinnedPointer(WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << 1, 2) >>> 0));
475
673
  const memoryU16 = new Uint16Array(WASM_MEMORY.buffer);
476
674
  for (let i = 0; i < length; ++i) memoryU16[(ptr >>> 1) + i] = value.charCodeAt(i);
477
675
  return ptr;
@@ -482,7 +680,7 @@ function instantiate(module2, imports = {}, runtime = {}) {
482
680
  }
483
681
  function __lowerBuffer(value) {
484
682
  if (value == null) return 0;
485
- const ptr = WASM_EXPORTS.__pin(WASM_EXPORTS.__new(value.byteLength, 1) >>> 0);
683
+ const ptr = trackPinnedPointer(WASM_EXPORTS.__pin(WASM_EXPORTS.__new(value.byteLength, 1) >>> 0));
486
684
  new Uint8Array(WASM_MEMORY.buffer).set(new Uint8Array(value), ptr);
487
685
  return ptr;
488
686
  }
@@ -497,7 +695,7 @@ function instantiate(module2, imports = {}, runtime = {}) {
497
695
  function __lowerStaticArray(lowerElement, id, align, values, typedConstructor = null) {
498
696
  if (values == null) return 0;
499
697
  const length = values.length;
500
- const buffer = WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << align, id)) >>> 0;
698
+ const buffer = trackPinnedPointer(WASM_EXPORTS.__pin(WASM_EXPORTS.__new(length << align, id)) >>> 0) >>> 0;
501
699
  if (typedConstructor) {
502
700
  new typedConstructor(WASM_MEMORY.buffer, buffer, length).set(values);
503
701
  } else {