Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions app/src/sim/shape.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/// The shape of a compiled project as the simulator sees it — a 1:1 mirror of
/// the WASM `describe_project` output. Everything here is derived from the
/// frozen IR; nothing is re-implemented.

export interface ProjectShape {
schemas: SchemaShape[];
}

export interface SchemaShape {
/** `::`-joined, e.g. `chat` or `wire::frame`. */
namespace: string;
/** `0x`-prefixed 16 hex digits — the value the generators emit as `IR_HASH`. */
ir_hash: string;
protocols: ProtocolShape[];
errors: ErrorShape[];
/** Every struct / enum in the schema, for the call form's nested inputs. */
types: TypeDef[];
}

export interface ProtocolShape {
name: string;
framing: "datagram" | "jsonrpc";
functions: FnShape[];
}

export interface FnShape {
name: string;
/** 0-based position in the protocol — the `Call` id `resolveKind` matches. */
index: number;
/** No return at all — a fire-and-forget `notify`. */
oneway: boolean;
args: ArgShape[];
returns: TypeRef | null;
throws: ThrowShape[];
}

export interface ArgShape {
name: string;
ty: TypeRef;
}

export interface ThrowShape {
ordinal: number;
/** The error's name, or `"<unresolved>"` for a bare `throws` slot. */
name: string;
}

export interface ErrorShape {
ordinal: number;
name: string;
message: string;
fields: FieldShape[];
}

export interface FieldShape {
name: string;
ty: TypeRef;
optional: boolean;
}

export type TypeDef =
| { kind: "struct"; name: string; fields: FieldShape[] }
| { kind: "enum"; name: string; variants: string[] };

export type TypeRef =
| { kind: "prim"; name: string }
| { kind: "ref"; name: string }
| { kind: "array"; of: TypeRef }
| { kind: "unit" }
| { kind: "union"; of: TypeRef[] };
18 changes: 13 additions & 5 deletions app/src/worker.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
/// The compile worker: loads the Comline WASM module once, then answers
/// `compileProject` / `generateProject` / `semanticTokens` / `hover` /
/// `completions` requests off the main thread. The editor services call the
/// language server's handlers verbatim, so the editor matches `comline-lsp`;
/// `compileProject` / `generateProject` run the schema set as one package, so
/// cross-file `use` resolves the way `comline build` resolves it.
/// `compileProject` / `generateProject` / `describeProject` / `semanticTokens` /
/// `hover` / `completions` requests off the main thread. The editor services
/// call the language server's handlers verbatim, so the editor matches
/// `comline-lsp`; `compileProject` / `generateProject` / `describeProject` run
/// the schema set as one package, so cross-file `use` resolves the way
/// `comline build` resolves it.

import init, {
compile_project,
generate_project,
describe_project,
semantic_tokens,
hover,
completions,
} from "./wasm/comline_playground_wasm.js";

export type { ProjectShape } from "./sim/shape.ts";

// ── result shapes (a thin slice of lsp-types) ─────────────────────────────
export interface LspPosition {
line: number;
Expand Down Expand Up @@ -74,6 +78,7 @@ export interface Hover {
type Req =
| { id: number; cmd: "compileProject"; files: FileInput[] }
| { id: number; cmd: "generateProject"; files: FileInput[]; target: string; mode: string }
| { id: number; cmd: "describeProject"; files: FileInput[] }
| { id: number; cmd: "semanticTokens"; source: string }
| { id: number; cmd: "hover"; source: string; line: number; character: number }
| { id: number; cmd: "completions"; source: string; line: number; character: number };
Expand All @@ -92,6 +97,9 @@ self.onmessage = async (e: MessageEvent<Req>) => {
case "generateProject":
result = generate_project(req.files, req.target, req.mode);
break;
case "describeProject":
result = describe_project(req.files);
break;
case "semanticTokens":
result = semantic_tokens(req.source);
break;
Expand Down
Loading
Loading