Use async functions in wasm imports (#28)

* Use async functions in wasm imports

* Complete implementing asyncify with assemblyscript loader
This commit is contained in:
nikugogoi 2021-10-05 17:52:51 +05:30 committed by nabarun
parent bf54e85d05
commit f34d83c04b
12 changed files with 189 additions and 108 deletions

View File

@ -1 +1,2 @@
require: 'ts-node/register'
timeout: 5000

View File

@ -34,10 +34,21 @@ import {
// Wrapped
} from '@graphprotocol/graph-ts';
/* eslint-disable @typescript-eslint/no-namespace */
export declare namespace test {
export function asyncMethod(): i32;
}
export function callGraphAPI (): void {
log.debug('hello {}', ['world']);
}
export function callAsyncMethod (): void {
log.debug('calling async method', []);
const res = test.asyncMethod();
log.debug('res after async: {}', [res.toString()]);
}
export class Foo {
static getFoo (): Foo {
return new Foo();
@ -49,3 +60,15 @@ export class Foo {
}
export const FooID = idof<Foo>();
export class Bar {
prop: string
constructor (prop: string) {
this.prop = prop;
}
getProp (): string {
return this.prop;
}
}

View File

@ -7,7 +7,6 @@
"@graphprotocol/graph-ts": "^0.22.0",
"@typescript-eslint/eslint-plugin": "^4.25.0",
"@typescript-eslint/parser": "^4.25.0",
"assemblyscript": "^0.19.16",
"eslint": "^7.27.0",
"eslint-config-semistandard": "^15.0.1",
"eslint-config-standard": "^16.0.3",
@ -23,12 +22,12 @@
"scripts": {
"lint": "eslint .",
"build": "tsc",
"asbuild:debug": "asc assembly/index.ts --lib ./node_modules --exportRuntime --target debug",
"asbuild:release": "asc assembly/index.ts --lib ./node_modules --exportRuntime --target release",
"asbuild:debug": "asc assembly/index.ts --lib ./node_modules --exportRuntime --target debug --runPasses asyncify",
"asbuild:release": "asc assembly/index.ts --lib ./node_modules --exportRuntime --target release --runPasses asyncify",
"asbuild": "yarn asbuild:debug && yarn asbuild:release",
"test": "yarn asbuild:debug && mocha src/**/*.test.ts"
},
"dependencies": {
"@assemblyscript/loader": "^0.19.16"
"assemblyscript": "https://github.com/vulcanize/assemblyscript.git#ng-integrate-asyncify"
}
}

View File

@ -16,7 +16,7 @@ describe('call handler in mapping code', () => {
exports = instance.exports;
});
it('should execute the handler function', () => {
it('should execute the handler function', async () => {
const {
_start,
__newString,
@ -35,33 +35,33 @@ describe('call handler in mapping code', () => {
_start();
// Create dummy block data.
const block = new ethereum.Block(
Bytes.empty(),
Bytes.empty(),
Bytes.empty(),
Address.zero(),
Bytes.empty(),
Bytes.empty(),
Bytes.empty(),
BigInt.fromI32(0),
BigInt.fromI32(0),
BigInt.fromI32(0),
BigInt.fromI32(0),
BigInt.fromI32(0),
BigInt.fromI32(0),
const block = await ethereum.Block.__new(
await Bytes.empty(),
await Bytes.empty(),
await Bytes.empty(),
await Address.zero(),
await Bytes.empty(),
await Bytes.empty(),
await Bytes.empty(),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
null
);
// Create dummy transaction data.
const transaction = new ethereum.Transaction(
Bytes.empty(),
BigInt.fromI32(0),
Address.zero(),
const transaction = await ethereum.Transaction.__new(
await Bytes.empty(),
await BigInt.fromI32(0),
await Address.zero(),
null,
BigInt.fromI32(0),
BigInt.fromI32(0),
BigInt.fromI32(0),
Bytes.empty()
await BigInt.fromI32(0),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
await Bytes.empty()
);
// Create event params data.
@ -78,19 +78,20 @@ describe('call handler in mapping code', () => {
}
];
const eventParamArray = eventParamsData.map(data => {
const eventParamArrayPromise = eventParamsData.map(async data => {
const { name, value, kind } = data;
let ethValue;
switch (kind) {
case 'uint': {
const bigIntString = __newString(value.toString());
ethValue = ethereum.Value.fromUnsignedBigInt(BigInt.fromString(bigIntString));
const bigIntString = await (await __newString(value.toString()));
const bigInt = await BigInt.fromString(bigIntString);
ethValue = await ethereum.Value.fromUnsignedBigInt(bigInt);
break;
}
case 'string': {
ethValue = ethereum.Value.fromString(__newString(value));
ethValue = await ethereum.Value.fromString(await __newString(value));
break;
}
@ -98,28 +99,29 @@ describe('call handler in mapping code', () => {
break;
}
return new ethereum.EventParam(
__newString(name),
return ethereum.EventParam.__new(
await __newString(name),
ethValue
);
});
const eventParams = __newArray(idOfType(TypeId.ArrayEventParam), eventParamArray);
const eventParamArray = await Promise.all(eventParamArrayPromise);
const eventParams = await __newArray(await idOfType(TypeId.ArrayEventParam), eventParamArray);
// Dummy contract address string.
const addStrPtr = __newString('0xCA6D29232D1435D8198E3E5302495417dD073d61');
const addStrPtr = await __newString('0xCA6D29232D1435D8198E3E5302495417dD073d61');
// Create Test event to be passed to handler.
const test = new Test(
Address.fromString(addStrPtr),
BigInt.fromI32(0),
BigInt.fromI32(0),
const test = await Test.__new(
await Address.fromString(addStrPtr),
await BigInt.fromI32(0),
await BigInt.fromI32(0),
null,
block,
transaction,
eventParams
);
handleTest(test);
await handleTest(test);
});
});

View File

@ -6,7 +6,7 @@ import path from 'path';
import { instantiate } from './index';
describe('eden wasm loader tests', () => {
xdescribe('eden wasm loader tests', () => {
it('should load the subgraph network wasm', async () => {
const filePath = path.resolve(__dirname, '../test/subgraph/eden/EdenNetwork/EdenNetwork.wasm');
await instantiate(filePath);

View File

@ -15,13 +15,13 @@ describe('eth-call wasm tests', () => {
exports = instance.exports;
});
it('should execute exported function', () => {
it('should execute exported function', async () => {
const { _start, testEthCall } = exports;
// Important to call _start for built subgraphs on instantiation!
// TODO: Check api version https://github.com/graphprotocol/graph-node/blob/6098daa8955bdfac597cec87080af5449807e874/runtime/wasm/src/module/mod.rs#L533
_start();
testEthCall();
await testEthCall();
});
});

View File

@ -23,23 +23,31 @@ describe('wasm loader tests', () => {
callGraphAPI();
});
it('should execute async function', async () => {
const { callAsyncMethod } = exports;
await callAsyncMethod();
});
it('should use a class/instance created in wasm from JS', async () => {
const { Foo, __getString, __pin, __unpin } = exports;
const fooPtr = __pin(Foo.getFoo());
const fooPtr = await __pin(await Foo.getFoo());
const foo = Foo.wrap(fooPtr);
const strPtr = foo.getString();
const strPtr = await foo.getString();
expect(__getString(strPtr)).to.equal('hello world!');
__unpin(fooPtr);
await __unpin(fooPtr);
});
it('should instantiate a class in wasm from JS', async () => {
const { Foo, FooID, __getString, __new, __pin, __unpin } = exports;
const { Foo, FooID, Bar, __getString, __new, __pin, __unpin, __newString } = exports;
const fooPtr = __pin(__new(FooID));
const fooPtr = await __pin(await __new(FooID));
const foo = Foo.wrap(fooPtr);
const strPtr = foo.getString();
const strPtr = await foo.getString();
expect(__getString(strPtr)).to.equal('hello world!');
__unpin(fooPtr);
const bar = await Bar.__new(await __newString('test'));
expect(__getString(await bar.prop)).to.equal('test');
});
});

View File

@ -3,7 +3,7 @@
//
import fs from 'fs/promises';
import loader from '@assemblyscript/loader';
import loader from 'assemblyscript/lib/loader';
import {
utils,
BigNumber
@ -22,7 +22,7 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
const buffer = await fs.readFile(filePath);
// const provider = getDefaultProvider(NETWORK_URL);
const imports = {
const imports: WebAssembly.Imports = {
index: {
'store.get': () => {
console.log('store.get');
@ -80,7 +80,7 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
},
'log.log': (_: number, msg: number) => {
console.log('console.log', __getString(msg));
console.log('log.log', __getString(msg));
},
// 'dataSource.create': () => {
@ -88,18 +88,38 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
// },
'dataSource.address': () => {
console.log('dataSource.address');
},
'test.asyncMethod': async () => {
console.log('before timer start');
await new Promise(resolve => {
setTimeout(() => {
resolve(1);
}, 3000);
});
console.log('after timer complete');
return 123;
}
},
ethereum: {
'ethereum.call': (call: number) => {
const smartContractCall = ethereum.SmartContractCall.wrap(call);
'ethereum.call': async (call: number) => {
const smartContractCall = await ethereum.SmartContractCall.wrap(call);
const contractAddress = Address.wrap(smartContractCall.contractAddress);
const contractName = __getString(smartContractCall.contractName);
const functionName = __getString(smartContractCall.functionName);
const functionSignature = __getString(smartContractCall.functionSignature);
const functionParams = __getArray(smartContractCall.functionParams);
console.log('ethereum.call params', __getString(contractAddress.toHexString()), contractName, functionName, functionSignature, functionParams);
const contractAddress = await Address.wrap(await smartContractCall.contractAddress);
const contractName = __getString(await smartContractCall.contractName);
const functionName = __getString(await smartContractCall.functionName);
const functionSignature = __getString(await smartContractCall.functionSignature);
const functionParams = __getArray(await smartContractCall.functionParams);
console.log(
'ethereum.call params',
__getString(await contractAddress.toHexString()),
contractName,
functionName,
functionSignature,
functionParams
);
// TODO: Get ABI according to contractName.
// const contract = new Contract(__getString(contractAddress.toHexString()), exampleAbi, provider);
@ -113,14 +133,15 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
result = [result];
}
const resultPtrArray = result.map((value: any) => {
const resultPtrArrayPromise = result.map(async (value: any) => {
// TODO: Create Value instance according to type.
const ethValue = ethereum.Value.fromString(__newString(value));
const ethValue = await ethereum.Value.fromString(await __newString(value));
return ethValue;
});
const res = __newArray(getIdOfType(TypeId.ArrayEthereumValue), resultPtrArray);
const resultPtrArray: any[] = await Promise.all(resultPtrArrayPromise);
const res = await __newArray(await getIdOfType(TypeId.ArrayEthereumValue), resultPtrArray);
return res;
} catch (err) {
@ -130,12 +151,12 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
}
},
conversion: {
'typeConversion.stringToH160': (s: number) => {
'typeConversion.stringToH160': async (s: number) => {
const string = __getString(s);
const address = utils.getAddress(string);
const byteArray = utils.arrayify(address);
const uint8ArrayId = getIdOfType(TypeId.Uint8Array);
const uint8ArrayId = await getIdOfType(TypeId.Uint8Array);
const ptr = __newArray(uint8ArrayId, byteArray);
return ptr;
@ -152,10 +173,10 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
console.log('index typeConversion.bigIntToHex');
},
'typeConversion.bytesToHex': (bytes: number) => {
'typeConversion.bytesToHex': async (bytes: number) => {
const byteArray = __getArray(bytes);
const hexString = utils.hexlify(byteArray);
const ptr = __newString(hexString);
const ptr = await __newString(hexString);
return ptr;
},
@ -196,19 +217,19 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
console.log('bigDecimal.times');
},
'bigInt.fromString': (s: number) => {
'bigInt.fromString': async (s: number) => {
const string = __getString(s);
const bigNumber = BigNumber.from(string);
const hex = bigNumber.toHexString();
const bytes = utils.arrayify(hex);
const uint8ArrayId = getIdOfType(TypeId.Uint8Array);
const ptr = __newArray(uint8ArrayId, bytes);
const bigInt = BigInt.fromSignedBytes(ptr);
const uint8ArrayId = await getIdOfType(TypeId.Uint8Array);
const ptr = await __newArray(uint8ArrayId, bytes);
const bigInt = await BigInt.fromSignedBytes(ptr);
return bigInt;
},
'bigInt.plus': (x: number, y: number) => {
'bigInt.plus': async (x: number, y: number) => {
const xBigIntArray = __getArray(x);
const xBigNumber = BigNumber.from(xBigIntArray);
@ -216,12 +237,12 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
const yBigNumber = BigNumber.from(yBigIntArray);
const sum = xBigNumber.add(yBigNumber);
const ptr = __newString(sum.toString());
const sumBigInt = BigInt.fromString(ptr);
const ptr = await __newString(sum.toString());
const sumBigInt = await BigInt.fromString(ptr);
return sumBigInt;
},
'bigInt.minus': (x: number, y: number) => {
'bigInt.minus': async (x: number, y: number) => {
const xBigIntArray = __getArray(x);
const xBigNumber = BigNumber.from(xBigIntArray);
@ -229,7 +250,7 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
const yBigNumber = BigNumber.from(yBigIntArray);
const diff = xBigNumber.sub(yBigNumber);
const ptr = __newString(diff.toString());
const ptr = await __newString(diff.toString());
const sumBigInt = BigInt.fromString(ptr);
return sumBigInt;
@ -265,8 +286,8 @@ export const instantiate = async (filePath: string): Promise<loader.ResultObject
};
const instance = await loader.instantiate(buffer, imports);
const { exports } = instance;
const exports = instance.exports;
const { __getString, __newString, __getArray, __newArray } = exports;
const getIdOfType: idOfType = exports.id_of_type as idOfType;

View File

@ -23,24 +23,24 @@ describe('numbers wasm tests', () => {
_start();
});
it('should execute bigInt fromString API', () => {
it('should execute bigInt fromString API', async () => {
const { testBigIntFromString, __getString } = exports;
const ptr = testBigIntFromString();
const ptr = await testBigIntFromString();
expect(__getString(ptr)).to.equal('123');
});
it('should execute bigInt plus API', () => {
it('should execute bigInt plus API', async () => {
const { testBigIntPlus, __getString } = exports;
const ptr = testBigIntPlus();
const ptr = await testBigIntPlus();
expect(__getString(ptr)).to.equal('200');
});
it('should execute bigInt minus API', () => {
it('should execute bigInt minus API', async () => {
const { testBigIntMinus, __getString } = exports;
const ptr = testBigIntMinus();
const ptr = await testBigIntMinus();
expect(__getString(ptr)).to.equal('100');
});

View File

@ -23,24 +23,24 @@ describe('typeConversion wasm tests', () => {
_start();
});
it('should execute typeConversion bytesToHex API', () => {
it('should execute typeConversion bytesToHex API', async () => {
const { testBytesToHex, __getString } = exports;
const ptr = testBytesToHex();
const ptr = await testBytesToHex();
expect(__getString(ptr)).to.equal('0x231a');
});
it('should execute typeConversion bigIntToString API', () => {
it('should execute typeConversion bigIntToString API', async () => {
const { testBigIntToString, __getString } = exports;
const ptr = testBigIntToString();
const ptr = await testBigIntToString();
expect(__getString(ptr)).to.equal('1000000000000000000');
});
it('should execute typeConversion stringToH160 API', () => {
it('should execute typeConversion stringToH160 API', async () => {
const { testStringToH160, __getString } = exports;
const ptr = testStringToH160();
const ptr = await testStringToH160();
expect(__getString(ptr)).to.equal('0xafad925b5eae1e370196cba39893e858ff7257d5');
});
});

View File

@ -5,7 +5,6 @@ import {
BigDecimal,
BigInt,
ethereum,
Value,
Address,
Bytes
} from '@graphprotocol/graph-ts';
@ -20,7 +19,6 @@ export {
ethereum,
Value,
Address,
Bytes,

View File

@ -65,11 +65,6 @@
http-errors "^1.7.3"
object-path "^0.11.4"
"@assemblyscript/loader@^0.19.16":
version "0.19.16"
resolved "https://registry.yarnpkg.com/@assemblyscript/loader/-/loader-0.19.16.tgz#481063138724deef314dc0930714eebf39117683"
integrity sha512-Skp0eLY3oP2YfAxaHq4IpsUZQOpllkBB0dNDrhck42mGQTimAJ6KegXMuFVa9PIP6gw3bDlCs2iIegfGnXiuFg==
"@babel/code-frame@7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
@ -3440,7 +3435,7 @@ array.prototype.flat@^1.2.4:
define-properties "^1.1.3"
es-abstract "^1.18.0-next.1"
arrify@^1.0.1:
arrify@^1.0.0, arrify@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d"
integrity sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=
@ -3480,13 +3475,15 @@ assemblyscript@0.19.10:
binaryen "101.0.0-nightly.20210723"
long "^4.0.0"
assemblyscript@^0.19.16:
version "0.19.16"
resolved "https://registry.yarnpkg.com/assemblyscript/-/assemblyscript-0.19.16.tgz#fc06c9892755775e8e31a59249fbc361fd49e1d1"
integrity sha512-AMNdwcat+EEsxjkVQ5vOE/lDbXBvy1swQKAuMG2Ken+DZufZH7wKHIAVKR5liteW/jLL3T971l1MN+onP/bixA==
"assemblyscript@https://github.com/vulcanize/assemblyscript.git#ng-integrate-asyncify":
version "0.0.0"
resolved "https://github.com/vulcanize/assemblyscript.git#ccbd560972503ecef05b43e0c7f694f97d42959f"
dependencies:
binaryen "101.0.0-nightly.20210904"
asyncify-wasm "^1.2.1"
binaryen "101.0.0-nightly.20210723"
long "^4.0.0"
source-map-support "^0.5.19"
ts-node "^6.2.0"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
@ -3546,6 +3543,11 @@ async@^2.0.1, async@^2.1.2, async@^2.4.0, async@^2.5.0, async@^2.6.1:
dependencies:
lodash "^4.17.14"
asyncify-wasm@^1.2.1:
version "1.2.1"
resolved "https://registry.yarnpkg.com/asyncify-wasm/-/asyncify-wasm-1.2.1.tgz#a15c0480e858619a4f971e44e6fc05c49015d9e8"
integrity sha512-ZS7tZ8H8EVbUxAZnkKHvMt9UkYoALue2jwrVl7cnLByjq+1MRrbq7rL5TS+EHQduwkfXD/cNZNa+I0ZyLEBBRQ==
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
@ -4181,11 +4183,6 @@ binaryen@101.0.0-nightly.20210723:
resolved "https://registry.yarnpkg.com/binaryen/-/binaryen-101.0.0-nightly.20210723.tgz#b6bb7f3501341727681a03866c0856500eec3740"
integrity sha512-eioJNqhHlkguVSbblHOtLqlhtC882SOEPKmNFZaDuz1hzQjolxZ+eu3/kaS10n3sGPONsIZsO7R9fR00UyhEUA==
binaryen@101.0.0-nightly.20210904:
version "101.0.0-nightly.20210904"
resolved "https://registry.yarnpkg.com/binaryen/-/binaryen-101.0.0-nightly.20210904.tgz#58a7990d6d64b16567f376a1fe47d8aea6698b14"
integrity sha512-2AvJhErttuoMvgNcYPPpPy7C12PSvDdtZWtEeX/Otm/Vtf4ePvBpT3UIA00hGAh8HNaGr+dzFNstxTUvjNwZTg==
bip39@2.5.0:
version "2.5.0"
resolved "https://registry.yarnpkg.com/bip39/-/bip39-2.5.0.tgz#51cbd5179460504a63ea3c000db3f787ca051235"
@ -4376,6 +4373,11 @@ buffer-from@^1.0.0:
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef"
integrity sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==
buffer-from@^1.1.0:
version "1.1.2"
resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
buffer-to-arraybuffer@^0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/buffer-to-arraybuffer/-/buffer-to-arraybuffer-0.0.5.tgz#6064a40fa76eb43c723aba9ef8f6e1216d10511a"
@ -5689,7 +5691,7 @@ dicer@0.3.0:
dependencies:
streamsearch "0.1.2"
diff@3.5.0:
diff@3.5.0, diff@^3.1.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12"
integrity sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==
@ -12745,6 +12747,14 @@ source-map-support@^0.5.13, source-map-support@^0.5.17:
buffer-from "^1.0.0"
source-map "^0.6.0"
source-map-support@^0.5.19, source-map-support@^0.5.6:
version "0.5.20"
resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.20.tgz#12166089f8f5e5e8c56926b377633392dd2cb6c9"
integrity sha512-n1lZZ8Ve4ksRqizaBQgxXDgKwttHDhyfQjA6YZZn8+AroHbsIz+JjwxQDxbp+7y5OYCI8t1Yk7etjD9CRd2hIw==
dependencies:
buffer-from "^1.0.0"
source-map "^0.6.0"
source-map-url@^0.4.0:
version "0.4.1"
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.1.tgz#0af66605a745a5a2f91cf1bbf8a7afbc283dec56"
@ -13502,6 +13512,20 @@ ts-node@^10.2.1:
make-error "^1.1.1"
yn "3.1.1"
ts-node@^6.2.0:
version "6.2.0"
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-6.2.0.tgz#65a0ae2acce319ea4fd7ac8d7c9f1f90c5da6baf"
integrity sha512-ZNT+OEGfUNVMGkpIaDJJ44Zq3Yr0bkU/ugN1PHbU+/01Z7UV1fsELRiTx1KuQNvQ1A3pGh3y25iYF6jXgxV21A==
dependencies:
arrify "^1.0.0"
buffer-from "^1.1.0"
diff "^3.1.0"
make-error "^1.1.1"
minimist "^1.2.0"
mkdirp "^0.5.1"
source-map-support "^0.5.6"
yn "^2.0.0"
tsconfig-paths@^3.9.0:
version "3.9.0"
resolved "https://registry.yarnpkg.com/tsconfig-paths/-/tsconfig-paths-3.9.0.tgz#098547a6c4448807e8fcb8eae081064ee9a3c90b"
@ -14762,6 +14786,11 @@ yn@3.1.1:
resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50"
integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==
yn@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/yn/-/yn-2.0.0.tgz#e5adabc8acf408f6385fc76495684c88e6af689a"
integrity sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=
yocto-queue@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"