@fossil-lang/wasm 0.3.0-alpha.3 → 0.3.0-alpha.6

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/dist/index.js CHANGED
@@ -1,19 +1,23 @@
1
1
  /**
2
2
  * @fossil-lang/wasm — JS/TS wrapper around the fossil-wasm wasm-bindgen artifacts.
3
3
  *
4
- * Public API (one of the six @fossil-lang/* packages per ADR-0028):
4
+ * Public API (one of the @fossil-lang/* packages; `git ls-files packages` is
5
+ * the list):
5
6
  * - {@link initFossilWasm} — consumer-controlled .wasm URL loader (memoised).
6
- * - {@link tokenize} — calls the Rust lexer, returns TokenRow[] (ADR-0030).
7
- * - {@link semanticLegend} — returns the LSP SemanticTokensLegend (Phase-6 06-07).
8
- * - {@link FossilPlayground} — Workspace API class (ADR-0024) for the LSP.
7
+ * - {@link tokenize} — calls the Rust lexer, returns TokenRow[].
8
+ * - {@link tokenKinds} — the legend for TokenRow.kind: variant names by index.
9
+ * - {@link semanticLegend} — returns the LSP SemanticTokensLegend.
10
+ * - {@link FossilPlayground} — Workspace API class: open / update / close,
11
+ * `check`, and the three position queries (`hover`, `completions`,
12
+ * `gotoDefinition`) an editor draws its IDE surface from.
9
13
  *
10
- * Consumer pattern (wasm-bindgen --target web — RESEARCH.md Pattern 3):
14
+ * Consumer pattern (wasm-bindgen --target web):
11
15
  *
12
16
  * import { initFossilWasm, tokenize } from '@fossil-lang/wasm';
13
17
  * import wasmUrl from '@fossil-lang/wasm/pkg/fossil_wasm_bg.wasm?url'; // Vite
14
18
  *
15
19
  * await initFossilWasm({ wasmUrl });
16
- * const tokens = tokenize('prefix ex: <https://example.org/>');
20
+ * const tokens = tokenize('User := io.csv("data/people.csv")');
17
21
  */
18
22
  // The wasm-bindgen glue (`../pkg/fossil_wasm.js`) is imported ONLY from leaf
19
23
  // modules — `load.ts` (init) and `client.ts` (the lexer / LSP / Workspace API) —
@@ -22,5 +26,5 @@
22
26
  // `init()`'s wasm instance from the one the functions use (the crash the
23
27
  // codemirror tokenizer hit on the main thread). This entry only re-exports.
24
28
  export { initFossilWasm } from './load.js';
25
- export { start_lsp_worker, tokenize, semanticLegend, FossilPlayground, refs, providers, } from './client.js';
29
+ export { start_lsp_worker, tokenize, tokenKinds, semanticLegend, FossilPlayground, refs, providers, } from './client.js';
26
30
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,2EAA2E;AAC3E,yEAAyE;AACzE,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,IAAI,EACJ,SAAS,GACV,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,2EAA2E;AAC3E,yEAAyE;AACzE,4EAA4E;AAC5E,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EACL,gBAAgB,EAChB,QAAQ,EACR,UAAU,EACV,cAAc,EACd,gBAAgB,EAChB,IAAI,EACJ,SAAS,GACV,MAAM,aAAa,CAAC"}
package/dist/load.d.ts CHANGED
@@ -17,7 +17,7 @@ export interface InitFossilWasmOpts {
17
17
  * {@link tokenize}, {@link semanticLegend}, or instantiating
18
18
  * {@link FossilPlayground}. Memoised — subsequent calls return the same promise.
19
19
  *
20
- * Per 08-RESEARCH.md Pattern 3 (wasm-bindgen --target web), consumers control
20
+ * With `wasm-bindgen --target web`, consumers control
21
21
  * the `.wasm` URL — this avoids tying library users to a specific bundler's
22
22
  * `.wasm` import magic. See `packages/wasm/README.md` for consumer patterns.
23
23
  */
package/dist/load.js CHANGED
@@ -9,7 +9,7 @@ let _initPromise = null;
9
9
  * {@link tokenize}, {@link semanticLegend}, or instantiating
10
10
  * {@link FossilPlayground}. Memoised — subsequent calls return the same promise.
11
11
  *
12
- * Per 08-RESEARCH.md Pattern 3 (wasm-bindgen --target web), consumers control
12
+ * With `wasm-bindgen --target web`, consumers control
13
13
  * the `.wasm` URL — this avoids tying library users to a specific bundler's
14
14
  * `.wasm` import magic. See `packages/wasm/README.md` for consumer patterns.
15
15
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fossil-lang/wasm",
3
- "version": "0.3.0-alpha.3",
3
+ "version": "0.3.0-alpha.6",
4
4
  "description": "JS/TS wrapper around the fossil-wasm wasm-bindgen artifacts (--target web). Exposes initFossilWasm + tokenize + semanticLegend + FossilPlayground class for downstream @fossil-lang/* packages.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -33,7 +33,7 @@
33
33
  ],
