joule-ui-a2ui writes any registry as a JSON Schema of the nodes its ingest takes, refuses a registry that declares what no node can state, and holds a catalogue to a registry through the validated ingest. joule-ui-lang writes a library as a file. wai-app calls both on its registry; its two files are committed under widgets/, and tests/exports.rs fails while they differ from it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
400 lines
10 KiB
JSON
400 lines
10 KiB
JSON
{
|
|
"$defs": {
|
|
"App": {
|
|
"additionalProperties": false,
|
|
"description": "The app: its title and what it holds. An app holds one room (a Room, a WatchTogether or a Show), and text, receipts and an energy meter beside it.",
|
|
"properties": {
|
|
"children": {
|
|
"items": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/$defs/Room"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/WatchTogether"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Show"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Text"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Receipts"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/EnergyMeter"
|
|
}
|
|
]
|
|
},
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "App"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Chat": {
|
|
"additionalProperties": false,
|
|
"description": "The room's chat: each message a signed event, verified before it is shown. Those who joined write; those who watch read.",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Chat"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"EnergyMeter": {
|
|
"additionalProperties": false,
|
|
"description": "What each action cost in energy, and how the figure was obtained (a page has no meter, so its figures are estimates, labelled so).",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "EnergyMeter"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Participants": {
|
|
"additionalProperties": false,
|
|
"description": "Who is in the room now, from the room's signed lifecycle.",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Participants"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Player": {
|
|
"additionalProperties": false,
|
|
"description": "The room's video: each participant's camera laid out from the room's signed record, every frame checked before it is shown.",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Player"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Poll": {
|
|
"additionalProperties": false,
|
|
"description": "A vote in a Show: the lead opens it, each viewer chooses one option, and the room's clock closes it and signs the result. `options` is a list of 2 to 32 texts; `seconds` how long it stays open (5 to 300; 30 when left out).",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Poll"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"options": {
|
|
"type": "array"
|
|
},
|
|
"question": {
|
|
"type": "string"
|
|
},
|
|
"seconds": {
|
|
"type": "number"
|
|
}
|
|
},
|
|
"required": [
|
|
"options",
|
|
"question"
|
|
],
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component",
|
|
"props"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Receipts": {
|
|
"additionalProperties": false,
|
|
"description": "This page's receipts: every action a person takes here is sealed into a hash-chained log this page signs and verifies, and the room's objects checked against their receipts are counted.",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Receipts"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Room": {
|
|
"additionalProperties": false,
|
|
"description": "A live room: people join with their camera and microphone, or watch. Every audio and video object is checked against its signed receipt before it is shown. Holds a Player for the room's video and a Chat; those who join can chat, those who watch read it.",
|
|
"properties": {
|
|
"children": {
|
|
"items": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/$defs/Player"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Chat"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Participants"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Receipts"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/EnergyMeter"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Text"
|
|
}
|
|
]
|
|
},
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Room"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Show": {
|
|
"additionalProperties": false,
|
|
"description": "A show: hosts on camera, the first of them leading; an audience that watches and votes. Holds a Player for the hosts' video, a Chat for the hosts, and Polls the lead opens and the audience answers. `audience` is how many inputs each viewer may send to one poll (1 to 255; 1 when left out).",
|
|
"properties": {
|
|
"children": {
|
|
"items": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/$defs/Player"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Chat"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Poll"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Participants"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Receipts"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/EnergyMeter"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Text"
|
|
}
|
|
]
|
|
},
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Show"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"audience": {
|
|
"type": "number"
|
|
},
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"Text": {
|
|
"additionalProperties": false,
|
|
"description": "A paragraph of text.",
|
|
"properties": {
|
|
"children": {
|
|
"maxItems": 0,
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "Text"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"text": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"text"
|
|
],
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component",
|
|
"props"
|
|
],
|
|
"type": "object"
|
|
},
|
|
"WatchTogether": {
|
|
"additionalProperties": false,
|
|
"description": "A watch room: everyone watches one file together, in sync; anyone may play, pause, seek or change the speed for everyone. `source` is the file's name within the app (for example \"film.mp4\"). A watch room carries the shared controls alone: it holds no Chat and no Poll.",
|
|
"properties": {
|
|
"children": {
|
|
"items": {
|
|
"anyOf": [
|
|
{
|
|
"$ref": "#/$defs/Participants"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Receipts"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/EnergyMeter"
|
|
},
|
|
{
|
|
"$ref": "#/$defs/Text"
|
|
}
|
|
]
|
|
},
|
|
"type": "array"
|
|
},
|
|
"component": {
|
|
"const": "WatchTogether"
|
|
},
|
|
"props": {
|
|
"additionalProperties": false,
|
|
"properties": {
|
|
"source": {
|
|
"type": "string"
|
|
},
|
|
"title": {
|
|
"type": "string"
|
|
}
|
|
},
|
|
"required": [
|
|
"source"
|
|
],
|
|
"type": "object"
|
|
}
|
|
},
|
|
"required": [
|
|
"component",
|
|
"props"
|
|
],
|
|
"type": "object"
|
|
}
|
|
},
|
|
"$id": "https://git.transaction.science/Transaction-Science/open-standards/raw/branch/main/wai/wai-app/widgets/catalogue.json",
|
|
"$ref": "#/$defs/App",
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"title": "WAI widgets"
|
|
}
|