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