Skip to content

Commit

Permalink
fix: add toolchain schema to docs (#1527)
Browse files Browse the repository at this point in the history
<!-- Please make sure there is an issue that this PR is correlated to. -->
Fixes RVT-4294
## Changes

<!-- If there are frontend changes, please include screenshots. -->
  • Loading branch information
MasterPtato committed Dec 5, 2024
1 parent a3d9ea0 commit ce7f63c
Show file tree
Hide file tree
Showing 11 changed files with 478 additions and 141 deletions.
193 changes: 104 additions & 89 deletions docs/src/components/JsonSchemaPreview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,27 +3,30 @@
import { Foldable } from '@/components/FoldableSchema';
import { Markdown } from '@/components/Markdown';
import { cn } from '@rivet-gg/components';
import { ReactNode } from 'react';
import { ReactNode, ReactElement } from 'react';
import type { JSONSchema7, JSONSchema7Definition, JSONSchema7Type } from 'json-schema';

interface JsonSchemaPreviewProps {
className?: string;
title?: string;
schema: JSONSchema7;
defs?: Record<string, JSONSchema7>;
parent?: string;
empty?: ReactNode;
}

export function JsonSchemaPreview({ className, schema, defs, parent, empty }: JsonSchemaPreviewProps) {
export function JsonSchemaPreview({ className, title, schema, defs, parent, empty }: JsonSchemaPreviewProps) {
if (schema.type === 'object') {
if (!schema.properties || Object.keys(schema.properties).length === 0) {
return empty;
}

if (schema.title) {
if (title ?? schema.title) {
return (
<div className='not-prose mb-6 rounded-md border px-4 pb-3'>
<h3 className='relative -top-4 mb-0 inline-block bg-card text-xl font-bold'>{schema.title}</h3>
<h3 className='relative -top-4 mb-0 inline-block bg-card text-xl font-bold'>
{title ?? schema.title}
</h3>
<ObjectSchema
className={className}
schema={schema}
Expand Down Expand Up @@ -65,8 +68,8 @@ function ObjectSchema({ schema: baseSchema, defs, parent, className }: ObjectSch
let newParent = parent ? `${parent}.${key}` : key;

return (
<ObjectSchemaItem key={key}>
<PropertyLabel parent={parent} name={key} schema={resolved} nullable={nullable} />
<ObjectSchemaItem className={'px-4'} key={key}>
<PropertyLabel parent={parent} name={key} schema={resolved} defs={defs} nullable={nullable} />
<Schema parent={newParent} schema={resolved} defs={defs} />
</ObjectSchemaItem>
);
Expand All @@ -79,42 +82,73 @@ interface SchemaProps {
schema: JSONSchema7;
defs: Record<string, JSONSchema7>;
parent?: string;
className?: string;
foldable?: boolean;
}

function Schema({ schema: baseSchema, defs, parent, className, foldable }: SchemaProps) {
function Schema({ schema: baseSchema, defs, parent, foldable }: SchemaProps) {
let isFoldable = foldable ?? true;
let schema = resolveSchema(baseSchema as JSONSchema7, defs);

// Enum
if (schema.oneOf) {
const common = {
type: 'object',
properties: schema.properties
} as JSONSchema7;

let inner = (
<ul className='space-y-4 rounded-md'>
<ul>
{schema.oneOf.map((item: JSONSchema7, index) => {
return (
<li key={index} className='my-4'>
<li key={index} className='mt-4 pl-4'>
{item.enum ? (
<TypeLabel type={item.enum[0]} description={item.description} />
) : (
<Schema parent={parent} schema={item} defs={defs} foldable={false} />
<>
<TypeLabel type={`Variant #${index + 1}`} />
<Schema parent={parent} schema={item} defs={defs} foldable={false} />
</>
)}
</li>
);
})}
{common.properties ? (
<li className='mt-4 pl-4'>
<TypeLabel type={'Common (on all variants)'} />
<Schema parent={parent} schema={common} defs={defs} foldable={false} />
</li>
) : null}
</ul>
);

return (
<div className='mt-1 px-4'>
{isFoldable ? (
<Foldable title='Show possible variants' closeTitle='Hide possible variants'>
{inner}
</Foldable>
) : (
inner
)}
</div>
return isFoldable ? (
<Foldable title='Show possible variants' closeTitle='Hide possible variants'>
{inner}
</Foldable>
) : (
inner
);
}

// String enum
if (schema.enum) {
let inner = (
<ul className='space-y-4 rounded-md'>
{schema.enum.map((item, index) => {
return (
<li key={index} className='mt-4 px-4'>
<TypeLabel type={item} />
</li>
);
})}
</ul>
);
return isFoldable ? (
<Foldable title='Show possible variants' closeTitle='Hide possible variants'>
{inner}
</Foldable>
) : (
inner
);
}

Expand All @@ -127,95 +161,72 @@ function Schema({ schema: baseSchema, defs, parent, className, foldable }: Schem
const isEmpty = item.type === 'object' && (!item.properties || Object.keys(item.properties).length === 0);

if (isObject && !isEmpty) {
return (
<div className='mt-1 px-4'>
{isFoldable ? (
<Foldable>
<JsonSchemaPreview schema={item} defs={defs} parent={newParent} />
</Foldable>
) : (
<JsonSchemaPreview schema={item} defs={defs} parent={newParent} />
)}
</div>
return isFoldable ? (
<Foldable>
<JsonSchemaPreview schema={item} defs={defs} parent={newParent} />
</Foldable>
) : (
<JsonSchemaPreview schema={item} defs={defs} parent={newParent} />
);
}
return null;
}

// Object
if (schema.type === 'object') {
const isEmpty = !schema.properties || Object.keys(schema.properties).length === 0;

if (!isEmpty) {
return (
<div className='mt-1 px-4'>
{isFoldable ? (
<Foldable>
<JsonSchemaPreview schema={schema} defs={defs} parent={parent} />
</Foldable>
) : (
<JsonSchemaPreview schema={schema} defs={defs} parent={parent} />
)}
</div>
return isFoldable ? (
<Foldable>
<ObjectSchema schema={schema} defs={defs} parent={parent} />
</Foldable>
) : (
<ObjectSchema schema={schema} defs={defs} parent={parent} />
);
}
return null;
}

// Array
if (schema.type === 'array' && schema.items) {
const newParent = `${parent}[]`;

const items = schema.items as JSONSchema7;
const items = resolveSchema(schema.items as JSONSchema7, defs);
const isObject = items.type === 'object';
const isEmpty =
items.type === 'object' && (!items.properties || Object.keys(items.properties).length === 0);
const isEnum = items.oneOf != undefined;

if (isObject && !isEmpty) {
return (
<div className='mt-1 px-4'>
{isFoldable ? (
<Foldable>
<JsonSchemaPreview schema={items} defs={defs} parent={newParent} />
</Foldable>
) : (
<JsonSchemaPreview schema={items} defs={defs} parent={newParent} />
)}
</div>
return isFoldable ? (
<Foldable
title={isEnum ? 'Show possible variants' : undefined}
closeTitle={isEnum ? 'Hide possible variants' : undefined}>
<Schema schema={items} defs={defs} parent={newParent} foldable={false} />
</Foldable>
) : (
<Schema schema={items} defs={defs} parent={newParent} />
);
}
return null;
}

if (schema.enum) {
let inner = (
<ul className='space-y-4 rounded-md'>
{schema.enum.map((item, index) => {
return (
<li key={index} className='my-4'>
<TypeLabel type={item} />
</li>
);
})}
</ul>
);
return (
<div className='mt-1 px-4'>
{isFoldable ? (
<Foldable title='Show possible variants' closeTitle='Hide possible variants'>
{inner}
</Foldable>
) : (
inner
)}
</div>
);
}
return null;
}

return <JsonSchemaPreview schema={schema} defs={defs} parent={parent} />;
interface ObjectSchemaItemProps {
className?: string;
children: ReactElement[];
}

function ObjectSchemaItem({ children }) {
function ObjectSchemaItem({ children, className }: ObjectSchemaItemProps) {
return (
<li className='min-w-0 overflow-auto whitespace-pre border-b pb-4 last:border-none last:pb-0'>
<li
className={cn(
'min-w-0 overflow-auto whitespace-pre border-b pb-4 last:border-none last:pb-0',
className
)}>
{children}
</li>
);
Expand All @@ -225,21 +236,21 @@ interface PropertyLabelProps {
parent?: string;
name: string;
schema: JSONSchema7;
defs: Record<string, JSONSchema7>;
nullable: boolean;
}

function PropertyLabel({ parent, name, schema, nullable }: PropertyLabelProps) {
function PropertyLabel({ parent, name, schema, defs, nullable }: PropertyLabelProps) {
return (
<>
<div className='scrollbar-hide flex items-center gap-1 overflow-auto px-4'>
<div className='scrollbar-hide flex items-center gap-1 overflow-auto'>
<code className='text-foreground/90'>
{parent ? <>{parent}.</> : null}
<span className='font-bold text-foreground'>{name}</span>
</code>
<div className='text-xs opacity-20'>{getPropertyTypeLabel(schema, nullable)}</div>
<div className='text-xs opacity-20'>{getPropertyTypeLabel(schema, defs, nullable)}</div>
</div>

<div className='text-wrap px-4 text-sm text-muted-foreground'>
<div className='prose text-wrap text-sm text-muted-foreground'>
<Markdown>{schema.description || ''}</Markdown>
</div>
</>
Expand All @@ -254,25 +265,29 @@ interface TypeLabelProps {
function TypeLabel({ type, description }: TypeLabelProps) {
return (
<>
<div className='scrollbar-hide flex items-center gap-1 overflow-auto px-4'>
<div className='scrollbar-hide flex items-center gap-1 overflow-auto'>
<code className='font-bold text-foreground'>{getTypeLabel(type)}</code>
</div>

<div className='prose text-wrap px-4 text-sm text-muted-foreground'>
<div className='prose text-wrap text-sm text-muted-foreground'>
<Markdown>{description || ''}</Markdown>
</div>
</>
);
}
function getPropertyTypeLabel(schema: JSONSchema7, nullable: boolean = false) {
function getPropertyTypeLabel(
schema: JSONSchema7,
defs: Record<string, JSONSchema7>,
nullable: boolean = false
) {
let s: string[] = [];

if (nullable) {
s.push('nullable');
}

if (schema.oneOf) {
let type = Array.from(new Set(schema.oneOf.map((s: JSONSchema7) => getPropertyTypeLabel(s))));
let type = Array.from(new Set(schema.oneOf.map((s: JSONSchema7) => getPropertyTypeLabel(s, defs))));
s.push(type.join(', '));
} else if (schema.type === 'string') {
s.push('string');
Expand All @@ -283,7 +298,7 @@ function getPropertyTypeLabel(schema: JSONSchema7, nullable: boolean = false) {
} else if (schema.type === 'boolean') {
s.push('boolean');
} else if (schema.type === 'array') {
s.push(`array of ${getPropertyTypeLabel(schema.items as JSONSchema7)}s`);
s.push(`array of ${getPropertyTypeLabel(resolveSchema(schema.items as JSONSchema7, defs), defs)}s`);
} else if (schema.type === 'object') {
if (schema.additionalProperties) {
s.push('map');
Expand Down
9 changes: 4 additions & 5 deletions docs/src/content/docs/actor-internals/networking.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,7 @@ actor servers to provide bridged port access to any ports chosen by the user. It
maps a randomly chosen port number on the host machine to the chosen port number
by you.


For isolates, Rivet restricts what ports an isolate can listen on.
Bridge networking is currently not implemented for isolates.

### Host

Expand All @@ -36,9 +35,11 @@ choose a specific port number. Port numbers will be randomly chosen for you for
port number in your application, there are environment variables provided with the port name and number
(ex. `PORT_MY_PORT=24020`).

Actors in host networking have no protection on what ports they can listen on
Containers with host networking have no restriction on what ports they can listen on
and connect to. This is less secure than using bridge networking.

For isolates, Rivet restricts what ports an isolate can listen on.

Host networking is sometimes required for edge cases where actors need an
unrestricted amount of ports. It's up to the developer to ensure that multiple
actors on the same machine do not interfere with each others' networking.
Expand Down Expand Up @@ -71,8 +72,6 @@ to better protect from DDoS attacks & improve monitoring of your application.

If using host ports, read about differences in behavior with [actor rescheduling](/docs/actor-internals/rescheduling).

Host routing must use the host network mode.

## Routing Diagram

This diagram shows how requests are routed from the end-user to the application running on Rivet based on the
Expand Down
8 changes: 7 additions & 1 deletion docs/src/content/docs/config.mdx
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
import { JsonSchemaPreview } from '@/components/JsonSchemaPreview';
import TOOLCHAIN_SPEC from './toolchain-spec.json';

# Config

TODO:

- Supported file names
- Spec

## Schema

<JsonSchemaPreview className='not-prose' title='Config' schema={TOOLCHAIN_SPEC} />
Loading

0 comments on commit ce7f63c

Please sign in to comment.