@fossil-lang/wasm 0.3.0-alpha.2 → 0.3.0-alpha.5

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 CHANGED
@@ -3,16 +3,20 @@
3
3
  JS/TS wrapper around the `fossil-wasm` Rust crate's wasm-bindgen artefacts. Provides:
4
4
 
5
5
  - `initFossilWasm({ wasmUrl })` — consumer-controlled `.wasm` URL loader (memoised).
6
- - `tokenize(text)` — calls the Rust lexer, returns `TokenRow[]` (ADR-0030).
7
- - `semanticLegend()` — returns the LSP semantic-tokens legend (Phase 6 plan 06-07).
8
- - `FossilPlayground` — the Workspace API class (ADR-0024) for LSP + compile.
6
+ - `tokenize(text)` — calls the Rust lexer, returns `TokenRow[]`. The Rust lexer
7
+ is the only lexer: no host reimplements one and drifts from the grammar.
8
+ - `semanticLegend()` — returns the LSP semantic-tokens legend.
9
+ - `FossilPlayground` — the Workspace API class for LSP + compile. `fossil-lsp`
10
+ itself is native-only (stdio over crossbeam), so the browser gets this
11
+ equivalent dispatch surface over the same `fossil-ide` functions.
9
12
 
10
13
  ## Why explicit `init({ wasmUrl })` and not auto-load?
11
14
 
12
15
  We use `wasm-bindgen --target web` (NOT `--target bundler`). This means consumers
13
16
  control the `.wasm` URL resolution — works in Vite, Next.js, Webpack, Rspack, or
