Skip to content
Open
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
1 change: 1 addition & 0 deletions changes/unreleased/wasm-render-document.added.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- `sysml-wasm` and `sysml-engine` serve `RenderDocument`: a browser or stdio consumer runs the whole document pipeline — the definition's queries, its document plan and tree, and the Markdown, HTML or AsciiDoc backend — without a service, taking and answering the protojson of the service's `RenderDocumentRequest` and `RenderDocumentResponse` so a typed client's `renderDocument` works over either transport. The combined module advertises `render_document`, `render_document_html`, `render_document_asciidoc` and `render_document_file_name`; `pdf` is refused naming the three forms, and a diagram block whose view carries layout positions is written as Mermaid with the renderer's Graphviz notice, since no WebAssembly build runs Graphviz. The service's `RenderDocument` and the workspace's Markdown rendering now share one pipeline (`internal/doc/docset`).
8 changes: 7 additions & 1 deletion client/node/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ while another origin is not.
`connectWasm()` uses the same `Connection`, `Model`, values and errors over the
combined `sysml-wasm` module. It serves `ParseFile`, `ParseSources`,
`GetDiagnostics`, `GetSymbol`, `Evaluate`, `Instantiate`, `ExecuteAction`,
`ExecuteState`, `RenderView` and `GetServerInfo`. Those are the module's complete RPC surface;
`ExecuteState`, `RenderView`, `RenderDocument` and `GetServerInfo`. Those are the module's complete RPC surface;
other capability-gated operations fail with `MissingCapabilityError`, and a
direct unsupported RPC fails with `UNIMPLEMENTED`.
The adapter uses JSON encoding; requesting protobuf encoding is refused.
Expand All @@ -212,6 +212,12 @@ compartment rows, each a node whose `compartment` names the compartment of its `
page paints before its module has loaded). A traced `ExecuteState` answers the service's
`DocumentEvent` records and the module advertises `state_trace`, so
`connection.executeState(…, { trace: true })` returns the same typed trace over either.
`RenderDocument` answers the service's protojson `RenderDocumentResponse` in the forms
`markdown`, `html` and `asciidoc` and the module advertises `render_document`,
`render_document_html`, `render_document_asciidoc` and `render_document_file_name`, so
`model.renderDocument(name, { form })` returns the same text over either; `pdf` is refused
naming the three forms, and a diagram whose view carries layout positions is written as
Mermaid with the renderer's Graphviz notice, since no WebAssembly build runs Graphviz.

In Node, install the optional `@openmbee/opensysml-wasm` package at the same
version as this client. `connectWasm()` resolves its module and matching Go
Expand Down
4 changes: 4 additions & 0 deletions client/node/test/wasm.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,10 @@ for (const thread of ["worker", "inline"] as const) {
"state_trace",
"action_trace",
"symbol_members",
"render_document",
"render_document_html",
"render_document_asciidoc",
"render_document_file_name",
]);

const wasmModel = await wasm.loads(SAMPLE);
Expand Down
3 changes: 2 additions & 1 deletion docs/internals/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,8 @@ github.com/Open-MBEE/OpenSysML
│ │ ├── queryexec/ # Query plan execution → typed, ordered row sets
│ │ ├── querytranslate/ # OSLC Query text and the API Query → query plans (the shared translator core)
│ │ ├── docir/ # Document plan evaluation → backend-agnostic document tree
│ │ ├── docrender/ # Markdown and HTML document backends
│ │ ├── docrender/ # Markdown, HTML and AsciiDoc document backends
│ │ ├── docset/ # One document of a model's set, end to end: plan, siblings, files, a backend's text (service, engine and workspace share it)
│ │ └── docpdf/ # PDF document backend
│ ├── workspace/
│ │ ├── model/ # Workspace, document management
Expand Down
2 changes: 1 addition & 1 deletion docs/project/api-json-differential/index.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions docs/project/pilot-differential-baseline.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

41 changes: 37 additions & 4 deletions docs/reference/wasm.md
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,8 @@ interactive stream work as they do under Node.
## The execution engine

`sysml-engine` is the in-process half of [the service](service-transports.md): the execution
RPCs — `ParseSources`, `Evaluate`, `Instantiate`, `ExecuteAction`, `ExecuteState` — answered
RPCs — `ParseSources`, `Evaluate`, `Instantiate`, `ExecuteAction`, `ExecuteState`, `RenderView`,
`RenderDocument` — answered
with the same JSON `sysml-grpc` emits, but without the protobuf machinery, the analysis
framework or a held-object store, which is what keeps a WebAssembly build small enough to
embed in a page. A model parsed through it hashes to the same `modelHash` the service
Expand Down Expand Up @@ -171,6 +172,33 @@ The engine has no current-document context, so a pseudo-view must name an elemen
example `#tree:OpenSysMLStack::stack`. An untargeted `#tree`, `#interconnection` or `#matrix` is
refused with InvalidArgument and the supported pseudo-view spellings.

