Types
How Block Protocol data is described with SemType
IntroductionCopy link to this section
When using SemType, data is shared between applications and blocks in the form of 'entities', and each entity has a type, known as an 'entity type'.
This type describes what properties an entity has, what type of value each is expected to be, and the relationship between the entity in question and other entities.
Relationships between entities are known as 'links' and they too are entities, which means they may have properties and relations to other entities.
The system by which types are defined is SemType, a standalone specification that the Block Protocol depends on.
The type systemCopy link to this section
SemType is designed so that types are composed of re-usable, sharable parts, which can be referenced by other users and by other types.
SemType consists of three classes of elements:
- Entity types: define what properties an entity may have (which property types), and what relationships (links) it may have with other entities
- Property types: define properties that can be referenced by entity types, and their expected values, which may be a reference to data types or objects which are made up of other property types
- Data types: primitive data types, e.g. text, numbers, booleans.
Creating typesCopy link to this section
The easiest way to get started is to create a free app.hash.ai account and follow the instructions to create a new entity type. Any public types you create here will be published to the SemType registry and will be usable by Block Protocol embedders, as well as blocks themselves.
Give your entity type a name and a description, and then click 'create'.
You can now define the properties your entity expects:
- Start typing to see if a suitable property already exists (e.g. called 'Name' with an expected data type of 'Text')
- Either select an existing property type, or click 'create new' to create a new one
- If creating a new one, specify a title, description, and expected value
You can also define the links your entity expects following a similar process:
- Start typing to see if a suitable link entity type already exists (e.g. called 'Owner')
- Either select an existing link entity type, or click 'create new' to create a new one
- When creating a link entity type, you first specify a title and description
- Back on your initial entity type, you can select the link entity type as a potential link from your entity, and then constrain the destination entities of those links by defining a selection of entity types. You can also set a minimum number of such links (e.g. to make it so that entities of your type are required to have certain links).
Make sure to click 'publish update' when you're done to release a new version of the entity type.
Using typesCopy link to this section
Once you have a type which describes the data your block expects, copy the URL from your browser.
- for blocks from the
htmltemplate, you can use this as theschemaproperty in theblock-metadata.json - for blocks made from the
reactandcustom-elementtemplate, you can use this for theblockEntityTypeproperty in theblockprotocolobject inpackage.jsonor as an input for codegen (see below)
You can also view the raw JSON of any type by a simple fetch or curl:
fetch("https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2")
.then((resp) => resp.json())
.then(console.log);curl https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2TypeScript types for entitiesCopy link to this section
SemType types are representable within TypeScript, and as such it is possible to create TypeScript representations of entity types.
There is a provided codegen utility in the @blockprotocol/graph package which provides an implementation of such generation.
For relatively simple cases, a wrapper around this is exposed through block-scripts which is able to parse the metadata about your block and generate types for you.
An example usage of this is included within the react and custom-element block templates.
For react and custom-element blocks, the codegen object in package.json can be used to configure block-scripts codegen.
This is setup by default within the templates, and can be ran with yarn codegen.
The codegen object has the following:
- a field
outputFolderwhich describes the folder which will contain the files with the generated types- all contents of this folder are deleted when the codegen is run
- a field
targetswhich is an object which is a mapping of files to the types that should be generated within them- keys of
targetsare the names of the files to be generated (e.g.person.ts) - values of
targetsare an array where the items are objects which satisfy the following:- contain the key
sourceTypeIdwith a value of a SemType ID (e.g.https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2), or - contain the key
blockEntityTypewith valuetrue, which if present will generate types for the type given by theblockEntityTypeproperty in theblockprotocolobject inpackage.json, alongside type aliases for it such asBlockEntity- there can be one at most of these entries in the whole of the
codegenobject
For example:
{
"blockprotocol": {
// ...
"blockEntityType": "https://blockprotocol.org/@blockprotocol/types/entity-type/thing/v/2",
"codegen": {
"outputFolder": "src/types/generated",
"targets": {
"block-entity.ts": [
{
// generate types in `block-entity.ts` for `Thing` (specified above) as this block's `BlockEntity`
"blockEntityType": true
},
{
// generate types in `block-entity.ts` for `Person`
"sourceTypeId": "https://blockprotocol.org/@example/types/entity-type/person/v/3"
}
],
"company.ts": [
{
// generate types in `company.ts` for `Company`
"sourceTypeId": "https://blockprotocol.org/@example/types/entity-type/company/v/1"
}
]
}
}
}
}