@vedivad/typst-web-service 0.7.11 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +18 -11
- package/dist/analyzer-worker.js +102 -146
- package/dist/analyzer-worker.js.map +1 -1
- package/dist/index.d.ts +142 -107
- package/dist/index.js +274 -330
- package/dist/index.js.map +1 -1
- package/dist/worker.js +106 -145
- package/dist/worker.js.map +1 -1
- package/package.json +2 -1
package/README.md
CHANGED
|
@@ -27,6 +27,9 @@ if (result.vector) {
|
|
|
27
27
|
document.querySelector("#preview")!.innerHTML = svg;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// result.diagnostics are returned in deterministic order
|
|
31
|
+
// (path, start position, end position, message)
|
|
32
|
+
|
|
30
33
|
// Multi-file
|
|
31
34
|
const result = await compiler.compile({
|
|
32
35
|
"/main.typ": '#import "template.typ": greet\n#greet("World")',
|
|
@@ -63,7 +66,7 @@ Config options ([typstyle docs](https://github.com/typstyle-rs/typstyle)):
|
|
|
63
66
|
| `reorder_import_items` | `boolean` | -- | Sort import items alphabetically |
|
|
64
67
|
| `wrap_text` | `boolean` | -- | Wrap text to fit within `max_width` |
|
|
65
68
|
|
|
66
|
-
##
|
|
69
|
+
## Completion and hover with tinymist
|
|
67
70
|
|
|
68
71
|
`TypstAnalyzer` runs a [tinymist](https://github.com/Myriad-Dreamin/tinymist) language server in a Web Worker. The `wasmUrl` option must point to the `tinymist_bg.wasm` binary from the `tinymist-web` package.
|
|
69
72
|
|
|
@@ -73,25 +76,29 @@ import tinymistWasmUrl from "tinymist-web/pkg/tinymist_bg.wasm?url";
|
|
|
73
76
|
|
|
74
77
|
const analyzer = await TypstAnalyzer.create({ wasmUrl: tinymistWasmUrl });
|
|
75
78
|
|
|
76
|
-
analyzer.onDiagnostics((uri, diagnostics) => {
|
|
77
|
-
console.log(uri, diagnostics);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
79
|
await analyzer.didChange("untitled:project/main.typ", source);
|
|
81
|
-
const completions = await analyzer.completion(
|
|
82
|
-
|
|
80
|
+
const completions = await analyzer.completion(
|
|
81
|
+
"untitled:project/main.typ",
|
|
82
|
+
line,
|
|
83
|
+
character,
|
|
84
|
+
);
|
|
85
|
+
const hover = await analyzer.hover(
|
|
86
|
+
"untitled:project/main.typ",
|
|
87
|
+
line,
|
|
88
|
+
character,
|
|
89
|
+
);
|
|
83
90
|
|
|
84
91
|
analyzer.destroy();
|
|
85
92
|
```
|
|
86
93
|
|
|
87
94
|
## Service classes
|
|
88
95
|
|
|
89
|
-
| Class | Runs on | WASM loading | Purpose
|
|
90
|
-
| ---------------- | ----------- | ----------------------- |
|
|
96
|
+
| Class | Runs on | WASM loading | Purpose |
|
|
97
|
+
| ---------------- | ----------- | ----------------------- | ---------------------------------------------------------- |
|
|
91
98
|
| `TypstCompiler` | Web Worker | CDN (automatic) | `compile()` -> diagnostics + vector, `compilePdf()` -> PDF |
|
|
92
99
|
| `TypstRenderer` | Main thread | CDN (automatic) | `renderSvg(vector)` -> SVG string |
|
|
93
|
-
| `TypstFormatter` | Main thread | Bundler (static import) | `format(source)`, `formatRange(source, start, end)`
|
|
94
|
-
| `TypstAnalyzer` | Web Worker | User-provided `wasmUrl` |
|
|
100
|
+
| `TypstFormatter` | Main thread | Bundler (static import) | `format(source)`, `formatRange(source, start, end)` |
|
|
101
|
+
| `TypstAnalyzer` | Web Worker | User-provided `wasmUrl` | Completion + hover via tinymist |
|
|
95
102
|
|
|
96
103
|
## License
|
|
97
104
|
|
package/dist/analyzer-worker.js
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
// src/analyzer-worker.ts
|
|
2
|
+
import * as Comlink from "comlink";
|
|
3
|
+
|
|
1
4
|
// ../../node_modules/.bun/tinymist-web@https+++github.com+Myriad-Dreamin+tinymist+releases+download+v0.14.10+tinymist-web.tar.gz/node_modules/tinymist-web/pkg/tinymist.js
|
|
2
5
|
var wasm;
|
|
3
6
|
function addToExternrefTable0(obj) {
|
|
@@ -911,168 +914,121 @@ async function __wbg_init(module_or_path) {
|
|
|
911
914
|
}
|
|
912
915
|
var tinymist_default = __wbg_init;
|
|
913
916
|
|
|
914
|
-
// src/worker-utils.ts
|
|
915
|
-
function postError(id, err) {
|
|
916
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
917
|
-
self.postMessage({ type: "error", id, message });
|
|
918
|
-
}
|
|
919
|
-
|
|
920
917
|
// src/analyzer-worker.ts
|
|
921
|
-
var
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
while (events.length > 0) {
|
|
929
|
-
for (const event of events.splice(0)) {
|
|
930
|
-
server.on_event(event);
|
|
931
|
-
}
|
|
918
|
+
var AnalyzerWorker = class {
|
|
919
|
+
server = null;
|
|
920
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- events are opaque values from WASM
|
|
921
|
+
events = [];
|
|
922
|
+
ensureServer() {
|
|
923
|
+
if (!this.server) throw new Error("Analyzer not initialized");
|
|
924
|
+
return this.server;
|
|
932
925
|
}
|
|
933
|
-
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
sendEvent: (event) => void events.push(event),
|
|
938
|
-
sendRequest({ id }) {
|
|
939
|
-
server.on_response({ id, result: null });
|
|
940
|
-
},
|
|
941
|
-
sendNotification: ({
|
|
942
|
-
method,
|
|
943
|
-
params
|
|
944
|
-
}) => {
|
|
945
|
-
if (method === "textDocument/publishDiagnostics") {
|
|
946
|
-
const { uri, diagnostics } = params;
|
|
947
|
-
self.postMessage({
|
|
948
|
-
type: "diagnostics",
|
|
949
|
-
uri: normalizeUri(uri),
|
|
950
|
-
diagnostics
|
|
951
|
-
});
|
|
952
|
-
}
|
|
953
|
-
},
|
|
954
|
-
resolveFn: () => void 0
|
|
955
|
-
});
|
|
956
|
-
const initResult = server.on_request("initialize", {
|
|
957
|
-
capabilities: {
|
|
958
|
-
textDocument: {
|
|
959
|
-
publishDiagnostics: { relatedInformation: true },
|
|
960
|
-
completion: { completionItem: { snippetSupport: true } },
|
|
961
|
-
hover: { contentFormat: ["markdown", "plaintext"] }
|
|
962
|
-
}
|
|
963
|
-
},
|
|
964
|
-
rootUri: "file:///"
|
|
965
|
-
});
|
|
966
|
-
if (initResult && typeof initResult === "object" && "then" in initResult) {
|
|
967
|
-
await initResult;
|
|
926
|
+
notifyDidOpen(uri, content) {
|
|
927
|
+
this.ensureServer().on_notification("textDocument/didOpen", {
|
|
928
|
+
textDocument: { uri, languageId: "typst", version: 1, text: content }
|
|
929
|
+
});
|
|
968
930
|
}
|
|
969
|
-
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
}
|
|
973
|
-
self.onmessage = async (e) => {
|
|
974
|
-
const req = e.data;
|
|
975
|
-
if (req.type === "init") {
|
|
976
|
-
try {
|
|
977
|
-
await initServer(req.wasmUrl);
|
|
978
|
-
self.postMessage({
|
|
979
|
-
type: "ready",
|
|
980
|
-
id: req.id
|
|
981
|
-
});
|
|
982
|
-
} catch (err) {
|
|
983
|
-
postError(req.id, err);
|
|
984
|
-
}
|
|
985
|
-
return;
|
|
931
|
+
notifyDidClose(uri) {
|
|
932
|
+
this.ensureServer().on_notification("textDocument/didClose", {
|
|
933
|
+
textDocument: { uri }
|
|
934
|
+
});
|
|
986
935
|
}
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
936
|
+
notifyDidChange(uri, version, content) {
|
|
937
|
+
this.ensureServer().on_notification("textDocument/didChange", {
|
|
938
|
+
textDocument: { uri, version },
|
|
939
|
+
contentChanges: [{ text: content }]
|
|
940
|
+
});
|
|
990
941
|
}
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
942
|
+
flushEvents() {
|
|
943
|
+
if (!this.server) return;
|
|
944
|
+
while (this.events.length > 0) {
|
|
945
|
+
for (const event of this.events.splice(0)) {
|
|
946
|
+
this.server.on_event(event);
|
|
947
|
+
}
|
|
948
|
+
}
|
|
949
|
+
}
|
|
950
|
+
async init(wasmUrl) {
|
|
951
|
+
await tinymist_default({ module_or_path: wasmUrl });
|
|
952
|
+
this.server = new TinymistLanguageServer({
|
|
953
|
+
sendEvent: (event) => {
|
|
954
|
+
this.events.push(event);
|
|
955
|
+
},
|
|
956
|
+
sendRequest: ({
|
|
957
|
+
id
|
|
958
|
+
}) => {
|
|
959
|
+
this.server.on_response({ id, result: null });
|
|
960
|
+
},
|
|
961
|
+
sendNotification: () => {
|
|
962
|
+
},
|
|
963
|
+
resolveFn: () => void 0
|
|
964
|
+
});
|
|
965
|
+
const initResult = this.server.on_request("initialize", {
|
|
966
|
+
capabilities: {
|
|
994
967
|
textDocument: {
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
version: 1,
|
|
998
|
-
text: req.content
|
|
968
|
+
completion: { completionItem: { snippetSupport: true } },
|
|
969
|
+
hover: { contentFormat: ["markdown", "plaintext"] }
|
|
999
970
|
}
|
|
1000
|
-
}
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
971
|
+
},
|
|
972
|
+
rootUri: "file:///"
|
|
973
|
+
});
|
|
974
|
+
if (initResult && typeof initResult === "object" && "then" in initResult) {
|
|
975
|
+
await initResult;
|
|
1005
976
|
}
|
|
1006
|
-
|
|
977
|
+
this.flushEvents();
|
|
978
|
+
this.server.on_notification("initialized", {});
|
|
979
|
+
this.flushEvents();
|
|
1007
980
|
}
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
textDocument: { uri: req.uri }
|
|
1012
|
-
});
|
|
1013
|
-
flushEvents();
|
|
1014
|
-
self.postMessage({ type: "ack", id: req.id });
|
|
1015
|
-
} catch (err) {
|
|
1016
|
-
postError(req.id, err);
|
|
1017
|
-
}
|
|
1018
|
-
return;
|
|
981
|
+
async didOpen(uri, content) {
|
|
982
|
+
this.notifyDidOpen(uri, content);
|
|
983
|
+
this.flushEvents();
|
|
1019
984
|
}
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
textDocument: { uri: req.uri, version: req.version },
|
|
1024
|
-
contentChanges: [{ text: req.content }]
|
|
1025
|
-
});
|
|
1026
|
-
flushEvents();
|
|
1027
|
-
self.postMessage({ type: "ack", id: req.id });
|
|
1028
|
-
} catch (err) {
|
|
1029
|
-
postError(req.id, err);
|
|
1030
|
-
}
|
|
1031
|
-
return;
|
|
985
|
+
async didClose(uri) {
|
|
986
|
+
this.notifyDidClose(uri);
|
|
987
|
+
this.flushEvents();
|
|
1032
988
|
}
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
result: resolved ?? null
|
|
1045
|
-
});
|
|
1046
|
-
} catch (err) {
|
|
1047
|
-
postError(req.id, err);
|
|
989
|
+
async didChange(uri, version, content) {
|
|
990
|
+
this.notifyDidChange(uri, version, content);
|
|
991
|
+
this.flushEvents();
|
|
992
|
+
}
|
|
993
|
+
async didChangeMany(opens, changes) {
|
|
994
|
+
this.ensureServer();
|
|
995
|
+
for (const { uri, content } of opens) {
|
|
996
|
+
this.notifyDidOpen(uri, content);
|
|
997
|
+
}
|
|
998
|
+
for (const { uri, version, content } of changes) {
|
|
999
|
+
this.notifyDidChange(uri, version, content);
|
|
1048
1000
|
}
|
|
1049
|
-
|
|
1001
|
+
this.flushEvents();
|
|
1050
1002
|
}
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
position: { line: req.line, character: req.character }
|
|
1056
|
-
});
|
|
1057
|
-
const resolved = result && typeof result === "object" && "then" in result ? await result : result;
|
|
1058
|
-
flushEvents();
|
|
1059
|
-
self.postMessage({
|
|
1060
|
-
type: "hoverResult",
|
|
1061
|
-
id: req.id,
|
|
1062
|
-
result: resolved ?? null
|
|
1063
|
-
});
|
|
1064
|
-
} catch (err) {
|
|
1065
|
-
postError(req.id, err);
|
|
1003
|
+
async didCloseMany(uris) {
|
|
1004
|
+
this.ensureServer();
|
|
1005
|
+
for (const uri of uris) {
|
|
1006
|
+
this.notifyDidClose(uri);
|
|
1066
1007
|
}
|
|
1067
|
-
|
|
1008
|
+
this.flushEvents();
|
|
1009
|
+
}
|
|
1010
|
+
async completion(uri, line, character) {
|
|
1011
|
+
const result = this.ensureServer().on_request("textDocument/completion", {
|
|
1012
|
+
textDocument: { uri },
|
|
1013
|
+
position: { line, character }
|
|
1014
|
+
});
|
|
1015
|
+
const resolved = result && typeof result === "object" && "then" in result ? await result : result;
|
|
1016
|
+
this.flushEvents();
|
|
1017
|
+
return resolved ?? null;
|
|
1068
1018
|
}
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
type: "destroyed",
|
|
1074
|
-
id: req.id
|
|
1019
|
+
async hover(uri, line, character) {
|
|
1020
|
+
const result = this.ensureServer().on_request("textDocument/hover", {
|
|
1021
|
+
textDocument: { uri },
|
|
1022
|
+
position: { line, character }
|
|
1075
1023
|
});
|
|
1024
|
+
const resolved = result && typeof result === "object" && "then" in result ? await result : result;
|
|
1025
|
+
this.flushEvents();
|
|
1026
|
+
return resolved ?? null;
|
|
1027
|
+
}
|
|
1028
|
+
destroy() {
|
|
1029
|
+
this.server?.free();
|
|
1030
|
+
this.server = null;
|
|
1076
1031
|
}
|
|
1077
1032
|
};
|
|
1033
|
+
Comlink.expose(new AnalyzerWorker());
|
|
1078
1034
|
//# sourceMappingURL=analyzer-worker.js.map
|