Last updated
Last updated
Up until now, subgraphs have been using one of the (v0.6). Finally we've added support for the (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 theapiVersion
specified in the subgraph manifest.
TypedArray
s can now be built from ArrayBuffer
s by using the ()
New standard library functions: String#toUpperCase
, String#toLowerCase
, String#localeCompare
and TypedArray#set
()
Added support for x instanceof GenericClass ()
Added StaticArray<T>
, a more efficient array variant ()
Added Array<T>#flat
()
Implemented radix
argument on Number#toString
()
Added support for separators in floating point literals ()
Added support for first class functions ()
Add builtins: i32/i64/f32/f64.add/sub/mul
()
Implement Array/TypedArray/String#at
()
Added support for template literal strings ()
Add encodeURI(Component)
and decodeURI(Component)
()
Add toString
, toDateString
and toTimeString
to Date
()
Add toUTCString
for Date
()
Add nonnull/NonNullable
builtin type ()
Change your mappings apiVersion
in subgraph.yaml
to 0.0.6
:
Update the graph-cli
you're using to the latest
version by running:
Do the same for graph-ts
, but instead of installing globally, save it in your main dependencies:
Follow the rest of the guide to fix the language breaking changes.
Run codegen
and deploy
again.
On the older version of AssemblyScript, you could create code like this:
However on the newer version, because the value is nullable, it requires you to check, like this:
Or force it like this:
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.
However now this isn't possible anymore, and the compiler returns this error:
You'll need to rename your duplicate variables if you had variable shadowing.
By doing the upgrade on your subgraph, sometimes you might get errors like these:
To solve you can simply change the if
statement to something like this:
The same applies if you're doing != instead of ==.
The common way to do casting before was to just use the as
keyword, like this:
However this only works in two scenarios:
Primitive casting (between types such as u8
, i32
, bool
; eg: let b: isize = 10; b as usize
);
Upcasting on class inheritance (subclass → superclass)
Examples:
There are two scenarios where you may want to cast, but using as
/<T>var
isn't safe:
Downcasting on class inheritance (superclass → subclass)
Between two types that share a superclass
For those cases, you can use the changetype<T>
function:
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.
Also we've added a few more static methods in some types to ease casting, they are:
Bytes.fromByteArray
Bytes.fromUint8Array
BigInt.fromByteArray
ByteArray.fromBigInt
However that only works when you're doing the if
/ ternary on a variable, not on a property access, like this:
Which outputs this error:
To fix this issue, you can create a variable for that property access so that the compiler can do the nullability check magic:
If you try to sum (for example) a nullable type (from a property access) with a non nullable one, the AssemblyScript compiler instead of giving a compile time error warning that one of the values is nullable, it just compiles silently, giving chance for the code to break at runtime.
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.
If you have any code like this:
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:
Also if you have nullable properties in a GraphQL entity, like this:
And you have code similar to this:
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:
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 😉
If you export any classes with properties that are other classes (declared by you or by the standard library) like this:
The compiler will error because you either need to add an initializer for the properties that are classes, or add the !
operator:
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:
Depending on the types you're using, eg nullable ones, and how you're accessing them, you might encounter a runtime error like this one:
To actually push at the beginning you should either, initialize the Array
with size zero, like this:
Or you should mutate it via index:
This is not a direct AssemblyScript change, but you may have to update your schema.graphql
file.
Now you no longer can define fields in your types that are Non-Nullable Lists. If you have a schema like this:
You'll have to add an !
to the member of the List type, like this:
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).
Math
functions such as exp
, exp2
, log
, log2
and pow
have been replaced by faster variants ()
Slightly optimize Math.mod
()
Cache more field accesses in std Map and Set ()
Optimize for powers of two in ipow32/64
()
The type of an array literal can now be inferred from its contents ()
Updated stdlib to Unicode 13.0.0 ()
Before you could do and code like this would work:
For the nullability case we recommend taking a look at the , it will make your code cleaner 🙂
To use the you can use either if
statements or the ternary operator (?
and :
) like this:
Aligned Map#set
and Set#add
with the spec, returning this
()
Arrays no longer inherit from ArrayBufferView, but are now distinct ()
Classes initialized from object literals can no longer define a constructor ()
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
()
Coerce NaN
to false
when casting to bool
()
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) ()
Bug fix of relational string comparisons when sizes differ ()