@markup-carve/carve-wasm 0.1.4 → 0.1.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.
@@ -0,0 +1,35 @@
1
+ import init, { ParserSession, toHtmlWithOptions } from '@markup-carve/carve-wasm/web'
2
+
3
+ const ready = init()
4
+ let session
5
+ self.onmessage = async ({ data: { id, action, source, changes } }) => {
6
+ try {
7
+ await ready
8
+ let value
9
+ switch (action) {
10
+ case 'open': {
11
+ const next = new ParserSession(source)
12
+ session?.free()
13
+ session = next
14
+ value = JSON.parse(session.snapshot())
15
+ break
16
+ }
17
+ case 'edit':
18
+ if (!session) throw new Error('Open a document before editing')
19
+ value = JSON.parse(session.edit(JSON.stringify(changes)))
20
+ break
21
+ case 'render':
22
+ value = toHtmlWithOptions(source, { rawHtml: false, profile: 'comment' })
23
+ break
24
+ case 'close':
25
+ session?.free()
26
+ session = undefined
27
+ value = null
28
+ break
29
+ default: throw new Error('Unknown worker action')
30
+ }
31
+ self.postMessage({ id, value })
32
+ } catch (error) {
33
+ self.postMessage({ id, error: { name: error.name, message: error.message } })
34
+ }
35
+ }
@@ -0,0 +1,3 @@
1
+ export function utf16ToUtf8(source: string, offset: number): number;
2
+ export function codepointToUtf8(source: string, offset: number): number;
3
+ export function utf8ToUtf16(source: string, offset: number): number;
@@ -0,0 +1,18 @@
1
+ const encoder = new TextEncoder()
2
+
3
+ function convert(source, offset, from, to) {
4
+ if (!Number.isSafeInteger(offset) || offset < 0) throw new RangeError('offset must be a non-negative safe integer')
5
+ const position = { utf16: 0, utf8: 0, codepoint: 0 }
6
+ for (const character of source) {
7
+ if (position[from] === offset) return position[to]
8
+ position.utf16 += character.length
9
+ position.utf8 += encoder.encode(character).length
10
+ position.codepoint++
11
+ if (position[from] > offset) throw new RangeError('offset splits a Unicode character')
12
+ }
13
+ if (position[from] !== offset) throw new RangeError('offset exceeds the source length')
14
+ return position[to]
15
+ }
16
+ export const utf16ToUtf8 = (source, offset) => convert(source, offset, 'utf16', 'utf8')
17
+ export const codepointToUtf8 = (source, offset) => convert(source, offset, 'codepoint', 'utf8')
18
+ export const utf8ToUtf16 = (source, offset) => convert(source, offset, 'utf8', 'utf16')
package/node/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mark Scherer
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/node/README.md ADDED
@@ -0,0 +1,105 @@
1
+ # carve-wasm
2
+
3
+ WebAssembly build of the [Carve](https://markup-carve.github.io/carve/) markup
4
+ renderer, compiled from
5
+ [carve-rs](https://github.com/markup-carve/carve-rs). It runs the Rust
6
+ implementation in browsers and powers the **Rust (WASM)** engine in the
7
+ [Carve playground](https://markup-carve.github.io/carve/playground).
8
+
9
+ ## Install
10
+
11
+ ```bash
12
+ npm install @markup-carve/carve-wasm
13
+ ```
14
+
15
+ ## Render Carve
16
+
17
+ The package root selects synchronous Node bindings in Node and the bundler
18
+ build in browser bundles. The browser bundler must support native WASM imports
19
+ and top-level await. Vite 8.3.2 is tested. See the
20
+ [compatibility guide](docs/compatibility.md) for explicit browser, Node and
21
+ rendering-only imports.
22
+
23
+ ```js
24
+ import { toHtml, toHtmlFull, toHtmlWithOptions } from '@markup-carve/carve-wasm'
25
+
26
+ toHtml('# Hello, Carve!')
27
+ toHtmlFull('# Hello\n\n``` mermaid\ngraph TD; A-->B\n```\n')
28
+ toHtmlWithOptions(source, {
29
+ extensions: ['glossary', 'table-of-contents'],
30
+ rawHtml: false,
31
+ sections: true,
32
+ })
33
+ ```
34
+
35
+ `toHtml` uses the core renderer. `toHtmlFull` enables the extension set used
36
+ by the playground preview. `toHtmlWithOptions` lets the caller choose
37
+ extensions and rendering policy. Unknown extension names throw instead of
38
+ silently producing incomplete output.
39
+
40
+ Other core targets include `toMarkdown`, `toPlainText`, `toAnsi`, and
41
+ `toCarve`. Each has a `*WithOptions` form.
42
+
43
+ ## Convert existing content
44
+
45
+ The package imports HTML, Markdown, Djot, and BBCode. `fromHtml`,
46
+ `fromMarkdown`, `migrateDjot`, and `migrateBbcode` return the converted value
47
+ with a fidelity report. The simpler `fromDjot` and `fromBbcode` helpers return
48
+ only the converted string.
49
+
50
+ Markdown, Djot, and BBCode reports currently mark fidelity as unverified. An
51
+ empty diagnostic list does not claim that every construct was preserved.
52
+
53
+ ```js
54
+ import { fromHtml, fromMarkdown, htmlToAst, htmlToCarve } from '@markup-carve/carve-wasm'
55
+
56
+ const { value, report } = htmlToCarve('<p>Hello <strong>world</strong></p>', 'safe')
57
+ const { value: ast } = htmlToAst('<p>Hello <b>world</b></p>', 'safe')
58
+
59
+ fromHtml(html, 'semantic')
60
+ fromMarkdown(markdown)
61
+ ```
62
+
63
+ HTML modes are `safe` (the default), `semantic`, and trusted-only
64
+ `roundtrip`. `htmlToAst` returns the serialized Carve AST without passing it
65
+ through the source writer, so its report can differ from `htmlToCarve` when a
66
+ construct is representable in the tree but not in Carve source.
67
+
68
+ ## Common host APIs
69
+
70
+ - `extensions()` returns the extension names supported by the bundled engine.
71
+ - `toCarvePatch()` and `applySourcePatch()` create and apply stale-safe UTF-8
72
+ byte edits.
73
+ - `toHtmlWithSymbols()` resolves configured `:name:` symbols. Symbol values
74
+ are trusted raw output and must not come from user input.
75
+ - `parseJson()`, `astJsonToHtml()`, and the other AST functions use the PART 12
76
+ AST JSON shared by Carve implementations.
77
+ - Include expansion calls a synchronous host resolver, records dependencies,
78
+ and enforces depth, byte, and call budgets. The resolver decides which paths
79
+ to refuse.
80
+ - `ParserSession` retains a document between edits and can reuse unchanged
81
+ plain paragraphs. Call `free()` when the editor closes. Tree patches,
82
+ three-way merge and ProseMirror helpers also support browser editors.
83
+
84
+ The [complete API and usage reference](docs/reference.md) documents these
85
+ APIs, renderer profiles, resource limits, includes, AST fields, and the
86
+ TypeScript declarations.
87
+
88
+ ## Security
89
+
90
+ Use `rawHtml: false` with a restrictive profile such as `comment` for
91
+ untrusted documents. Symbols and static renderer callbacks are trusted
92
+ configuration and may emit unescaped HTML. Treat source patches as trusted
93
+ edit instructions, not as signed data. A profile rejection throws.
94
+
95
+ Carve also enforces URL-scheme and attribute hardening in the renderer. See
96
+ the language [security documentation](https://markup-carve.github.io/carve/security)
97
+ for the complete model.
98
+
99
+ ## Development
100
+
101
+ Contributor documentation lives under `docs/`:
102
+
103
+ - [Building and testing](https://github.com/markup-carve/carve-wasm/blob/main/docs/building.md)
104
+ - [The carve-rs engine pin](https://github.com/markup-carve/carve-wasm/blob/main/docs/engine-pin.md)
105
+ - [Release process](https://github.com/markup-carve/carve-wasm/blob/main/docs/releasing.md)