forked from boos/BoosAPI
feat(desktop): embed BoosAPI Desktop client as a subproject
Vendor the rebranded BoosAPI Desktop client (Tauri + Vue) into metapi as a monorepo subdirectory under desktop/. Source only — node_modules, dist, Cargo target and the upstream .git history are excluded. desktop/ keeps its own independent Cargo workspace (desktop/src-tauri with crates/*); it is not part of the backend boosapi crate, so a `cargo check` at the metapi root still compiles only the backend. Build the desktop app from desktop/src-tauri per desktop/README.md. Note: app icons are still placeholder assets pending the final BoosAPI logo. The updater signing keys live outside the repo and are not included.
This commit is contained in:
@@ -0,0 +1,618 @@
|
||||
import React from 'react'
|
||||
|
||||
const DEMO_IMAGE_SRC = '/ssr-image.svg'
|
||||
|
||||
function textNode(content: string) {
|
||||
return {
|
||||
type: 'text',
|
||||
content,
|
||||
raw: content,
|
||||
}
|
||||
}
|
||||
|
||||
function paragraphNode(content: string) {
|
||||
return {
|
||||
type: 'paragraph',
|
||||
raw: content,
|
||||
children: [textNode(content)],
|
||||
}
|
||||
}
|
||||
|
||||
function headingNode(content: string, level = 2) {
|
||||
return {
|
||||
type: 'heading',
|
||||
level,
|
||||
raw: `${'#'.repeat(level)} ${content}`,
|
||||
children: [textNode(content)],
|
||||
}
|
||||
}
|
||||
|
||||
function listItemNode(content: string) {
|
||||
return {
|
||||
type: 'list_item',
|
||||
raw: content,
|
||||
children: [paragraphNode(content)],
|
||||
}
|
||||
}
|
||||
|
||||
function definitionListNode() {
|
||||
return {
|
||||
type: 'definition_list',
|
||||
items: [
|
||||
{
|
||||
type: 'definition_item',
|
||||
term: [textNode('Term')],
|
||||
definition: [paragraphNode('Definition')],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function tableNode() {
|
||||
return {
|
||||
type: 'table',
|
||||
header: {
|
||||
cells: [
|
||||
{ children: [textNode('Name')] },
|
||||
{ children: [textNode('Value')] },
|
||||
],
|
||||
},
|
||||
rows: [
|
||||
{
|
||||
cells: [
|
||||
{ children: [textNode('Alpha')] },
|
||||
{ children: [textNode('One')] },
|
||||
],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
function vmrContainerNode() {
|
||||
return {
|
||||
type: 'vmr_container',
|
||||
name: 'tip',
|
||||
attrs: [['data-kind', 'tip']],
|
||||
children: [paragraphNode('Container body')],
|
||||
}
|
||||
}
|
||||
|
||||
function createRenderCtx(serverEntry: any) {
|
||||
return {
|
||||
customComponents: {},
|
||||
events: {},
|
||||
typewriter: false,
|
||||
codeBlockStream: true,
|
||||
showTooltips: false,
|
||||
renderCodeBlocksAsPre: false,
|
||||
codeBlockThemes: {},
|
||||
customId: 'matrix',
|
||||
renderNode: serverEntry.renderNode,
|
||||
} as any
|
||||
}
|
||||
|
||||
function insightNode(label: string, body: string) {
|
||||
return {
|
||||
type: 'insight',
|
||||
raw: label,
|
||||
label,
|
||||
children: [paragraphNode(body)],
|
||||
}
|
||||
}
|
||||
|
||||
function customThinkingNode(scope: string, body: string) {
|
||||
return {
|
||||
type: 'html_block',
|
||||
tag: 'thinking',
|
||||
attrs: [
|
||||
['data-tone', 'calm'],
|
||||
['data-scope', scope],
|
||||
],
|
||||
content: `<thinking data-tone="calm" data-scope="${scope}">${body}</thinking>`,
|
||||
raw: `<thinking data-tone="calm" data-scope="${scope}">${body}</thinking>`,
|
||||
}
|
||||
}
|
||||
|
||||
export const BASIC_NEXT_MARKDOWN = `
|
||||
# Next Entry Basic
|
||||
|
||||
Server-first markdown content with <strong>inline HTML</strong>, a [stable link](https://example.com), and a footnote.[^1]
|
||||
|
||||
<div data-ssr-status="next-basic-html">Next HTML block</div>
|
||||
|
||||
| Name | Value |
|
||||
| --- | --- |
|
||||
| Next | SSR |
|
||||
|
||||

|
||||
|
||||
[^1]: Footnote text from the Next entry.
|
||||
`.trim()
|
||||
|
||||
export const NEXT_CUSTOM_ID = 'next-ssr-lab'
|
||||
export const NEXT_CUSTOM_ALT_ID = 'next-ssr-lab-alt'
|
||||
export const SERVER_CUSTOM_ID = 'server-ssr-lab'
|
||||
export const SERVER_CUSTOM_ALT_ID = 'server-ssr-lab-alt'
|
||||
|
||||
export const NEXT_CUSTOM_NODES = [
|
||||
paragraphNode('Next scoped paragraph'),
|
||||
insightNode('Next custom node', 'Next custom child body'),
|
||||
customThinkingNode('next-primary', 'Next scoped thinking body'),
|
||||
] as any[]
|
||||
|
||||
export const NEXT_CUSTOM_ALT_NODES = [
|
||||
paragraphNode('Next isolated paragraph'),
|
||||
insightNode('Next isolated custom node', 'Next isolated child body'),
|
||||
customThinkingNode('next-alt', 'Next isolated thinking body'),
|
||||
] as any[]
|
||||
|
||||
export const SERVER_BASIC_NODES = [
|
||||
headingNode('Server Entry Basic'),
|
||||
paragraphNode('Server scoped paragraph'),
|
||||
{
|
||||
type: 'link',
|
||||
href: 'https://example.com/server',
|
||||
title: 'Server link',
|
||||
text: 'Server link',
|
||||
raw: '[Server link](https://example.com/server)',
|
||||
children: [textNode('Server link')],
|
||||
},
|
||||
tableNode(),
|
||||
{
|
||||
type: 'html_block',
|
||||
content: '<div data-ssr-status="server-basic-html">Server HTML block</div>',
|
||||
raw: '<div data-ssr-status="server-basic-html">Server HTML block</div>',
|
||||
},
|
||||
] as any[]
|
||||
|
||||
export const SERVER_CUSTOM_NODES = [
|
||||
paragraphNode('Server scoped paragraph'),
|
||||
insightNode('Server custom node', 'Server custom child body'),
|
||||
customThinkingNode('server-primary', 'Server scoped thinking body'),
|
||||
] as any[]
|
||||
|
||||
export const SERVER_CUSTOM_ALT_NODES = [
|
||||
paragraphNode('Server isolated paragraph'),
|
||||
insightNode('Server isolated custom node', 'Server isolated child body'),
|
||||
customThinkingNode('server-alt', 'Server isolated thinking body'),
|
||||
] as any[]
|
||||
|
||||
export const ENHANCED_DEMOS = {
|
||||
code: {
|
||||
type: 'code_block',
|
||||
language: 'ts',
|
||||
code: 'export const answer = 42\nconsole.log(answer)',
|
||||
raw: 'export const answer = 42\nconsole.log(answer)',
|
||||
loading: false,
|
||||
},
|
||||
markdown: {
|
||||
type: 'code_block',
|
||||
language: 'md',
|
||||
code: '# Nested markdown\n\n- item one\n- item two',
|
||||
raw: '# Nested markdown\n\n- item one\n- item two',
|
||||
loading: false,
|
||||
},
|
||||
mathBlock: {
|
||||
type: 'math_block',
|
||||
content: 'x^2 + y^2 = z^2',
|
||||
raw: '$$x^2 + y^2 = z^2$$',
|
||||
loading: false,
|
||||
},
|
||||
mathInline: {
|
||||
type: 'math_inline',
|
||||
content: 'a+b',
|
||||
raw: '$a+b$',
|
||||
markup: '$',
|
||||
loading: false,
|
||||
},
|
||||
mermaid: {
|
||||
type: 'code_block',
|
||||
language: 'mermaid',
|
||||
code: 'graph TD;A[Start]-->B[Done];',
|
||||
raw: 'graph TD;A[Start]-->B[Done];',
|
||||
loading: false,
|
||||
},
|
||||
d2: {
|
||||
type: 'code_block',
|
||||
language: 'd2',
|
||||
code: 'api -> db',
|
||||
raw: 'api -> db',
|
||||
loading: false,
|
||||
},
|
||||
infographic: {
|
||||
type: 'code_block',
|
||||
language: 'infographic',
|
||||
code: '{"title":"SSR Lab","children":[{"title":"Node A"},{"title":"Node B"}]}',
|
||||
raw: '{"title":"SSR Lab","children":[{"title":"Node A"},{"title":"Node B"}]}',
|
||||
loading: false,
|
||||
},
|
||||
} as const
|
||||
|
||||
export const FALLBACK_DEMOS = {
|
||||
nextPre: {
|
||||
type: 'code_block',
|
||||
language: 'ts',
|
||||
code: 'const stableFallback = true',
|
||||
raw: 'const stableFallback = true',
|
||||
loading: false,
|
||||
},
|
||||
mermaid: {
|
||||
type: 'code_block',
|
||||
language: 'mermaid',
|
||||
code: 'graph TD;Fallback-->Stable;',
|
||||
raw: 'graph TD;Fallback-->Stable;',
|
||||
loading: false,
|
||||
},
|
||||
d2: {
|
||||
type: 'code_block',
|
||||
language: 'd2',
|
||||
code: 'fallback -> stable',
|
||||
raw: 'fallback -> stable',
|
||||
loading: false,
|
||||
},
|
||||
infographic: {
|
||||
type: 'code_block',
|
||||
language: 'infographic',
|
||||
code: '{"title":"Fallback"}',
|
||||
raw: '{"title":"Fallback"}',
|
||||
loading: false,
|
||||
},
|
||||
} as const
|
||||
|
||||
export function createMatrixCases(entry: any, serverEntry: any) {
|
||||
const ctx = createRenderCtx(serverEntry)
|
||||
const withCtx = (props: Record<string, any>) => ({
|
||||
...props,
|
||||
ctx,
|
||||
renderNode: serverEntry.renderNode,
|
||||
indexKey: 'matrix',
|
||||
customId: 'matrix',
|
||||
})
|
||||
|
||||
return [
|
||||
{
|
||||
name: 'NodeRenderer',
|
||||
element: React.createElement(entry.NodeRenderer, {
|
||||
content: '# Matrix Heading\n\nParagraph text',
|
||||
final: true,
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'AdmonitionNode',
|
||||
element: React.createElement(entry.AdmonitionNode, withCtx({
|
||||
node: {
|
||||
type: 'admonition',
|
||||
kind: 'note',
|
||||
children: [paragraphNode('Alert body')],
|
||||
},
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'BlockquoteNode',
|
||||
element: React.createElement(entry.BlockquoteNode, withCtx({
|
||||
node: {
|
||||
type: 'blockquote',
|
||||
children: [paragraphNode('Quoted body')],
|
||||
},
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'CheckboxNode',
|
||||
element: React.createElement(entry.CheckboxNode, {
|
||||
node: { type: 'checkbox', checked: true },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'CodeBlockNode',
|
||||
element: React.createElement(entry.CodeBlockNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'ts',
|
||||
code: 'const answer = 42',
|
||||
raw: 'const answer = 42',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ReactCodeBlockNode',
|
||||
element: React.createElement(entry.ReactCodeBlockNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'ts',
|
||||
code: 'const answer = 42',
|
||||
raw: 'const answer = 42',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'MarkdownCodeBlockNode',
|
||||
element: React.createElement(entry.MarkdownCodeBlockNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'md',
|
||||
code: '# nested markdown',
|
||||
raw: '# nested markdown',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'PreCodeNode',
|
||||
element: React.createElement(entry.PreCodeNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'js',
|
||||
code: 'const fallback = true',
|
||||
raw: 'const fallback = true',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'D2BlockNode',
|
||||
element: React.createElement(entry.D2BlockNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'd2',
|
||||
code: 'x -> y',
|
||||
raw: 'x -> y',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'MermaidBlockNode',
|
||||
element: React.createElement(entry.MermaidBlockNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'mermaid',
|
||||
code: 'graph TD;A-->B;',
|
||||
raw: 'graph TD;A-->B;',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'InfographicBlockNode',
|
||||
element: React.createElement(entry.InfographicBlockNode, {
|
||||
node: {
|
||||
type: 'code_block',
|
||||
language: 'infographic',
|
||||
code: '{"title":"Demo"}',
|
||||
raw: '{"title":"Demo"}',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'DefinitionListNode',
|
||||
element: React.createElement(entry.DefinitionListNode, withCtx({
|
||||
node: definitionListNode(),
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'EmojiNode',
|
||||
element: React.createElement(entry.EmojiNode, {
|
||||
node: { type: 'emoji', name: 'sparkles' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'EmphasisNode',
|
||||
element: React.createElement(entry.EmphasisNode, {
|
||||
node: { type: 'emphasis' },
|
||||
children: 'Emphasis',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'StrongNode',
|
||||
element: React.createElement(entry.StrongNode, {
|
||||
node: { type: 'strong' },
|
||||
children: 'Strong',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'StrikethroughNode',
|
||||
element: React.createElement(entry.StrikethroughNode, {
|
||||
node: { type: 'strikethrough' },
|
||||
children: 'Strike',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'HighlightNode',
|
||||
element: React.createElement(entry.HighlightNode, {
|
||||
node: { type: 'highlight' },
|
||||
children: 'Highlight',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'InsertNode',
|
||||
element: React.createElement(entry.InsertNode, {
|
||||
node: { type: 'insert' },
|
||||
children: 'Insert',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'SubscriptNode',
|
||||
element: React.createElement(entry.SubscriptNode, {
|
||||
node: { type: 'subscript' },
|
||||
children: 'Sub',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'SuperscriptNode',
|
||||
element: React.createElement(entry.SuperscriptNode, {
|
||||
node: { type: 'superscript' },
|
||||
children: 'Sup',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'FootnoteNode',
|
||||
element: React.createElement(entry.FootnoteNode, withCtx({
|
||||
node: {
|
||||
type: 'footnote',
|
||||
id: '1',
|
||||
children: [paragraphNode('Footnote body')],
|
||||
},
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'FootnoteReferenceNode',
|
||||
element: React.createElement(entry.FootnoteReferenceNode, {
|
||||
node: { type: 'footnote_reference', id: '1' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'FootnoteAnchorNode',
|
||||
element: React.createElement(entry.FootnoteAnchorNode, {
|
||||
node: { type: 'footnote_anchor', id: '1' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'HardBreakNode',
|
||||
element: React.createElement(entry.HardBreakNode, {
|
||||
node: { type: 'hardbreak' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'HeadingNode',
|
||||
element: React.createElement(entry.HeadingNode, {
|
||||
node: { type: 'heading', level: 2 },
|
||||
children: 'Heading',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ParagraphNode',
|
||||
element: React.createElement(entry.ParagraphNode, {
|
||||
node: { type: 'paragraph' },
|
||||
children: 'Paragraph',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'HtmlBlockNode',
|
||||
element: React.createElement(entry.HtmlBlockNode, {
|
||||
node: { type: 'html_block', content: '<div><strong>Block HTML</strong></div>' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'HtmlInlineNode',
|
||||
element: React.createElement(entry.HtmlInlineNode, {
|
||||
node: { type: 'html_inline', content: '<span>Inline HTML</span>' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ImageNode',
|
||||
element: React.createElement(entry.ImageNode, {
|
||||
node: {
|
||||
type: 'image',
|
||||
src: DEMO_IMAGE_SRC,
|
||||
alt: 'Demo image',
|
||||
title: 'Demo image',
|
||||
raw: '',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'InlineCodeNode',
|
||||
element: React.createElement(entry.InlineCodeNode, {
|
||||
node: { type: 'inline_code', code: 'inline-demo' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'LinkNode',
|
||||
element: React.createElement(entry.LinkNode, {
|
||||
node: {
|
||||
type: 'link',
|
||||
href: 'https://example.com',
|
||||
title: 'Example',
|
||||
text: 'Example',
|
||||
raw: '[Example](https://example.com)',
|
||||
children: [textNode('Example')],
|
||||
},
|
||||
children: 'Example',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ListItemNode',
|
||||
element: React.createElement(entry.ListItemNode, {
|
||||
node: { type: 'list_item' },
|
||||
children: 'List item',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ListNode',
|
||||
element: React.createElement(entry.ListNode, withCtx({
|
||||
node: {
|
||||
type: 'list',
|
||||
ordered: false,
|
||||
items: [listItemNode('List body')],
|
||||
},
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'MathBlockNode',
|
||||
element: React.createElement(entry.MathBlockNode, {
|
||||
node: {
|
||||
type: 'math_block',
|
||||
content: 'x^2',
|
||||
raw: '$$x^2$$',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'MathInlineNode',
|
||||
element: React.createElement(entry.MathInlineNode, {
|
||||
node: {
|
||||
type: 'math_inline',
|
||||
content: 'a+b',
|
||||
raw: '$a+b$',
|
||||
markup: '$',
|
||||
},
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ReferenceNode',
|
||||
element: React.createElement(entry.ReferenceNode, {
|
||||
node: { type: 'reference', id: 'ref-1' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'TableNode',
|
||||
element: React.createElement(entry.TableNode, withCtx({
|
||||
node: tableNode(),
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'TextNode',
|
||||
element: React.createElement(entry.TextNode, {
|
||||
node: { type: 'text', content: 'Text body' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'ThematicBreakNode',
|
||||
element: React.createElement(entry.ThematicBreakNode, {
|
||||
node: { type: 'thematic_break' },
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'Tooltip',
|
||||
element: React.createElement(entry.Tooltip, {
|
||||
visible: true,
|
||||
anchorEl: null,
|
||||
content: 'Tooltip body',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'HtmlPreviewFrame',
|
||||
element: React.createElement(entry.HtmlPreviewFrame, {
|
||||
code: '<p>Preview</p>',
|
||||
}),
|
||||
},
|
||||
{
|
||||
name: 'VmrContainerNode',
|
||||
element: React.createElement(entry.VmrContainerNode, withCtx({
|
||||
node: vmrContainerNode(),
|
||||
})),
|
||||
},
|
||||
{
|
||||
name: 'FallbackComponent',
|
||||
element: React.createElement(entry.FallbackComponent, {
|
||||
node: { type: 'mystery' },
|
||||
}),
|
||||
},
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user