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