34
34
  "sideEffects": false,
35
35
  "dependencies": {
36
- "@fossil-lang/types": "0.3.0-alpha.3"
36
+ "@fossil-lang/types": "0.3.0-alpha.6"
37
37
  },
38
38
  "devDependencies": {
39
39
  "typescript": "^5.6.0",
@@ -7,6 +7,24 @@
7
7
  *
8
8
  * `Copy + Clone + Eq + Hash` so it can be a `HashMap` key on the Rust
9
9
  * side; `#[wasm_bindgen]` so JS can pass it back across the boundary.
10
+ *
11
+ * # Every exported method takes `&FileHandle`, and it has to
12
+ *
13
+ * wasm-bindgen CONSUMES an exported struct passed by value: the generated glue
14
+ * calls `__destroy_into_raw()` on the JS wrapper, which nulls its pointer. A
15
+ * handle passed by value is therefore good for exactly one call, and the second
16
+ * throws *"null pointer passed to rust"* — from inside a method that has nothing
17
+ * wrong with it, naming no handle and no file.
18
+ *
19
+ * `Copy` does not save it. The derive is a Rust-side property; nothing about it
20
+ * reaches the JS boundary, where this is a class holding a pointer like any
21
+ * other. The three methods a host calls repeatedly with one handle
22
+ * (`update_file`, `close_file`, `diagnostics_for`) take `&FileHandle` so
23
+ * wasm-bindgen borrows instead, and the handle stays live across the whole
24
+ * lifetime `open_file`'s doc comment promises.
25
+ *
26
+ * This was reachable from the FIRST loop an editor runs: `updateFile(h, text)` on
27
+ * every check, with the handle `openFile` returned once.
10
28
  */
11
29
  export class FileHandle {
12
30
  private constructor();
@@ -15,163 +33,178 @@ export class FileHandle {
15
33
  }
16
34
 
17
35
  /**
18
- * JS-facing handle for the Fossil compiler running inside a WASM module.
36
+ * The JS-facing workspace — `FossilPlayground` on the JS side, and a
37
+ * `RefCell` around the Rust one.
38
+ *
39
+ * # Why the interior `RefCell`, and it is not a style choice
40
+ *
41
+ * `wasm-bindgen` wraps every exported struct in its own `WasmRefCell`. A
42
+ * method taking `&mut self` borrows that cell EXCLUSIVELY for the call, and a
43
+ * failed borrow does not return — it panics, with
44
+ * *"recursive use of an object detected which would lead to unsafe aliasing in
45
+ * rust"*. On `wasm32-unknown-unknown` a panic is an abort: the trap unwinds
46
+ * nothing, so the borrow flag it was holding is never cleared, and **every
47
+ * later call on that object fails the same way for the life of the module.**
48
+ * One bad call poisons the workspace permanently.
49
+ *
50
+ * That is a real defect and it was reachable from correct host code:
51
+ * `apps/playground` reproduced it by typing sixteen characters faster than its
52
+ * debounce, and the app carried a `busy` flag and a 120 ms coalesce to stay
53
+ * out of it. A mitigation a host has to remember is not a fix — and an editor
54
+ * is precisely the workload that forgets.
19
55
  *
20
- * One instance owns one [`WasmDb`] (Salsa store + injected [`WasmSystem`]
21
- * + `Arc<OutputDescriptorKind>`). Hosts construct a single playground per
22
- * browser tab / Node process and reuse it across all method calls to
23
- * amortise the Salsa interning + memoisation overhead.
56
+ * So no exported method takes `&mut self`. Every one takes `&self`, which
57
+ * wasm-bindgen borrows SHARED — shared borrows nest, so re-entry cannot fail
58
+ * there — and the mutation goes through this `RefCell` with
59
+ * `try_borrow_mut`. Genuine re-entry (a JS callback that calls back in while a
60
+ * call is live) now returns a catchable `Error` naming what happened, and
61
+ * **the workspace is still usable afterwards**, because a returned `Err` drops
62
+ * its guard where a panic did not.
63
+ *
64
+ * The Rust-side [`FossilPlayground`] keeps its `&mut self` signatures
65
+ * untouched: `lsp_worker` already owns it inside an `Rc<RefCell<…>>`, and the
66
+ * native tests drive it directly. Only the JS boundary changed.
24
67
  */
25
68
  export class FossilPlayground {
26
69
  free(): void;
27
70
  [Symbol.dispose](): void;
28
71
  /**
29
- * Run `parse → def_map → typecheck_mapping` across every open file and
30
- * return a flat JS array of `{ uri, range, severity, message }` rows
31
- * keyed by file URI. The LSP Worker (07-03) republishes these grouped
32
- * by URI as `textDocument/publishDiagnostics` notifications.
72
+ * Every open **program**'s diagnostics as a flat JS array of
73
+ * `{ uri, range, severity, message }` rows keyed by file URI — the
74
+ * playground's panel view. It is NOT what the LSP Worker publishes; see
75
+ * [`CheckRow`], and `lsp_worker::publish_diagnostics` for the wire.
76
+ *
77
+ * A buffer the installed provider catalogue claims — the `.shex` the
78
+ * playground had to open to give the compiler a document, a `.csv`, a
79
+ * `.parquet` — is an INPUT and is not parsed as fossil.
80
+ * [`fossil_ide::diagnostics()`] is where that is said and measured, for both
81
+ * hosts.
33
82
  *
34
83
  * `range` is the UTF-16 LSP range (via `fossil_ide::LineIndex` — the
35
- * rust-analyzer model from 06-05). `severity` is the LSP integer
36
- * constant (1 = error, 2 = warning, 3 = info). `message` carries any
37
- * `suggestion_source` as a `\nhelp: ...` suffix (mirroring `fossil-lsp`
38
- * `to_lsp_diagnostic` in 06-09).
84
+ * rust-analyzer model). `severity` is the LSP integer constant
85
+ * (1 = error, 2 = warning, 3 = info). `message` carries any
86
+ * `suggestion_source` as a `\nhelp: ...` suffix. All three come from
87
+ * [`fossil_ide::lsp_diagnostic`], the rendering an editor is shown.
39
88
  *
40
89
  * # Errors
41
90
  *
42
- * Returns a JS error only if the result fails to serialize to `JsValue`.
91
+ * Returns a JS error if the workspace is busy, or if the result fails to
92
+ * serialize to `JsValue`.
43
93
  */
44
94
  check(): any;
45
95
  /**
46
- * Return the stdlib classification manifest as a JS array of
47
- * `{ name, wasm_class }` objects (STDL-07).
96
+ * Close a file in the workspace. Idempotent in spirit but strict in
97
+ * signal: closing an unknown / already-closed handle is an error so
98
+ * JS-side bugs surface loudly (mirrors `ty_wasm`).
48
99
  *
49
- * `wasm_class` is the string `"pure_sql"` or `"native_udf_only"`. The
50
- * playground reads this once at startup to render `native_udf_only`
51
- * functions as disabled with a "native-only — unavailable in the browser"
52
- * tooltip (SC#1 playground half). `DuckDB`-WASM cannot register the Rust
53
- * UDFs those functions need (Pitfall 3), so the classification is the
54
- * authority on what is runnable in-browser.
100
+ * # Errors
55
101
  *
56
- * This is pure read-only data projected from the `&'static`-ready
57
- * `fossil_registry::FunctionRegistry` — no `DuckDB`, no native UDF code,
58
- * WASM-clean.
102
+ * Returns a JS error if `handle` was never opened or was already closed,
103
+ * or if the workspace is busy.
104
+ */
105
+ close_file(handle: FileHandle): void;
106
+ /**
107
+ * The completion candidates at a position: `{ label, kind, detail }` rows,
108
+ * already narrowed by the receiver — `str.` offers string members and no
109
+ * reader, a property key position offers the target shape's predicates and
110
+ * no catalogue row.
111
+ *
112
+ * `kind` is the LSP `CompletionItemKind` **by name** (`"function"`,
113
+ * `"field"`). See [`ide::CompletionRow`] for why a number does not cross
114
+ * this boundary.
59
115
  *
60
116
  * # Errors
61
117
  *
62
- * Returns a JS error only if the manifest fails to serialize to `JsValue`.
118
+ * Returns a JS error if the workspace is busy, or if the result fails to
119
+ * serialize to `JsValue`. An unknown handle is an empty array.
63
120
  */
64
- classification(): any;
121
+ completions(handle: FileHandle, line: number, character: number): any;
65
122
  /**
66
- * Close a file in the workspace. Idempotent in spirit but strict in
67
- * signal: closing an unknown / already-closed handle is an error so
68
- * JS-side bugs surface loudly (mirrors `ty_wasm`).
123
+ * Per-file diagnostic drain: `check()` returns the workspace-wide flat
124
+ * array, this returns one file's rows, so a host can refresh one buffer's
125
+ * panel without partitioning the workspace array on the JS side. It is NOT
126
+ * what the LSP Worker publishes — that is
127
+ * [`fossil_ide::lsp_diagnostics`], through `lsp_worker::publish_diagnostics`.
69
128
  *
70
129
  * # Errors
71
130
  *
72
- * Returns a JS error if `handle` was never opened or was already closed.
131
+ * Returns a JS error if `handle` is unknown, if the workspace is busy, or
132
+ * if serialization fails.
73
133
  */
74
- close_file(handle: FileHandle): void;
134
+ diagnostics_for(handle: FileHandle): any;
75
135
  /**
76
- * Per-file diagnostic drain — the B3 follow-up accessor the LSP Worker
77
- * (07-03) consumes for its per-file `publishDiagnostics` notifications.
78
- * `check()` returns the workspace-wide flat array; `diagnostics_for`
79
- * returns just one file's rows so 07-03 can dispatch one notification
80
- * per affected URI without partitioning the workspace array on the JS
81
- * side.
136
+ * Where the name under the cursor is defined: `{ uri, range }` rows, empty
137
+ * when nothing there has a definition.
138
+ *
139
+ * `uri` is the key the host opened the buffer under, verbatim — and two of
140
+ * the three positions goto-def recognises resolve into the shape document,
141
+ * so a host with one pane has to read it before moving a cursor.
82
142
  *
83
143
  * # Errors
84
144
  *
85
- * Returns a JS error if `handle` is unknown, or if serialization fails.
145
+ * Returns a JS error if the workspace is busy, or if the result fails to
146
+ * serialize to `JsValue`.
86
147
  */
87
- diagnostics_for(handle: FileHandle): any;
148
+ gotoDefinition(handle: FileHandle, line: number, character: number): any;
149
+ /**
150
+ * What is under the cursor: `{ markdown, range }`, or `null` when the
151
+ * cursor is on whitespace, on an expression the checker inferred no type
152
+ * for, or outside any mapping.
153
+ *
154
+ * `line` / `character` are LSP — zero-based, and `character` in UTF-16
155
+ * code units, which is what a JS host counts in anyway. The `range` comes
156
+ * back in the same units.
157
+ *
158
+ * # Errors
159
+ *
160
+ * Returns a JS error if the workspace is busy, or if the result fails to
161
+ * serialize to `JsValue`. An unknown handle is `null`, not an error —
162
+ * see [`FossilPlayground::hover_row`].
163
+ */
164
+ hover(handle: FileHandle, line: number, character: number): any;
88
165
  /**
89
166
  * Construct a new playground.
90
167
  *
91
- * Installs `console_error_panic_hook` (idempotent — RESEARCH.md
92
- * Don't-Hand-Roll #8) so any panic inside compiler-core surfaces as a
93
- * `console.error` stack trace in the host (browser `DevTools` or Node).
168
+ * Installs `console_error_panic_hook` (idempotent) so any panic inside
169
+ * compiler-core surfaces as a `console.error` stack trace in the host
170
+ * (browser `DevTools` or Node).
94
171
  */
95
172
  constructor();
96
173
  /**
97
174
  * Open a file in the workspace. Returns a [`FileHandle`] the JS side
98
- * keys subsequent `update_file` / `close_file` / `compile_file` calls
99
- * on. `path` is the URI / virtual path the diagnostics carry back to
100
- * the LSP client.
175
+ * keys subsequent `update_file` / `close_file` calls on. `path` is the
176
+ * URI / virtual path the diagnostics carry back to the LSP client.
101
177
  *
102
178
  * Mirrors `ty_wasm::Workspace::open_file` (Astral). Interns a fresh
103
179
  * [`fossil_base::SourceFile`] under the current Salsa revision.
104
180
  *
105
181
  * # Errors
106
182
  *
107
- * Returns a JS error only if the internal counter is exhausted
108
- * (`u32::MAX` files — would require a runaway loop in JS, not a normal
109
- * failure mode).
183
+ * Returns a JS error if the workspace is already inside another call —
184
+ * see the type-level note on [`WasmPlayground`].
110
185
  */
111
186
  open_file(path: string, contents: string): FileHandle;
112
187
  /**
113
188
  * Register an [`fossil_descriptors_input::InferredDescriptor`] for a
114
- * source binding name BEFORE invoking [`Self::compile`] /
115
- * [`Self::compile_file`]. The Rust compiler reads from this registration
116
- * during forward type propagation (Phase 3 CORE-05 rewired in plan
117
- * 13-02).
118
- *
119
- * `descriptor_json` is the JSON serialisation of `InferredDescriptor`;
120
- * the canonical shape is exposed in `packages/wasm/src/index.ts` as
121
- * `InferredDescriptorJson`:
189
+ * source binding name BEFORE invoking `check`. The Rust compiler reads
190
+ * from this registration during forward type propagation — the browser has
191
+ * no filesystem to introspect a CSV from, so the column types must arrive
192
+ * from the host.
122
193
  *
123
- * ```json
124
- * {
125
- * "source_name": "users",
126
- * "columns": [
127
- * { "name": "id", "primitive": "Integer" },
128
- * { "name": "name", "primitive": "String" }
129
- * ],
130
- * "content_hash": ""
131
- * }
132
- * ```
133
- *
134
- * Called by the browser-side playground orchestration AFTER running
135
- * DuckDB-WASM `DESCRIBE read_csv_auto('<resolved-url>')` and BEFORE
136
- * invoking `compile()` / `compile_file()`. Keyed by source-binding
137
- * name (`"users"` for `users := io.csv("...")`), NOT by URL.
138
- *
139
- * Idempotent: re-registering with the same `source_name` OVERWRITES the
140
- * previous entry — intentional, since the host may re-introspect when
141
- * file content changes.
194
+ * Registering the same URI twice REPLACES the previous descriptor
195
+ * — intentional, since the host re-introspects when the source changes.
142
196
  *
143
197
  * # Errors
144
198
  *
145
199
  * - Malformed JSON / missing required fields → JS `Error` with the
146
200
  * underlying `serde_json` message.
147
- *
148
- * Implementation: thin shim over the pure-Rust
149
- * [`Self::register_inferred_descriptor_native`] helper.
201
+ * - The workspace is busy.
150
202
  */
151
203
  registerInferredDescriptor(descriptor_json: string): void;
152
- /**
153
- * Install a user-supplied `ShEx` schema as the active output descriptor.
154
- * On parse failure the previously-installed descriptor is RETAINED (no
155
- * half-applied state — a broken schema must never wedge the editor;
156
- * same contract as `fossil-lsp`'s `load_sibling_shex` in 06-09).
157
- *
158
- * The schema is parsed via
159
- * [`fossil_descriptors_output::ShExDescriptor::from_reader`] (no
160
- * network access — Pitfall 1) and wrapped in
161
- * [`OutputDescriptorKind::ShEx`]. The resulting `Arc` is swapped into
162
- * the [`WasmDb`]'s descriptor slot atomically; future `fossil-ide`
163
- * feature calls (hover, completion) reading
164
- * [`HirDb::output_descriptor_kind`] see the new schema.
165
- *
166
- * # Errors
167
- *
168
- * Returns a JS error if the text is not a parseable `ShEx` schema.
169
- */
170
- set_target_shex(text: string): void;
171
204
  /**
172
205
  * Apply an edit to an open file. Mutates the SAME `SourceFile` via the
173
206
  * Salsa [`salsa::Setter`] (`set_text`) — this BUMPS THE REVISION, the
174
- * real cancellation trigger (ADR-0022): any in-flight analysis from the
207
+ * real cancellation trigger: any in-flight analysis from the
175
208
  * previous keystroke observes the new revision at its next cooperative
176
209
  * checkpoint. NO new `SourceFile` is interned — the Salsa input
177
210
  * identity stays stable across the file's lifetime, so memoised
@@ -180,15 +213,19 @@ export class FossilPlayground {
180
213
  *
181
214
  * # Errors
182
215
  *
183
- * Returns a JS error if `handle` was never opened or was already closed.
216
+ * Returns a JS error if `handle` was never opened or was already closed,
217
+ * or if the workspace is already inside another call — see the type-level
218
+ * note on [`WasmPlayground`]. **Neither leaves the workspace unusable**,
219
+ * which is the whole reason this method takes `&self`.
184
220
  */
185
221
  update_file(handle: FileHandle, contents: string): void;
186
222
  }
187
223
 
188
224
  /**
189
- * The data-source providers fossil supports (`io.csv`, `io.rdf`, …) as a JS
190
- * array of `{ name, extensions, kind }`. Pure projection of the stdlib source
191
- * registry — no parsing, no db.
225
+ * The providers this host installs (`io.csv`, `io.rdf`, `io.shex`, …) as a JS
226
+ * array of `{ name, extensions, kind }`. Pure projection of the provider
227
+ * registry — no parsing, no db. `kind` is read off each row's capabilities, so
228
+ * the two shape-document rows come back as `Schema`.
192
229
  *
193
230
  * # Errors
194
231
  * Returns a JS error only if the result fails to serialize to `JsValue`.
@@ -208,15 +245,14 @@ export function providers(): any;
208
245
  export function refs(program: string): any;
209
246
 
210
247
  /**
211
- * `JS`-facing re-export of the Phase-6 06-07 semantic-token legend.
248
+ * `JS`-facing re-export of the semantic-token legend.
212
249
  *
213
250
  * Returns `{ tokenTypes: string[], tokenModifiers: string[] }` — the exact
214
- * LSP `SemanticTokensLegend` shape. `CodeMirror` (plan 08-08 +
215
- * `packages/codemirror-fossil/src/tags.ts`) uses this to translate
216
- * LSP `semanticTokens/full` response indices into highlight tag names.
251
+ * LSP `SemanticTokensLegend` shape, which is what turns the indices in a
252
+ * `semanticTokens/full` response into names a host can style.
217
253
  *
218
- * Delegates to [`fossil_ide::semantic_legend`] (the 06-07 authoritative
219
- * definition) — NO duplicate legend definition lives here.
254
+ * Delegates to [`fossil_ide::semantic_legend`], the one definition — a second
255
+ * legend here would desynchronise the indices the native LSP already emits.
220
256
  *
221
257
  * # Errors
222
258
  *
@@ -239,10 +275,31 @@ export function semantic_legend(): any;
239
275
  */
240
276
  export function start_lsp_worker(): void;
241
277
 
278
+ /**
279
+ * The name of every [`TokenRow::kind`], indexed BY that kind.
280
+ *
281
+ * `token_kinds()[row.kind]` is the variant name — `"Comment"`, `"KwFrom"`,
282
+ * `"String"`. A host maps names to highlight categories and never writes a
283
+ * discriminant down, which is the only version of this contract that survives
284
+ * a reorder of the lexer.
285
+ *
286
+ * This is the same move [`semantic_legend`] makes for LSP semantic tokens: the
287
+ * indices are meaningless without the legend, so ship the legend.
288
+ *
289
+ * A kind past the end of the array is a variant appended by a newer compiler
290
+ * than the host was built against. That is BACKWARDS-COMPATIBLE by
291
+ * construction: the host sees `undefined` and styles the span as plain text.
292
+ *
293
+ * # Errors
294
+ *
295
+ * Returns a JS error only if `serde_wasm_bindgen` fails to serialise a
296
+ * `Vec<&str>` (impossible in practice).
297
+ */
298
+ export function tokenKinds(): any;
299
+
242
300
  /**
243
301
  * `JS`-facing tokenize. Returns the same row stream as [`tokenize_native`],
244
- * serialised via `serde_wasm_bindgen`. Consumed by
245
- * `@fossil-lang/codemirror-fossil`'s `StreamParser` (plan 08-08).
302
+ * serialised via `serde_wasm_bindgen`.
246
303
  *
247
304
  * # Errors
248
305
  *
@@ -260,20 +317,22 @@ export interface InitOutput {
260
317
  readonly start_lsp_worker: () => [number, number];
261
318
  readonly tokenize: (a: number, b: number) => [number, number, number];
262
319
  readonly semantic_legend: () => [number, number, number];
320
+ readonly tokenKinds: () => [number, number, number];
263
321
  readonly __wbg_filehandle_free: (a: number, b: number) => void;
264
322
  readonly __wbg_fossilplayground_free: (a: number, b: number) => void;
265
323
  readonly fossilplayground_new: () => number;
266
- readonly fossilplayground_classification: (a: number) => [number, number, number];
267
324
  readonly fossilplayground_open_file: (a: number, b: number, c: number, d: number, e: number) => [number, number, number];
268
325
  readonly fossilplayground_update_file: (a: number, b: number, c: number, d: number) => [number, number];
269
326
  readonly fossilplayground_close_file: (a: number, b: number) => [number, number];
270
327
  readonly fossilplayground_check: (a: number) => [number, number, number];
271
328
  readonly fossilplayground_diagnostics_for: (a: number, b: number) => [number, number, number];
272
- readonly fossilplayground_set_target_shex: (a: number, b: number, c: number) => [number, number];
329
+ readonly fossilplayground_hover: (a: number, b: number, c: number, d: number) => [number, number, number];
330
+ readonly fossilplayground_completions: (a: number, b: number, c: number, d: number) => [number, number, number];
331
+ readonly fossilplayground_gotoDefinition: (a: number, b: number, c: number, d: number) => [number, number, number];
273
332
  readonly fossilplayground_registerInferredDescriptor: (a: number, b: number, c: number) => [number, number];
274
333
  readonly providers: () => [number, number, number];
275
334
  readonly refs: (a: number, b: number) => [number, number, number];
276
- readonly wasm_bindgen__convert__closures_____invoke__h6bdcc41945596778: (a: number, b: number, c: any) => void;
335
+ readonly wasm_bindgen__convert__closures_____invoke__h900f85fb942a113b: (a: number, b: number, c: any) => void;
277
336
  readonly __wbindgen_malloc_command_export: (a: number, b: number) => number;
278
337
  readonly __wbindgen_realloc_command_export: (a: number, b: number, c: number, d: number) => number;
279
338
  readonly __wbindgen_exn_store_command_export: (a: number) => void;