@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 +13 -11
- package/dist/client.d.ts +199 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +231 -0
- package/dist/client.js.map +1 -0
- package/dist/index.d.ts +115 -204
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -188
- package/dist/index.js.map +1 -1
- package/dist/load.d.ts +1 -1
- package/dist/load.js +1 -1
- package/package.json +2 -2
- package/pkg/fossil_wasm.d.ts +194 -111
- package/pkg/fossil_wasm.js +252 -131
- package/pkg/fossil_wasm_bg.wasm +0 -0
- package/pkg/fossil_wasm_bg.wasm.d.ts +7 -3
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[]
|
|
7
|
-
|
|
8
|
-
- `
|
|
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.
|
|
15
|
-
|
|
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('
|
|
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
|
-
-
|
|
68
|
-
-
|
|
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.
|
package/dist/client.d.ts
ADDED
|
@@ -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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"}
|