Composition / foldkit-composition
Sixty seconds
ts
import { Schema } from 'effect'
import { Block, Catalog, Composition, Content, Region } from 'foldkit-composition'
const Heading = Block.define('Heading', {
Props: Schema.Struct({ text: Schema.String, level: Schema.Literals([1, 2, 3]) }),
provides: [Content.Flow],
})
const Section = Block.define('Section', {
Props: Schema.Struct({ tone: Schema.Literals(['plain', 'accent']) }),
regions: { body: Region.many({ accepts: [Content.Flow] }) },
provides: [Content.Section],
})
const Site = Catalog.make({ blocks: [Heading, Section], roots: [Content.Section] })
const page = Schema.decodeUnknownSync(Composition.Document)({
format: 1,
roots: ['intro'],
nodes: {
intro: { block: 'Section', props: { tone: 'plain' }, regions: { body: ['title'] } },
title: { block: 'Heading', props: { text: 'Hello', level: 1 }, regions: {} },
},
})
Composition.validate(Site, page) // []
Composition.describe(Site, page)
// Section intro {"tone":"plain"}
// body:
// Heading title {"level":1,"text":"Hello"}Block.defineandCatalog.makedescribe; nothing runs. A Catalog with two Blocks of one name, a Region that accepts nothing, or a Block that provides nothing throws when it is made.Composition.Documentis a Schema: the Document is plain JSON, stored in a column or a field like any other value.validatereturns what is wrong, each finding with a code, the node, a path and a sentence. It never changes the Document.