14
- plain `new URL(...)` in a Web Worker context. See `08-RESEARCH.md` Pitfall 1
15
- (this monorepo's phase-8 research) for why `--target bundler` was rejected.
17
+ plain `new URL(...)` in a Web Worker context. `--target bundler` was rejected
18
+ because its output assumes the consumer's bundler resolves `.wasm` ESM imports,
19
+ which a republished library cannot assume of a host's Vite/Next/Webpack config.
16
20
 
17
21
  ## Consumer patterns
18
22
 
@@ -23,7 +27,7 @@ import { initFossilWasm, tokenize } from '@fossil-lang/wasm';
23
27
  import wasmUrl from '@fossil-lang/wasm/pkg/fossil_wasm_bg.wasm?url';
24
28
 
25
29
  await initFossilWasm({ wasmUrl });
26
- const tokens = tokenize('prefix ex: <https://example.org/>');
30
+ const tokens = tokenize('User := io.csv("data/people.csv")');
27
31
  ```
28
32
 
29
33
  ### Next.js host (in a Client Component)
@@ -63,8 +67,6 @@ Optionally `wasm-opt` (binaryen) for size reduction.
63
67
 
64
68
  ## Source of truth
65
69
 
66
- - Rust crate: `crates/fossil-wasm/`
67
- - tokenize ADR: `decisions/0030-wasm-exported-tokenizer.md`
68
- - Workspace API ADR: `decisions/0024-fossil-wasm-workspace-api.md`
69
- - Distribution pattern: `decisions/0028-playground-as-react-library.md`
70
- (this package is one of the six in the `@fossil-lang/*` family)
70
+ - Rust crate: `crates/fossil-wasm/` — everything here is a wrapper over its
71
+ wasm-bindgen exports, and nothing in this package reimplements it.
72
+ - The grammar the tokenizer follows: `grammar.bnf` at the repo root.
@@ -0,0 +1,199 @@
1
+ /**
2
+ * The wasm-bindgen-backed runtime surface (lexer, LSP worker, Workspace API) of
3
+ * @fossil-lang/wasm.
4
+ *
5
+ * Kept in its OWN module (NOT the package entry) so the wasm-bindgen glue
6
+ * (`../pkg/fossil_wasm.js`) is imported only from leaf modules — `load.ts` (for
7
+ * `init`) and here. Under a bundler with `"sideEffects": false`, importing the
8
+ * stateful glue from the entry chunk can duplicate it: `init()` then populates
9
+ * the `wasm` binding in one instance while these functions read `undefined` from
10
+ * another (→ `Cannot read properties of undefined (reading '__wbindgen_malloc…')`,
11
+ * seen when the codemirror tokenizer calls `tokenize` on the main thread).
12
+ * Mirrors `@fossil-lang/corpus`'s `client.ts` split, the known-good shape.
13
+ */
14
+ import { FileHandle as RawFileHandle } from '../pkg/fossil_wasm.js';
15
+ import type { TokenRow, TokenKindLegend, SemanticTokensLegend } from '@fossil-lang/types';
16
+ import type { CheckRow, CompletionRow, DefinitionRow, HoverRow, InferredDescriptorJson, SourceRefInfo, ProviderInfo } from './index.js';
17
+ /**
18
+ * Install the LSP-over-postMessage dispatcher on the current Worker scope.
19
+ *
20
+ * `fossil-wasm` IS the LSP server-side in the browser: `fossil-lsp` is
21
+ * native-only (it speaks stdio over crossbeam and does not compile to
22
+ * `wasm32`), so the Worker gets an equivalent 16-route dispatch loop over the
23
+ * same `fossil-ide` free functions. The Rust function (re-exported from
24
+ * `crates/fossil-wasm/src/lsp_worker.rs`) installs `self.onmessage` on the
25
+ * Worker scope and owns LSP JSON-RPC dispatch from that point forward.
26
+ *
27
+ * MUST be called inside a Web Worker scope, AFTER {@link initFossilWasm} has
28
+ * resolved. Calling it on the main thread is a no-op (the dispatcher needs
29
+ * `DedicatedWorkerGlobalScope.onmessage`).
30
+ */
31
+ export declare function start_lsp_worker(): void;
32
+ /**
33
+ * Opaque file-handle returned by {@link FossilPlayground.openFile}. Pass it
34
+ * back into the matching `updateFile` / `closeFile` / `diagnosticsFor`
35
+ * calls. JS code cannot construct one directly (the wasm-bindgen class has a
36
+ * private constructor) — handles are minted only by `openFile` on the Rust
37
+ * side, where they index a `HashMap<FileHandle, SourceFile>` keyed by a `u32`.
38
+ */
39
+ export type FileHandle = RawFileHandle;
40
+ /**
41
+ * Tokenize a Fossil source string. Returns the byte-range tokens from the
42
+ * canonical Rust lexer (`fossil_syntax::lexer::raw_lex`) — the single grammar
43
+ * source of truth, so no editor ever reimplements the lexer in TS and drifts.
44
+ *
45
+ * MUST be called after {@link initFossilWasm} has resolved; otherwise the
46
+ * underlying wasm-bindgen function throws (the wasm module is not yet
47
+ * instantiated).
48
+ */
49
+ export declare function tokenize(text: string): TokenRow[];
50
+ /**
51
+ * The legend for {@link TokenRow.kind}: every lexer variant NAME, indexed by the
52
+ * discriminant a row carries. `tokenKinds()[row.kind]` is `"Comment"`,
53
+ * `"KwFrom"`, `"String"`, …
54
+ *
55
+ * **This is the contract, and the numbers are not.** `kind` is a variant
56
+ * discriminant of `fossil_syntax::lexer::Token`, so any reorder of that enum
57
+ * remaps every value with nothing going red. The predecessor of this package
58
+ * hard-coded the table (`enum FossilKind { Whitespace = 0, … }`) under a comment
59
+ * saying it had to be updated in lockstep; it was wrong in nine places by the
60
+ * time it was deleted. Keying on the name is what makes a reorder a non-event.
61
+ *
62
+ * An index past the end of the legend is a variant appended by a compiler newer
63
+ * than this host: `undefined`, and a host styles it as plain text.
64
+ *
65
+ * MUST be called after {@link initFossilWasm} has resolved.
66
+ */
67
+ export declare function tokenKinds(): TokenKindLegend;
68
+ /**
69
+ * Returns the LSP `SemanticTokensLegend` (token types + modifiers list) the
70
+ * editor uses to map LSP `semanticTokens/full` response indices to highlight
71
+ * categories. Re-export of `fossil_ide::semantic_legend` over the wasm-bindgen
72
+ * boundary — NO duplicate legend definition lives here.
73
+ *
74
+ * MUST be called after {@link initFossilWasm} has resolved.
75
+ */
76
+ export declare function semanticLegend(): SemanticTokensLegend;
77
+ /**
78
+ * Parse a Fossil program and return its external references — the typed lineage
79
+ * (every data URI + `schema =` argument, each tagged with its `@conn` alias and
80
+ * role). keasy's client-compute job runner reads this to derive a job's
81
+ * connections WITHOUT subprocessing `fossil` / a server round-trip. Identical
82
+ * shape to the native `fossil refs` (the SAME `fossil_lineage::SourceRefInfo`
83
+ * struct), so the browser and the CLI never diverge.
84
+ *
85
+ * MUST be called after {@link initFossilWasm} has resolved.
86
+ */
87
+ export declare function refs(program: string): SourceRefInfo[];
88
+ /**
89
+ * List the data-source providers fossil supports (`io.csv`, `io.rdf`, …) — the
90
+ * provider name, the extensions it reads, and how it can be used. Identical
91
+ * shape to the native `fossil providers`.
92
+ *
93
+ * MUST be called after {@link initFossilWasm} has resolved.
94
+ */
95
+ export declare function providers(): ProviderInfo[];
96
+ /**
97
+ * Workspace API class. Thin TS wrapper around the wasm-bindgen
98
+ * `FossilPlayground` that exposes camelCase method names for JS idiom + better
99
+ * TS inference (the raw bindings use snake_case from the Rust impl block).
100
+ *
101
+ * One instance per browser tab / Node process — the instance owns the Salsa
102
+ * store + `Arc<OutputDescriptorKind>` for the schema slot.
103
+ *
104
+ * NOTE: {@link FileHandle} is opaque — JS cannot construct one. Callers receive
105
+ * a handle from `openFile` and pass it back to subsequent operations.
106
+ */
107
+ export declare class FossilPlayground {
108
+ private _inner;
109
+ constructor();
110
+ /**
111
+ * Free the underlying WASM-side Salsa store. Call when the playground is no
112
+ * longer needed (e.g. component unmount).
113
+ */
114
+ free(): void;
115
+ /**
116
+ * Open a file in the workspace. Returns the {@link FileHandle} subsequent
117
+ * `updateFile` / `closeFile` / `diagnosticsFor` calls key on.
118
+ */
119
+ openFile(path: string, contents: string): FileHandle;
120
+ /**
121
+ * Apply an edit to an open file. Mutates the SAME `SourceFile` via the Salsa
122
+ * `Setter` (`set_text`) — bumps the revision for incremental
123
+ * invalidation rather than a full recompute, and that revision bump is also
124
+ * what cancels any analysis still running on an older snapshot.
125
+ */
126
+ updateFile(handle: FileHandle, contents: string): void;
127
+ /**
128
+ * Close a file in the workspace. Strict: closing an unknown / already-closed
129
+ * handle throws so JS-side bugs surface loudly.
130
+ */
131
+ closeFile(handle: FileHandle): void;
132
+ /**
133
+ * Workspace-wide diagnostic drain. Runs `parse → def_map → typecheck_mapping`
134
+ * across every open file and returns a flat array of {@link CheckRow}.
135
+ */
136
+ check(): CheckRow[];
137
+ /**
138
+ * Per-file diagnostic drain — the accessor the LSP Worker uses for its
139
+ * per-file `publishDiagnostics` notifications.
140
+ */
141
+ diagnosticsFor(handle: FileHandle): CheckRow[];
142
+ /**
143
+ * What is under the cursor — `{ markdown, range }`, or `null` when nothing
144
+ * there has a type.
145
+ *
146
+ * `line` / `character` are LSP: zero-based, `character` in UTF-16 code units.
147
+ * A CodeMirror or Monaco host already counts in those units, so a document
148
+ * offset converts with `doc.lineAt(pos)` and no byte arithmetic — unlike
149
+ * {@link tokenize}, whose offsets ARE bytes.
150
+ *
151
+ * ## Push the buffer before you ask
152
+ *
153
+ * This reads the text of the last {@link updateFile}. Hover fires on
154
+ * mouse-move and the checker is debounced, so a hover mid-debounce answers
155
+ * about text one keystroke old and its range lands one keystroke wrong. The
156
+ * three read-only methods take a SHARED borrow on the Rust side and cannot
157
+ * poison the workspace the way a re-entered `updateFile` once could — see the
158
+ * `ide` module in `crates/fossil-wasm` — but staleness is not a borrow
159
+ * problem and nothing here can fix it for you.
160
+ */
161
+ hover(handle: FileHandle, line: number, character: number): HoverRow | null;
162
+ /**
163
+ * The completion candidates at a position, already narrowed by the receiver:
164
+ * `str.` offers string members and no reader, a property-key position offers
165
+ * the target shape's predicates and no catalogue row at all.
166
+ *
167
+ * `kind` is the LSP `CompletionItemKind` **by name** (`"function"`,
168
+ * `"field"`) rather than by number. The numbers never cross this boundary —
169
+ * `packages/codemirror-fossil`'s deleted predecessor is what happens when
170
+ * they do.
171
+ *
172
+ * The same staleness note as {@link hover} applies, and harder: completion
173
+ * fires on nearly every keystroke.
174
+ */
175
+ completions(handle: FileHandle, line: number, character: number): CompletionRow[];
176
+ /**
177
+ * Where the name under the cursor is defined. Empty when nothing there has a
178
+ * definition.
179
+ *
180
+ * `uri` is the key the buffer was opened under, verbatim — and two of the
181
+ * four positions this recognises resolve into the **shape document**, so a
182
+ * host with a single editor pane has to read `uri` before it moves a cursor.
183
+ */
184
+ gotoDefinition(handle: FileHandle, line: number, character: number): DefinitionRow[];
185
+ /**
186
+ * Register an {@link InferredDescriptorJson} under the source URI the program
187
+ * wrote, BEFORE invoking {@link check}. The Rust compiler reads from this
188
+ * during forward type propagation.
189
+ *
190
+ * The compiler never introspects a source itself: it performs no network or
191
+ * file IO — that would break the WASM gate and Salsa's determinism alike —
192
+ * so a host that wants column types must run the `DESCRIBE` and push the
193
+ * result in here.
194
+ *
195
+ * @throws Error if the descriptor JSON fails to deserialise on the Rust side.
196
+ */
197
+ registerInferredDescriptor(descriptor: InferredDescriptorJson): void;
198
+ }
199
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAEL,UAAU,IAAI,aAAa,EAO5B,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAC1F,OAAO,KAAK,EACV,QAAQ,EACR,aAAa,EACb,aAAa,EACb,QAAQ,EACR,sBAAsB,EACtB,aAAa,EACb,YAAY,EACb,MAAM,YAAY,CAAC;AAEpB;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,IAAI,IAAI,CAEvC;AAED;;;;;;GAMG;AACH,MAAM,MAAM,UAAU,GAAG,aAAa,CAAC;AAEvC;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,EAAE,CAMjD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,IAAI,eAAe,CAE5C;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,IAAI,oBAAoB,CAErD;AAED;;;;;;;;;GASG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,aAAa,EAAE,CAErD;AAED;;;;;;GAMG;AACH,wBAAgB,SAAS,IAAI,YAAY,EAAE,CAE1C;AAED;;;;;;;;;;GAUG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAsB;;IAMpC;;;OAGG;IACH,IAAI,IAAI,IAAI;IAIZ;;;OAGG;IACH,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,UAAU;IAIpD;;;;;OAKG;IACH,UAAU,CAAC,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI;IAItD;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI;IAInC;;;OAGG;IACH,KAAK,IAAI,QAAQ,EAAE;IAInB;;;OAGG;IACH,cAAc,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,EAAE;IAI9C;;;;;;;;;;;;;;;;;;OAkBG;IACH,KAAK,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,IAAI;IAM3E;;;;;;;;;;;;OAYG;IACH,WAAW,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE;IAIjF;;;;;;;OAOG;IACH,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE;IAIpF;;;;;;;;;;;OAWG;IACH,0BAA0B,CAAC,UAAU,EAAE,sBAAsB,GAAG,IAAI;CAKrE"}
package/dist/client.js ADDED
@@ -0,0 +1,231 @@
1
+ /**
2
+ * The wasm-bindgen-backed runtime surface (lexer, LSP worker, Workspace API) of
3
+ * @fossil-lang/wasm.
4
+ *
5
+ * Kept in its OWN module (NOT the package entry) so the wasm-bindgen glue
6
+ * (`../pkg/fossil_wasm.js`) is imported only from leaf modules — `load.ts` (for
7
+ * `init`) and here. Under a bundler with `"sideEffects": false`, importing the
8
+ * stateful glue from the entry chunk can duplicate it: `init()` then populates
9
+ * the `wasm` binding in one instance while these functions read `undefined` from
10
+ * another (→ `Cannot read properties of undefined (reading '__wbindgen_malloc…')`,
11
+ * seen when the codemirror tokenizer calls `tokenize` on the main thread).
12
+ * Mirrors `@fossil-lang/corpus`'s `client.ts` split, the known-good shape.
13
+ */
14
+ import { FossilPlayground as RawFossilPlayground, FileHandle as RawFileHandle, tokenize as rawTokenize, semantic_legend as rawSemanticLegend, tokenKinds as rawTokenKinds, start_lsp_worker as rawStartLspWorker, refs as rawRefs, providers as rawProviders, } from '../pkg/fossil_wasm.js';
15
+ /**
16
+ * Install the LSP-over-postMessage dispatcher on the current Worker scope.
17
+ *
18
+ * `fossil-wasm` IS the LSP server-side in the browser: `fossil-lsp` is
19
+ * native-only (it speaks stdio over crossbeam and does not compile to
20
+ * `wasm32`), so the Worker gets an equivalent 16-route dispatch loop over the
21
+ * same `fossil-ide` free functions. The Rust function (re-exported from
22
+ * `crates/fossil-wasm/src/lsp_worker.rs`) installs `self.onmessage` on the
23
+ * Worker scope and owns LSP JSON-RPC dispatch from that point forward.
24
+ *
25
+ * MUST be called inside a Web Worker scope, AFTER {@link initFossilWasm} has
26
+ * resolved. Calling it on the main thread is a no-op (the dispatcher needs
27
+ * `DedicatedWorkerGlobalScope.onmessage`).
28
+ */
29
+ export function start_lsp_worker() {
30
+ rawStartLspWorker();
31
+ }
32
+ /**
33
+ * Tokenize a Fossil source string. Returns the byte-range tokens from the
34
+ * canonical Rust lexer (`fossil_syntax::lexer::raw_lex`) — the single grammar
35
+ * source of truth, so no editor ever reimplements the lexer in TS and drifts.
36
+ *
37
+ * MUST be called after {@link initFossilWasm} has resolved; otherwise the
38
+ * underlying wasm-bindgen function throws (the wasm module is not yet
39
+ * instantiated).
40
+ */
41
+ export function tokenize(text) {
42
+ // The wasm-bindgen wrapper returns a `JsValue` typed as `any`; the Rust side
43
+ // (crates/fossil-wasm/src/tokenize.rs) serializes `Vec<TokenRow>` via
44
+ // `serde_wasm_bindgen::to_value`, so the shape matches `{ kind, start, end }`
45
+ // exactly. Cast is safe because the Rust ↔ JS contract is enforced upstream.
46
+ return rawTokenize(text);
47
+ }
48
+ /**
49
+ * The legend for {@link TokenRow.kind}: every lexer variant NAME, indexed by the
50
+ * discriminant a row carries. `tokenKinds()[row.kind]` is `"Comment"`,
51
+ * `"KwFrom"`, `"String"`, …
52
+ *
53
+ * **This is the contract, and the numbers are not.** `kind` is a variant
54
+ * discriminant of `fossil_syntax::lexer::Token`, so any reorder of that enum
55
+ * remaps every value with nothing going red. The predecessor of this package
56
+ * hard-coded the table (`enum FossilKind { Whitespace = 0, … }`) under a comment
57
+ * saying it had to be updated in lockstep; it was wrong in nine places by the
58
+ * time it was deleted. Keying on the name is what makes a reorder a non-event.
59
+ *
60
+ * An index past the end of the legend is a variant appended by a compiler newer
61
+ * than this host: `undefined`, and a host styles it as plain text.
62
+ *
63
+ * MUST be called after {@link initFossilWasm} has resolved.
64
+ */
65
+ export function tokenKinds() {
66
+ return rawTokenKinds();
67
+ }
68
+ /**
69
+ * Returns the LSP `SemanticTokensLegend` (token types + modifiers list) the
70
+ * editor uses to map LSP `semanticTokens/full` response indices to highlight
71
+ * categories. Re-export of `fossil_ide::semantic_legend` over the wasm-bindgen
72
+ * boundary — NO duplicate legend definition lives here.
73
+ *
74
+ * MUST be called after {@link initFossilWasm} has resolved.
75
+ */
76
+ export function semanticLegend() {
77
+ return rawSemanticLegend();
78
+ }
79
+ /**
80
+ * Parse a Fossil program and return its external references — the typed lineage
81
+ * (every data URI + `schema =` argument, each tagged with its `@conn` alias and
82
+ * role). keasy's client-compute job runner reads this to derive a job's
83
+ * connections WITHOUT subprocessing `fossil` / a server round-trip. Identical
84
+ * shape to the native `fossil refs` (the SAME `fossil_lineage::SourceRefInfo`
85
+ * struct), so the browser and the CLI never diverge.
86
+ *
87
+ * MUST be called after {@link initFossilWasm} has resolved.
88
+ */
89
+ export function refs(program) {
90
+ return rawRefs(program);
91
+ }
92
+ /**
93
+ * List the data-source providers fossil supports (`io.csv`, `io.rdf`, …) — the
94
+ * provider name, the extensions it reads, and how it can be used. Identical
95
+ * shape to the native `fossil providers`.
96
+ *
97
+ * MUST be called after {@link initFossilWasm} has resolved.
98
+ */
99
+ export function providers() {
100
+ return rawProviders();
101
+ }
102
+ /**
103
+ * Workspace API class. Thin TS wrapper around the wasm-bindgen
104
+ * `FossilPlayground` that exposes camelCase method names for JS idiom + better
105
+ * TS inference (the raw bindings use snake_case from the Rust impl block).
106
+ *
107
+ * One instance per browser tab / Node process — the instance owns the Salsa
108
+ * store + `Arc<OutputDescriptorKind>` for the schema slot.
109
+ *
110
+ * NOTE: {@link FileHandle} is opaque — JS cannot construct one. Callers receive
111
+ * a handle from `openFile` and pass it back to subsequent operations.
112
+ */
113
+ export class FossilPlayground {
114
+ _inner;
115
+ constructor() {
116
+ this._inner = new RawFossilPlayground();
117
+ }
118
+ /**
119
+ * Free the underlying WASM-side Salsa store. Call when the playground is no
120
+ * longer needed (e.g. component unmount).
121
+ */
122
+ free() {
123
+ this._inner.free();
124
+ }
125
+ /**
126
+ * Open a file in the workspace. Returns the {@link FileHandle} subsequent
127
+ * `updateFile` / `closeFile` / `diagnosticsFor` calls key on.
128
+ */
129
+ openFile(path, contents) {
130
+ return this._inner.open_file(path, contents);
131
+ }
132
+ /**
133
+ * Apply an edit to an open file. Mutates the SAME `SourceFile` via the Salsa
134
+ * `Setter` (`set_text`) — bumps the revision for incremental
135
+ * invalidation rather than a full recompute, and that revision bump is also
136
+ * what cancels any analysis still running on an older snapshot.
137
+ */
138
+ updateFile(handle, contents) {
139
+ this._inner.update_file(handle, contents);
140
+ }
141
+ /**
142
+ * Close a file in the workspace. Strict: closing an unknown / already-closed
143
+ * handle throws so JS-side bugs surface loudly.
144
+ */
145
+ closeFile(handle) {
146
+ this._inner.close_file(handle);
147
+ }
148
+ /**
149
+ * Workspace-wide diagnostic drain. Runs `parse → def_map → typecheck_mapping`
150
+ * across every open file and returns a flat array of {@link CheckRow}.
151
+ */
152
+ check() {
153
+ return this._inner.check();
154
+ }
155
+ /**
156
+ * Per-file diagnostic drain — the accessor the LSP Worker uses for its
157
+ * per-file `publishDiagnostics` notifications.
158
+ */
159
+ diagnosticsFor(handle) {
160
+ return this._inner.diagnostics_for(handle);
161
+ }
162
+ /**
163
+ * What is under the cursor — `{ markdown, range }`, or `null` when nothing
164
+ * there has a type.
165
+ *
166
+ * `line` / `character` are LSP: zero-based, `character` in UTF-16 code units.
167
+ * A CodeMirror or Monaco host already counts in those units, so a document
168
+ * offset converts with `doc.lineAt(pos)` and no byte arithmetic — unlike
169
+ * {@link tokenize}, whose offsets ARE bytes.
170
+ *
171
+ * ## Push the buffer before you ask
172
+ *
173
+ * This reads the text of the last {@link updateFile}. Hover fires on
174
+ * mouse-move and the checker is debounced, so a hover mid-debounce answers
175
+ * about text one keystroke old and its range lands one keystroke wrong. The
176
+ * three read-only methods take a SHARED borrow on the Rust side and cannot
177
+ * poison the workspace the way a re-entered `updateFile` once could — see the
178
+ * `ide` module in `crates/fossil-wasm` — but staleness is not a borrow
179
+ * problem and nothing here can fix it for you.
180
+ */
181
+ hover(handle, line, character) {
182
+ // `serde_wasm_bindgen` writes `None` as `undefined`; a host reading this
183
+ // should have one falsy answer to check, not two.
184
+ return this._inner.hover(handle, line, character) ?? null;
185
+ }
186
+ /**
187
+ * The completion candidates at a position, already narrowed by the receiver:
188
+ * `str.` offers string members and no reader, a property-key position offers
189
+ * the target shape's predicates and no catalogue row at all.
190
+ *
191
+ * `kind` is the LSP `CompletionItemKind` **by name** (`"function"`,
192
+ * `"field"`) rather than by number. The numbers never cross this boundary —
193
+ * `packages/codemirror-fossil`'s deleted predecessor is what happens when
194
+ * they do.
195
+ *
196
+ * The same staleness note as {@link hover} applies, and harder: completion
197
+ * fires on nearly every keystroke.
198
+ */
199
+ completions(handle, line, character) {
200
+ return this._inner.completions(handle, line, character);
201
+ }
202
+ /**
203
+ * Where the name under the cursor is defined. Empty when nothing there has a
204
+ * definition.
205
+ *
206
+ * `uri` is the key the buffer was opened under, verbatim — and two of the
207
+ * four positions this recognises resolve into the **shape document**, so a
208
+ * host with a single editor pane has to read `uri` before it moves a cursor.
209
+ */
210
+ gotoDefinition(handle, line, character) {
211
+ return this._inner.gotoDefinition(handle, line, character);
212
+ }
213
+ /**
214
+ * Register an {@link InferredDescriptorJson} under the source URI the program
215
+ * wrote, BEFORE invoking {@link check}. The Rust compiler reads from this
216
+ * during forward type propagation.
217
+ *
218
+ * The compiler never introspects a source itself: it performs no network or
219
+ * file IO — that would break the WASM gate and Salsa's determinism alike —
220
+ * so a host that wants column types must run the `DESCRIBE` and push the
221
+ * result in here.
222
+ *
223
+ * @throws Error if the descriptor JSON fails to deserialise on the Rust side.
224
+ */
225
+ registerInferredDescriptor(descriptor) {
226
+ // The wasm-bindgen wrapper accepts a JSON string; serialise here so callers
227
+ // pass a typed object.
228
+ this._inner.registerInferredDescriptor(JSON.stringify(descriptor));
229
+ }
230
+ }
231
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}