It also serves `RenderDocument`, running the document pipeline — the definition's queries,
its document plan and document tree, and a backend's text — as the protojson of the
`RenderDocumentResponse` [`sysml-grpc` answers the RPC with](wire-contract.md#queries):
`markdown`, `html` or `asciidoc` holds the text of the form asked for and `fileName` the
file a rendered set writes the document to. A request names the cached model, the document
definition's qualified name and, optionally, the form:

```json
{
"modelHash": "…",
"documentId": "Observatory::MassReport",
"form": "html"
}
```

`form` is `markdown` (the default when empty), `html` or `asciidoc`, exactly the forms the
service renders; `pdf` or any other spelling is refused with InvalidArgument naming those
three, since the PDF backend drives converters no WebAssembly build can run. The engine
holds no objects, so a document reads the model alone, as the service does before an
`Instantiate`; a query's `elementId` column is empty, since neither `sysml-engine` nor
`sysml-wasm` links the converter the service reads ids from; and no Graphviz draws for it, so a diagram block whose view carries layout
positions is written as Mermaid with the renderer's notice (`drawn as Mermaid, not at its
stated positions: Graphviz (dot) is not installed`) where the service writes DOT. A document
that is not one — a part def not specializing `DocumentQueries::Document` — is InvalidArgument,
an unknown name NotFound, and a fault in the model's own queries FailedPrecondition, with the
source declaration named, as the service reports them.

The `js` build installs a host surface instead of reading a pipe: load it through
`wasm_exec.js` with no arguments and `globalThis.sysmlEngine` appears with

Expand Down Expand Up @@ -272,14 +300,18 @@ system and stdin, as the site's REPL page does.
`sysml-wasm` combines the parsing, validation and execution methods of `sysml-core` and
`sysml-engine` in one WebAssembly module. It serves `ParseSources`, `ParseFile`,
`GetDiagnostics`, `GetSymbol`, `Evaluate`, `Instantiate`, `ExecuteAction`, `ExecuteState`,
`RenderView` and `GetServerInfo`. Parsing and symbol facts route through the core;
evaluation, execution and view rendering route through the engine. `ParseSources` and
`RenderView`, `RenderDocument` and `GetServerInfo`. Parsing and symbol facts route through the core;
evaluation, execution, view rendering and document rendering route through the engine. `ParseSources` and
`ParseFile` check that both frontends produce the same model hash and return the core
response, including roots and diagnostics. `RenderView` answers with the protojson
`RenderViewResponse` the service returns, so the module advertises the `render_view`
capability and a service client's typed `renderView` works over it unchanged. A traced
`ExecuteState` likewise answers its `trace` as the service's `DocumentEvent` records and
the module advertises `state_trace`, so a typed `executeState` with `trace` works over it.
`RenderDocument` answers the protojson `RenderDocumentResponse` in the forms `markdown`,
`html` and `asciidoc`, and the module advertises `render_document`, `render_document_html`,
`render_document_asciidoc` and `render_document_file_name`, so a typed `renderDocument`
works over it too; `pdf` is refused naming the three forms, as [the engine](#the-execution-engine) refuses it.

A hash from either parse method is shared by every method that takes a `modelHash`, including
`GetDiagnostics`, `GetSymbol`, `Evaluate`, `Instantiate`, `ExecuteAction` and `ExecuteState`.
Expand All @@ -290,7 +322,8 @@ The module retains the 16 most recently used models; an evicted hash is evicted
`structured_values`, `measurement_refs`, `function_values`, `set_values`, `tensor_values`,
`infinity_value`, `diagnostic_codes`, `schedule`, `final_time`, `metaobject_values`,
`undetermined_value`, `performer`, `big_int_values`, `render_view`, `state_trace`,
`action_trace`.
`action_trace`, `render_document`, `render_document_html`, `render_document_asciidoc`,
`render_document_file_name`.

The `js` build installs one synchronous host surface, `globalThis.sysmlWasm`, with
`version` and `call(method, paramsJSON)`. The call returns a JSON-RPC envelope string.
Expand Down
4 changes: 2 additions & 2 deletions examples/self-model/surfaces.sysml
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ package OpenSysMLSurfaces {
#Surface part def EngineCommand :> JsonCommand {
attribute :>> goPackage = "internal/frontend/engine";
attribute :>> entrypoint = "cmd/sysml-engine";
attribute :>> serves = "ParseSources, Evaluate, Instantiate, ExecuteAction, ExecuteState, RenderView";
attribute :>> serves = "ParseSources, Evaluate, Instantiate, ExecuteAction, ExecuteState, RenderView, RenderDocument";
}

#Surface part def CoreCommand :> JsonCommand {
Expand All @@ -208,7 +208,7 @@ package OpenSysMLSurfaces {
#Surface part def CombinedCommand :> JsonCommand {
attribute :>> goPackage = "internal/frontend/combined";
attribute :>> entrypoint = "cmd/sysml-wasm";
attribute :>> serves = "ParseSources, ParseFile, GetDiagnostics, GetSymbol, Evaluate, Instantiate, ExecuteAction, ExecuteState, RenderView, GetServerInfo";
attribute :>> serves = "ParseSources, ParseFile, GetDiagnostics, GetSymbol, Evaluate, Instantiate, ExecuteAction, ExecuteState, RenderView, RenderDocument, GetServerInfo";
attribute releaseAsset : String = "sysml-wasm.wasm";
}

Expand Down
Loading
Loading