type Actor { type: ActorType! uid: String! } # actor type enum ActorType { WALL USER CLIENT_BOT CLIENT } # Element that can be attached to other elements interface Attachable { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits(key: [String!]): [Trait!] style: Style! } # web browser type Browser implements Element, Attachable, Surface { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: BrowserStyle! url: String! frameless: Boolean surface: Surface attachments(type: [ElementType!]): [Attachable] } type BrowserStyle implements Style { hidden: Boolean width: Float height: Float } input BrowserStyleInput { hidden: Boolean = false width: Float = 800 height: Float = 600 } # Rectangular area of the workspace type Canvas implements Element { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: CanvasStyle! name: String! } # color of the canvas border enum CanvasBorderColor { Blue Green Red Yellow } type CanvasStyle implements Style { hidden: Boolean width: Float height: Float borderColor: CanvasBorderColor } input CanvasStyleInput { width: Float = 1000 height: Float = 1000 borderColor: CanvasBorderColor = Red } type Cell { id: String! row: Int! column: Int! } interface Command { received: DateTime! clientId: String! actor: Actor! } # The javascript `Date` as string. Type represents date and time as the ISO Date string. scalar DateTime type DeleteCommand implements Command { received: DateTime! clientId: String! actor: Actor! id: ID! } # multipage document with navigation capabilities type Document implements Element, Attachable, Surface { # Intrinsic asset width width: Float # Intrinsic asset height height: Float # Asset title title: String # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: ElementStyle! contentType: DocumentContentType! # asset url, provided if asset download is allowed url: String surface: Surface attachments(type: [ElementType!]): [Attachable] } enum DocumentContentType { doc docx ppt pptx xls xlsx pdf unknown } # Basic workspace building block interface Element { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits(key: [String!]): [Trait!] style: Style! } type ElementStyle implements Style { hidden: Boolean } input ElementStyleInput { hidden: Boolean = false } # element type enum ElementType { Text Note Image Document Grid Browser Video Stroke Shape Canvas Group Window } # font family enum FontFamily { Dosis Helvetica Times_New_Roman Source_Code_Pro Aleo Exo_2 } # italicization enum FontStyle { normal italic } # font thickness enum FontWeight { normal bold } # Element grid type Grid implements Element { # If true, element will be "pinned" and immovable in the workspace pin: Boolean # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits(key: [String!]): [Trait!] style: GridStyle! rows: Int columns: Int cells: [Cell!] } type GridStyle implements Style { hidden: Boolean horizontalMargin: Float verticalMargin: Float cellWidth: Float cellHeight: Float } input GridStyleInput { hidden: Boolean = false horizontalMargin: Float = 0 verticalMargin: Float = 0 cellWidth: Float = 0 cellHeight: Float = 0 } # Group of elements type Group implements Element { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits(key: [String!]): [Trait!] style: ElementStyle! children: [Element] } # Image asset type Image implements Attachable, Surface, Element { # Intrinsic asset width width: Float # Intrinsic asset height height: Float # Asset title title: String # If true, element will be "pinned" and immovable in the workspace pin: Boolean # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: ElementStyle! contentType: ImageContentType! surface: Surface attachments(type: [ElementType!]): [Attachable] # asset url, provided if asset download is allowed url(scale: ImageScale): String } enum ImageContentType { jpeg gif png tiff unknown } enum ImageScale { Original High Medium Low } # The `JSON` scalar type represents JSON values as specified by [ECMA-404](http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf). scalar JSON type MergeCommand implements Command { received: DateTime! clientId: String! actor: Actor! merge: MergeElementInput! } interface MergeElementInput { # Workspace-unique element id id: ID! zIndex: Int transform: Transform } type Mutation { delete(id: String!, workspace: String!): String! newUpload(in: UploadInput, workspace: String!): Upload! newCanvas(workspace: String!, in: NewCanvasInput!): Canvas! newStroke(workspace: String!, in: NewStrokeInput!): Stroke! newNote(workspace: String!, in: NewNoteInput!): Note! newText(workspace: String!, in: NewTextInput!): Text! newWindow(workspace: String!, in: NewWindowInput!): Window! newGrid(workspace: String!, in: NewGridInput!): Grid! newVideo(workspace: String!, in: NewVideoInput!): Video! newBrowser(workspace: String!, in: NewBrowserInput!): Browser! newImage(workspace: String!, in: NewImageInput!): Image! newDocument(workspace: String!, in: NewDocumentInput!): Document! newShape(workspace: String!, in: NewShapeInput!): Shape! } input NewBrowserInput { traits: [TraitInput!] transform: TransformInput style: BrowserStyleInput url: String! frameless: Boolean } input NewCanvasInput { traits: [TraitInput!] transform: TransformInput style: CanvasStyleInput name: String! } type NewCommand implements Command { received: DateTime! clientId: String! actor: Actor! new: Element! } input NewDocumentInput { traits: [TraitInput!] transform: TransformInput width: Float! height: Float! # Workspace-unique element id assigned on upload uploadId: String! style: ElementStyleInput contentType: DocumentContentType! } input NewGridInput { traits: [TraitInput!] transform: TransformInput style: GridStyleInput rows: Int = 0 columns: Int = 0 } input NewImageInput { traits: [TraitInput!] transform: TransformInput width: Float! height: Float! # Workspace-unique element id assigned on upload uploadId: String! style: ElementStyleInput url: String title: String! contentType: ImageContentType! } input NewNoteInput { traits: [TraitInput!] transform: TransformInput style: NoteStyleInput text: String! } input NewShapeInput { traits: [TraitInput!] transform: TransformInput style: ShapeStyleInput geometry: ShapeGeometry! mirrorX: Boolean mirrorY: Boolean # shape locations as a list of pairs, where coordinates are paired '[x, y, x, y]' in an array points: [Float!] } input NewStrokeInput { traits: [TraitInput!] transform: TransformInput style: StrokeStyleInput points: [Float!]! } input NewTextInput { traits: [TraitInput!] transform: TransformInput style: TextStyleInput text: String! } input NewVideoInput { traits: [TraitInput!] transform: TransformInput width: Float! height: Float! # Workspace-unique element id assigned on upload uploadId: String! style: ElementStyleInput } input NewWindowInput { traits: [TraitInput!] transform: TransformInput style: ElementStyleInput } # Note card type Note implements Element, Attachable, Surface { # If true, element will be "pinned" and immovable in the workspace pin: Boolean # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: NoteStyle! width: Float height: Float # Note content text: String! surface: Surface attachments(type: [ElementType!]): [Attachable] } type NoteStyle implements Style { hidden: Boolean # font size in pixels fontSize: Int fontWeight: FontWeight textTransform: TextTransform backgroundColor: String } input NoteStyleInput { fontWeight: FontWeight = normal textTransform: TextTransform = none backgroundColor: String = "none" } type Query { elements( workspace: String! # Restrict output to elements with traits matching these traits traits: [TraitInput!] # id of the canvas in which the elements are included canvas: String # id of the element. When canvas is specified the element will exist in the bounds of the canvas id: String type: [ElementType!] viewport: Viewport # retrieve element state as of the specified moment in time asof: DateTime ): [Element] } # Predefined shape type Shape implements Element { # If true, element will be "pinned" and immovable in the workspace pin: Boolean # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: ShapeStyle! # predefined shape geometry: ShapeGeometry! # text on shape text: String # if true, flip the predefined shape around the X-axis mirrorX: Boolean # if true, flip the predefined shape around the Y-axis mirrorY: Boolean # shape locations as a list of pairs, where coordinates are paired '[x, y, x, y, ...]' in an array points: [Float!]! } # one of None, ArrowFill, ArrowStroke, Tee, Circle enum ShapeCapStyle { None ArrowFill ArrowStroke Tee Circle } enum ShapeGeometry { Line Rectangle Ellipse Diamond Circle TriangleUp TriangleRight ArrowUp ArrowRight ArrowUpDown ArrowLeftRight ArrowAll ArrowRightCurve ArrowRightU } # one of Solid, Dot, DashShort, DashLong enum ShapeStrokeStyle { Solid Dot DashShort DashLong } type ShapeStyle implements Style { hidden: Boolean width: Float height: Float strokeWidth: Float strokeColor: [Float!] fillColor: [Float!] strokeStyle: ShapeStrokeStyle startCap: ShapeCapStyle endCap: ShapeCapStyle } input ShapeStyleInput { width: Float = 0 height: Float = 0 strokeWidth: Float = 0 strokeColor: [Float!] = [0, 0, 0, 0] fillColor: [Float!] = [0, 0, 0, 0] strokeStyle: ShapeStrokeStyle = Solid startCap: ShapeCapStyle = None endCap: ShapeCapStyle = None } # freehand stroke type Stroke implements Element, Attachable { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: StrokeStyle! # stroke locations as a list of pairs, # where coordinates are paired '[x, y, x, y, x, y, ...]' in an array, # in the coordinate space of the containing object points: [Float!]! surface: Surface } enum StrokeBrush { Pen Eraser } enum StrokeColor { White Gray Yellow Red Green Purple Cyan } type StrokeStyle implements Style { hidden: Boolean color: StrokeColor strokeWidth: Float brushType: StrokeBrush } input StrokeStyleInput { color: StrokeColor = White strokeWidth: Float = 1 brushType: StrokeBrush = Pen } interface Style { hidden: Boolean } type Subscription { history(workspace: String!): Command! } # Element to which other elements can be attached interface Surface { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits(key: [String!]): [Trait!] style: Style! } # Freeform text type Text implements Element, Attachable { # If true, element will be "pinned" and immovable in the workspace pin: Boolean # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: TextStyle! # characters text: String! surface: Surface } type TextStyle implements Style { hidden: Boolean width: Float height: Float fontWeight: FontWeight textTransform: TextTransform # font size in pixels fontSize: Int fontFamily: FontFamily fontStyle: FontStyle color: String backgroundColor: String } input TextStyleInput { width: Float = 265 height: Float = 75 fontWeight: FontWeight = normal textTransform: TextTransform = none # font size in pixels fontSize: Int = 64 fontFamily: FontFamily = Dosis fontStyle: FontStyle = normal color: String = "white" backgroundColor: String = "none" } # text transform enum TextTransform { none uppercase } # Key-value pair describing arbitrary metadata in JSON-LD format, attached to an element type Trait { # Property name, conforming to JSON-LD, structured as an URI key: String! # Property value, in JSON-LD format value: JSON } input TraitInput { # trait name key: String! # JSON-LD vocabulary, https://json-ld.org/spec/latest/json-ld/#default-vocabulary vocab: String # JSON-LD @type of the value, which cannot be specified by the value itself due to lexical restrictions of GraphQL type: String # JSON-LD @id of the value,, which cannot be specified by the value itself due to lexical restrictions of GraphQL id: String value: JSON } # transformation relative to origin type Transform { # x coordinate x: Float # y coordinate y: Float # x-coordinate scaling factor scaleX: Float # y-coordinate scaling factor scaleY: Float } input TransformInput { # x coordinate x: Float = 0 # y coordinate y: Float = 0 # x-coordinate scaling factor scaleX: Float = 1 # y-coordinate scaling factor scaleY: Float = 1 } type Upload { # upload ID uploadId: String! # URL for uploading asset data, valid for a limited time url: String! # POST form data to supply on upload fields: UploadFormData! } enum UploadContentType { jpeg gif png tiff doc docx ppt pptx xls xlsx pdf mp4 unknown } type UploadFormData { Policy: String! } input UploadInput { contentType: UploadContentType! } # Video file asset asset type Video implements Surface, Element, Attachable { # Intrinsic asset width width: Float # Intrinsic asset height height: Float # Asset title title: String # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: ElementStyle! # asset url, provided if asset download is allowed url: String surface: Surface attachments(type: [ElementType!]): [Attachable] } input Viewport { x: Float! y: Float! width: Float! height: Float! } # Generic rectangular element with possibly custom content type Window implements Element, Attachable, Surface { # Workspace-unique element id id: ID! # Stack order, an element with a higher stack order is in front of a lower stack order zIndex: Int transform: Transform traits( # If present, only output traits with the specified keys key: [String!] ): [Trait!] style: WindowStyle! surface: Surface attachments(type: [ElementType!]): [Attachable] } type WindowStyle implements Style { hidden: Boolean # Extrinsic window width width: Float # Extrinsic window height height: Float }