Docs
Sök⌘ K
  • Home
  • Om The Graph
  • Nätverk som stöds
  • Protocol Contracts
  • Subgrafer
    • Underströmmar
      • Token API
        • AI Suite
          • Indexing
            • Resources
              Resources > Migration Guides

              10 minutes

              AssemblyScript Migrationsguide

              Up until now, Subgraphs have been using one of the first versions of AssemblyScript⁠ (v0.6). Finally we’ve added support for the newest one available⁠ (v0.19.10)! 🎉

              That will enable Subgraph developers to use newer features of the AS language and standard library.

              This guide is applicable for anyone using graph-cli/graph-ts below version 0.22.0. If you’re already at a higher than (or equal) version to that, you’ve already been using version 0.19.10 of AssemblyScript 🙂

              Note: As of 0.24.0, graph-node can support both versions, depending on the apiVersion specified in the Subgraph manifest.

              Funktioner

              Ny funktionalitet

              • TypedArrays can now be built from ArrayBuffers by using the new wrap static method⁠ (v0.8.1⁠)
              • New standard library functions: String#toUpperCase, String#toLowerCase, String#localeCompareand TypedArray#set (v0.9.0⁠)
              • Added support for x instanceof GenericClass (v0.9.2⁠)
              • Added StaticArray<T>, a more efficient array variant (v0.9.3⁠)
              • Added Array<T>#flat (v0.10.0⁠)
              • Implemented radix argument on Number#toString (v0.10.1⁠)
              • Added support for separators in floating point literals (v0.13.7⁠)
              • Added support for first class functions (v0.14.0⁠)
              • Add builtins: i32/i64/f32/f64.add/sub/mul (v0.14.13⁠)
              • Implement Array/TypedArray/String#at (v0.18.2⁠)
              • Added support for template literal strings (v0.18.17⁠)
              • Add encodeURI(Component) and decodeURI(Component) (v0.18.27⁠)
              • Add toString, toDateString and toTimeString to Date (v0.18.29⁠)
              • Add toUTCString for Date (v0.18.30⁠)
              • Add nonnull/NonNullable builtin type (v0.19.2⁠)

              Optimeringar

              • Math functions such as exp, exp2, log, log2 and pow have been replaced by faster variants (v0.9.0⁠)
              • Slightly optimize Math.mod (v0.17.1⁠)
              • Cache more field accesses in std Map and Set (v0.17.8⁠)
              • Optimize for powers of two in ipow32/64 (v0.18.2⁠)

              Annat

              • The type of an array literal can now be inferred from its contents (v0.9.0⁠)
              • Updated stdlib to Unicode 13.0.0 (v0.10.0⁠)

              Hur uppgraderar du?

              1. Change your mappings apiVersion in subgraph.yaml to 0.0.9:
              1...2dataSources:3  ...4    mapping:5      ...6      apiVersion: 0.0.97      ...
              1. Update the graph-cli you’re using to the latest version by running:
              1# om du har den globalt installerad2npm install --global @graphprotocol/graph-cli@latest34# eller i din subgraf om du har det som ett utvecklingsberoende5npm install --save-dev @graphprotocol/graph-cli@latest
              1. Do the same for graph-ts, but instead of installing globally, save it in your main dependencies:
              1npm install --save @graphprotocol/graph-ts@latest
              1. Följ resten av guiden för att åtgärda språkbrytande ändringar.
              2. Run codegen and deploy again.

              Språkbrytande ändringar

              Nullbarhet

              I den äldre versionen av AssemblyScript kunde du skapa kod som detta:

              1function load(): Value | null { ... }23let maybeValue = load();4maybeValue.aMethod();

              Men i den nyare versionen, eftersom värdet är nullable, måste du kontrollera, så här:

              1let maybeValue = load()23if (maybeValue) {4  maybeValue.aMethod() // `maybeValue` is not null anymore5}

              Eller gör så här:

              1let maybeValue = load()! // bryts i runtime om värdet är null23maybeValue.aMethod()

              If you are unsure which to choose, we recommend always using the safe version. If the value doesn’t exist you might want to just do an early if statement with a return in you Subgraph handler.

              Variabelskuggning

              Before you could do variable shadowing⁠ and code like this would work:

              1let a = 102let b = 203let a = a + b

              Men nu är detta inte längre möjligt, och kompilatorn returnerar detta fel:

              1ERROR TS2451: Cannot redeclare block-scoped variable 'a'23 let a = a + b;4 ~~~~~~~~~~~~~5in assembly/index.ts(4,3)

              Du måste döpa om dina duplicerade variabler om du hade variabelskuggning.

              Jämförelser med nollvärden

              By doing the upgrade on your Subgraph, sometimes you might get errors like these:

              1ERROR TS2322: Type '~lib/@graphprotocol/graph-ts/common/numbers/BigInt | null' is not assignable to type '~lib/@graphprotocol/graph-ts/common/numbers/BigInt'.2     if (decimals == null) {3                     ~~~~4 in src/mappings/file.ts(41,21)

              To solve you can simply change the if statement to something like this:

              1if (!decimals) {23  // or45  if (decimals === null) {

              Samma gäller om du använder != istället för ==.

              Kasting

              The common way to do casting before was to just use the as keyword, like this:

              1let byteArray = new ByteArray(10)2let uint8Array = byteArray as Uint8Array // equivalent to: <Uint8Array>byteArray

              Detta fungerar dock endast i två scenarier:

              • Primitive casting (between types such as u8, i32, bool; eg: let b: isize = 10; b as usize);
              • Uppkasting vid klassarv (underklass → överklass)

              Exempel:

              1// primitive casting2let a: usize = 103let b: isize = 54let c: usize = a + (b as usize)
              1// upcasting on class inheritance2class Bytes extends Uint8Array {}34let bytes = new Bytes(2)5// <Uint8Array>bytes // same as: bytes as Uint8Array

              There are two scenarios where you may want to cast, but using as/<T>var isn’t safe:

              • Downcasting vid arv av klasser (superklass → subklass)
              • Mellan två typer som delar en superklass
              1// downcasting on class inheritance2class Bytes extends Uint8Array {}34let uint8Array = new Uint8Array(2)5// <Bytes>uint8Array // breaks in runtime :(
              1// between two types that share a superclass2class Bytes extends Uint8Array {}3class ByteArray extends Uint8Array {}45let bytes = new Bytes(2)6// <ByteArray>bytes // breaks in runtime :(

              For those cases, you can use the changetype<T> function:

              1// downcasting on class inheritance2class Bytes extends Uint8Array {}34let uint8Array = new Uint8Array(2)5changetype<Bytes>(uint8Array) // works :)
              1// between two types that share a superclass2class Bytes extends Uint8Array {}3class ByteArray extends Uint8Array {}45let bytes = new Bytes(2)6changetype<ByteArray>(bytes) // works :)

              If you just want to remove nullability, you can keep using the as operator (or <T>variable), but make sure you know that value can’t be null, otherwise it will break.

              1// ta bort ogiltighet2let previousBalance = AccountBalance.load(balanceId) // AccountBalance | null34if (previousBalance != null) {5  return previousBalance as AccountBalance // safe remove null6}78let newBalance = new AccountBalance(balanceId)

              For the nullability case we recommend taking a look at the nullability check feature⁠, it will make your code cleaner 🙂

              Vi har också lagt till några fler statiska metoder i vissa typer för att underlätta kastning, de är:

              • Bytes.fromByteArray
              • Bytes.fromUint8Array
              • BigInt.fromByteArray
              • ByteArray.fromBigInt

              Kontroll av nollställbarhet med tillgång till egendom

              To use the nullability check feature⁠ you can use either if statements or the ternary operator (? and :) like this:

              1let something: string | null = 'data'23let somethingOrElse = something ? something : 'else'45// or67let somethingOrElse89if (something) {10  somethingOrElse = something11} else {12  somethingOrElse = 'else'13}

              However that only works when you’re doing the if / ternary on a variable, not on a property access, like this:

              1class Container {2  data: string | null3}45let container = new Container()6container.data = 'data'78let somethingOrElse: string = container.data ? container.data : 'else' // Kompilerar inte

              Vilket ger detta fel:

              1ERROR TS2322: Type '~lib/string/String | null' is not assignable to type '~lib/string/String'.23   let somethingOrElse: string = container.data ? container.data : "else";4                                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

              För att åtgärda problemet kan du skapa en variabel för den egenskapen så att kompilatorn kan utföra den magiska nollbarhetskontrollen:

              1class Container {2  data: string | null3}45let container = new Container()6container.data = 'data'78let data = container.data910let somethingOrElse: string = data ? data : 'else' // kompilerar helt okej :)

              Operatörsöverladdning med egenskapsaccess

              Om du försöker summera (till exempel) en nullable typ (från en property access) med en non nullable, kommer AssemblyScript-kompilatorn istället för att ge en kompileringsfelsvarning om att ett av värdena är nullable, bara att kompilera tyst, vilket gör att koden kan gå sönder vid körning.

              1class BigInt extends Uint8Array {2  @operator('+')3  plus(other: BigInt): BigInt {4    // ...5  }6}78class Wrapper {9  public constructor(public n: BigInt | null) {}10}1112let x = BigInt.fromI32(2)13let y: BigInt | null = null1415x + y // ge kompileringsfel om ogiltighet1617let wrapper = new Wrapper(y)1819wrapper.n = wrapper.n + x // ger inte kompileringsfel som det borde

              We’ve opened a issue on the AssemblyScript compiler for this, but for now if you do these kind of operations in your Subgraph mappings, you should change them to do a null check before it.

              1let wrapper = new Wrapper(y)23if (!wrapper.n) {4  wrapper.n = BigInt.fromI32(0)5}67wrapper.n = wrapper.n + x // nu är `n` garanterat ett BigInt

              Initialisering av värde

              Om du har någon kod som denna:

              1var value: Type // null2value.x = 103value.y = 'content'

              It will compile but break at runtime, that happens because the value hasn’t been initialized, so make sure your Subgraph has initialized their values, like this:

              1var value = new Type() // initialized2value.x = 103value.y = 'content'

              Även om du har nullable properties i en GraphQL-entitet, som denna:

              1type Total @entity {2  id: Bytes!3  amount: BigInt4}

              Och du har en kod som liknar den här:

              1let total = Total.load('latest')23if (total === null) {4  total = new Total('latest')5}67total.amount = total.amount + BigInt.fromI32(1)

              You’ll need to make sure to initialize the total.amount value, because if you try to access like in the last line for the sum, it will crash. So you either initialize it first:

              1let total = Total.load('latest')23if (total === null) {4  total = new Total('latest')5  total.amount = BigInt.fromI32(0)6}78total.tokens = total.tokens + BigInt.fromI32(1)

              Or you can just change your GraphQL schema to not use a nullable type for this property, then we’ll initialize it as zero on the codegen step 😉

              1type Total @entity {2  id: Bytes!3  amount: BigInt!4}
              1let total = Total.load('latest')23if (total === null) {4  total = new Total('latest') // initierar redan icke-nullställbara egenskaper5}67total.amount = total.amount + BigInt.fromI32(1)

              Initialisering av klassegenskaper

              Om du exporterar några klasser med egenskaper som är andra klasser (deklarerade av dig eller av standardbiblioteket) på det här sättet:

              1class Thing {}23export class Something {4  value: Thing5}

              The compiler will error because you either need to add an initializer for the properties that are classes, or add the ! operator:

              1export class Something {2  constructor(public value: Thing) {}3}45// or67export class Something {8  value: Thing910  constructor(value: Thing) {11    this.value = value12  }13}1415// or1617export class Something {18  value!: Thing19}

              Initialisering av Array

              The Array class still accepts a number to initialize the length of the list, however you should take care because operations like .push will actually increase the size instead of adding to the beginning, for example:

              1let arr = new Array<string>(5) // ["", "", "", "", ""]23arr.push('something') // ["", "", "", "", "", "something"] // size 6 :(

              Beroende på vilka typer du använder, t.ex. nullable-typer, och hur du kommer åt dem, kan du stöta på ett runtime-fel som det här:

              1ERRO Handler skipped due to execution failure, error: Mapping aborted at ~lib/array.ts, line 110, column 40, with message: Element type must be nullable if array is holey  wasm backtrace:     0: 0x19c4 - <unknown>!~lib/@graphprotocol/graph-ts/index/format         1: 0x1e75 - <unknown>!~lib/@graphprotocol/graph-ts/common/collections/Entity#constructor        2: 0x30b9 - <unknown>!node_modules/@graphprotocol/graph-ts/global/global/id_of_type

              To actually push at the beginning you should either, initialize the Array with size zero, like this:

              1let arr = new Array<string>(0) // []23arr.push('something') // ["something"]

              Eller så bör du mutera den via index:

              1let arr = new Array<string>(5) // ["", "", "", "", ""]23arr[0] = 'something' // ["something", "", "", "", ""]

              GraphQL-schema

              This is not a direct AssemblyScript change, but you may have to update your schema.graphql file.

              Nu kan du inte längre definiera fält i dina typer som är Non-Nullable Lists. Om du har ett schema som detta:

              1type Something @entity {2  id: Bytes!3}45type MyEntity @entity {6  id: Bytes!7  invalidField: [Something]! # no longer valid8}

              You’ll have to add an ! to the member of the List type, like this:

              1type Something @entity {2  id: Bytes!3}45type MyEntity @entity {6  id: Bytes!7  invalidField: [Something!]! # valid8}

              This changed because of nullability differences between AssemblyScript versions, and it’s related to the src/generated/schema.ts file (default path, you might have changed this).

              Annat

              • Aligned Map#set and Set#add with the spec, returning this (v0.9.2⁠)
              • Arrays no longer inherit from ArrayBufferView, but are now distinct (v0.10.0⁠)
              • Classes initialized from object literals can no longer define a constructor (v0.10.0⁠)
              • The result of a ** binary operation is now the common denominator integer if both operands are integers. Previously, the result was a float as if calling Math/f.pow (v0.11.0⁠)
              • Coerce NaN to false when casting to bool (v0.14.9⁠)
              • When shifting a small integer value of type i8/u8 or i16/u16, only the 3 respectively 4 least significant bits of the RHS value affect the result, analogous to the result of an i32.shl only being affected by the 5 least significant bits of the RHS value. Example: someI8 << 8 previously produced the value 0, but now produces someI8 due to masking the RHS as 8 & 7 = 0 (3 bits) (v0.17.0⁠)
              • Bug fix of relational string comparisons when sizes differ (v0.17.8⁠)
              ⁠Edit on GitHub⁠

              KurateringGraphQL Validations Migration Guide
              On this page
              • Funktioner
              • Ny funktionalitet
              • Optimeringar
              • Annat
              • Hur uppgraderar du?
              • Språkbrytande ändringar
              • Nullbarhet
              • Variabelskuggning
              • Jämförelser med nollvärden
              • Kasting
              • Kontroll av nollställbarhet med tillgång till egendom
              • Operatörsöverladdning med egenskapsaccess
              • Initialisering av värde
              • Initialisering av klassegenskaper
              • Initialisering av Array
              • GraphQL-schema
              • Annat
              The GraphStatusTestnetBrand AssetsForumSecurityPrivacy PolicyTerms of Service