@peisar/peisar-wasm32-wasi 0.2.22 → 0.3.1
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/package.json +4 -4
- package/peisar.wasi-browser.js +3 -3
- package/peisar.wasi.cjs +165 -5
- package/peisar.wasi.d.cts +140 -90
- package/peisar.wasm32-wasi.wasm +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@peisar/peisar-wasm32-wasi",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.01",
|
|
4
4
|
"main": "peisar.wasi.cjs",
|
|
5
5
|
"files": [
|
|
6
6
|
"peisar.wasm32-wasi.wasm",
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
"browser": "peisar.wasi-browser.js",
|
|
31
31
|
"type": "module",
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@napi-rs/wasm-runtime": "~1.2.
|
|
34
|
-
"@emnapi/core": "2.0.0-alpha.
|
|
35
|
-
"@emnapi/runtime": "2.0.0-alpha.
|
|
33
|
+
"@napi-rs/wasm-runtime": "~1.2.5",
|
|
34
|
+
"@emnapi/core": "2.0.0-alpha.6",
|
|
35
|
+
"@emnapi/runtime": "2.0.0-alpha.6"
|
|
36
36
|
}
|
|
37
37
|
}
|
package/peisar.wasi-browser.js
CHANGED
|
@@ -1441,6 +1441,6 @@ try {
|
|
|
1441
1441
|
}
|
|
1442
1442
|
export default __napiModule.exports
|
|
1443
1443
|
export const Peisar = __napiModule.exports.Peisar
|
|
1444
|
-
export const
|
|
1445
|
-
export const
|
|
1446
|
-
export const
|
|
1444
|
+
export const PeisarCache = __napiModule.exports.PeisarCache
|
|
1445
|
+
export const frontmatter = __napiModule.exports.frontmatter
|
|
1446
|
+
export const yamlParser = __napiModule.exports.yamlParser
|
package/peisar.wasi.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
// napi-rs-artifact-metadata:{"version":2,"rootEntry":"index.
|
|
1
|
+
// napi-rs-artifact-metadata:{"version":2,"rootEntry":"index.cjs","exports":["Peisar","PeisarCache","frontmatter","yamlParser"],"managedRootEntries":["browser.js","index.cjs","peisar.wasm","peisar.debug.wasm"]}
|
|
2
2
|
/* eslint-disable */
|
|
3
3
|
/* auto-generated by NAPI-RS */
|
|
4
4
|
|
|
@@ -222,6 +222,34 @@ function __hasWasiThreadCrashed() {
|
|
|
222
222
|
}
|
|
223
223
|
|
|
224
224
|
let __wasiThreadCrashDisposePromise
|
|
225
|
+
// Raised by the crash disposal right before it terminates the workers. See
|
|
226
|
+
// `__wasiSetImmediate`.
|
|
227
|
+
let __wasiReentryClosed = false
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* emnapi's `features.setImmediate` for this binding's context. emnapi defers
|
|
231
|
+
* its calls back into wasm through it: `_emnapi_set_immediate` (libuv handle
|
|
232
|
+
* closes, threadsafe-function finalizers), threadsafe-function dispatch
|
|
233
|
+
* (`async-send`) and the finalizer queue. One queued before a crash disposal
|
|
234
|
+
* terminates the workers still runs after it, and a worker terminated while it
|
|
235
|
+
* held a lock in the wasm heap (napi's heap-sync allocator lock spins and never
|
|
236
|
+
* gives up) leaves that call spinning on this thread for good. The binding is
|
|
237
|
+
* unusable after a crash disposal, so those calls are dropped.
|
|
238
|
+
*
|
|
239
|
+
* Known residual, still able to enter wasm after a crash disposal because emnapi
|
|
240
|
+
* offers no hook for them: the `FinalizationRegistry` callbacks that free
|
|
241
|
+
* external memory when GC collects a value (`_free`, the shared-buffer meta
|
|
242
|
+
* release), threadsafe-function dispatch of `async-send` type 1 and
|
|
243
|
+
* `_emnapi_next_tick` (both `Promise.resolve().then`), and every deferred
|
|
244
|
+
* call under emnapi 1.x, whose `createContext` ignores `features`.
|
|
245
|
+
*/
|
|
246
|
+
function __wasiSetImmediate(callback) {
|
|
247
|
+
return setImmediate(function () {
|
|
248
|
+
if (!__wasiReentryClosed) {
|
|
249
|
+
callback()
|
|
250
|
+
}
|
|
251
|
+
})
|
|
252
|
+
}
|
|
225
253
|
|
|
226
254
|
/**
|
|
227
255
|
* Stores the first error a pool worker reported, with the worker's id. Called
|
|
@@ -371,6 +399,8 @@ function __disposeWasiBindingAfterThreadCrash() {
|
|
|
371
399
|
return __wasiThreadCrashDisposePromise
|
|
372
400
|
}
|
|
373
401
|
__releaseEmnapiWaitingRequestHandle()
|
|
402
|
+
// No call into wasm after this: see `__wasiSetImmediate`.
|
|
403
|
+
__wasiReentryClosed = true
|
|
374
404
|
let workerResult
|
|
375
405
|
try {
|
|
376
406
|
workerResult = __terminateWasiWorkers()
|
|
@@ -455,6 +485,130 @@ function __rollbackWasiInitializationAfterThreadCrash() {
|
|
|
455
485
|
return [crashError]
|
|
456
486
|
}
|
|
457
487
|
|
|
488
|
+
const __wasiThreadPoolReconcileSymbol = Symbol.for('napi.rs.wasi.reconcileThreadPool')
|
|
489
|
+
|
|
490
|
+
/**
|
|
491
|
+
* Takes a Worker out of emnapi's reuse pool, if it is still there. emnapi
|
|
492
|
+
* terminates a pooled Worker that failed to load but (up to
|
|
493
|
+
* @emnapi/wasi-threads 2.1.0) leaves it in the pool, where the next thread
|
|
494
|
+
* spawn would pop it. A newer emnapi removes it itself, so this is a no-op
|
|
495
|
+
* then.
|
|
496
|
+
*/
|
|
497
|
+
function __removeWasiPoolWorker(manager, worker) {
|
|
498
|
+
const index = manager.unusedWorkers.indexOf(worker)
|
|
499
|
+
if (index !== -1) {
|
|
500
|
+
manager.unusedWorkers.splice(index, 1)
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Takes a Worker the thread manager just terminated out of `__wasiWorkers`
|
|
506
|
+
* once it has exited, not before. `terminateWorker` only starts Node's
|
|
507
|
+
* asynchronous `worker.terminate()` and drops its promise, so a disposal that
|
|
508
|
+
* begins before the exit has to find this Worker in the set and wait for it
|
|
509
|
+
* like any other. A second `terminate()` settles when the Worker has exited,
|
|
510
|
+
* the way `__terminateWasiWorkers` waits.
|
|
511
|
+
*/
|
|
512
|
+
function __untrackWasiWorkerOnExit(worker) {
|
|
513
|
+
const terminated = worker.terminate()
|
|
514
|
+
if (__isThenable(terminated)) {
|
|
515
|
+
Promise.resolve(terminated).then(
|
|
516
|
+
() => {
|
|
517
|
+
__wasiWorkers.delete(worker)
|
|
518
|
+
},
|
|
519
|
+
// Left tracked: disposal terminates it again and reports the error.
|
|
520
|
+
() => {},
|
|
521
|
+
)
|
|
522
|
+
} else {
|
|
523
|
+
__wasiWorkers.delete(worker)
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Matches emnapi's idle reuse pool to the addon's configured MultiThread worker
|
|
529
|
+
* count, which the addon exports as `napi_wasm_runtime_pool_workers`
|
|
530
|
+
* (napi-async-runtime; 0 under CurrentThread). `reuseWorker: true` starts the
|
|
531
|
+
* pool empty, so without this every pool thread the first async call spawns
|
|
532
|
+
* boots a Worker and loads the wasm into it first. Here each missing Worker is
|
|
533
|
+
* created and starts loading now; a spawn later pops one that is already
|
|
534
|
+
* booting. Idle Workers above the count are terminated, last in first out,
|
|
535
|
+
* the way a spawn takes them. A Worker a spawn already took is not in the pool
|
|
536
|
+
* and is left alone.
|
|
537
|
+
*
|
|
538
|
+
* Runs once after a successful load and, when the loader wraps it, after every
|
|
539
|
+
* successful `configureAsyncRuntime`. Also reachable as
|
|
540
|
+
* binding[Symbol.for('napi.rs.wasi.reconcileThreadPool')]().
|
|
541
|
+
* It never throws and never waits on a Worker: a Worker whose load fails is
|
|
542
|
+
* dropped from the pool when its load rejects. Nothing at all happens after a
|
|
543
|
+
* thread crash, once disposal started, or for an addon without the export.
|
|
544
|
+
*/
|
|
545
|
+
function __reconcileWasiThreadPool() {
|
|
546
|
+
try {
|
|
547
|
+
if (__wasiDisposed || __wasiDisposePromise || __hasWasiThreadCrashed()) {
|
|
548
|
+
return
|
|
549
|
+
}
|
|
550
|
+
const read = __napiInstance?.exports?.napi_wasm_runtime_pool_workers
|
|
551
|
+
if (typeof read !== 'function') {
|
|
552
|
+
return
|
|
553
|
+
}
|
|
554
|
+
const count = read() >>> 0
|
|
555
|
+
const manager = __getWasiThreadManager()
|
|
556
|
+
if (
|
|
557
|
+
!manager ||
|
|
558
|
+
!Array.isArray(manager.unusedWorkers) ||
|
|
559
|
+
typeof manager.allocateUnusedWorker !== 'function' ||
|
|
560
|
+
typeof manager.loadWasmModuleToWorker !== 'function'
|
|
561
|
+
) {
|
|
562
|
+
return
|
|
563
|
+
}
|
|
564
|
+
// Both loops are bounded by the difference they start from, so a manager
|
|
565
|
+
// that does not update `unusedWorkers` the way emnapi does cannot spin.
|
|
566
|
+
for (let excess = manager.unusedWorkers.length - count; excess > 0; excess--) {
|
|
567
|
+
const worker = manager.unusedWorkers[manager.unusedWorkers.length - 1]
|
|
568
|
+
manager.terminateWorker(worker)
|
|
569
|
+
__removeWasiPoolWorker(manager, worker)
|
|
570
|
+
__untrackWasiWorkerOnExit(worker)
|
|
571
|
+
// Compatibility with @emnapi/wasi-threads 2.1.0 and older:
|
|
572
|
+
// `terminateWorker` installs a reporter that logs every emnapi message
|
|
573
|
+
// still queued on the port, so a Worker that finished loading just
|
|
574
|
+
// before it was terminated prints 'received "loaded" command from
|
|
575
|
+
// terminated worker'. Nothing listens for that Worker any more, and a
|
|
576
|
+
// newer emnapi ignores the late 'loaded' itself, so this is harmless
|
|
577
|
+
// there. `__terminateWasiWorkers` does the same.
|
|
578
|
+
worker.onmessage = undefined
|
|
579
|
+
}
|
|
580
|
+
for (let missing = count - manager.unusedWorkers.length; missing > 0; missing--) {
|
|
581
|
+
let worker
|
|
582
|
+
try {
|
|
583
|
+
// Through `onCreateWorker`: tracked in `__wasiWorkers`, unref'd, and
|
|
584
|
+
// handed the crash flags like any pool Worker.
|
|
585
|
+
worker = manager.allocateUnusedWorker()
|
|
586
|
+
manager
|
|
587
|
+
.loadWasmModuleToWorker(worker)
|
|
588
|
+
.then(undefined, () => __removeWasiPoolWorker(manager, worker))
|
|
589
|
+
} catch {
|
|
590
|
+
if (worker !== undefined) {
|
|
591
|
+
__removeWasiPoolWorker(manager, worker)
|
|
592
|
+
try {
|
|
593
|
+
manager.terminateWorker(worker)
|
|
594
|
+
__untrackWasiWorkerOnExit(worker)
|
|
595
|
+
} catch {}
|
|
596
|
+
}
|
|
597
|
+
return
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
} catch {}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
function __publishWasiThreadPoolReconcile(exports) {
|
|
604
|
+
Object.defineProperty(exports, __wasiThreadPoolReconcileSymbol, {
|
|
605
|
+
configurable: false,
|
|
606
|
+
enumerable: false,
|
|
607
|
+
value: __reconcileWasiThreadPool,
|
|
608
|
+
writable: false,
|
|
609
|
+
})
|
|
610
|
+
}
|
|
611
|
+
|
|
458
612
|
const __cwd = process.cwd()
|
|
459
613
|
const __rootDir = __nodePath.parse(__cwd).root
|
|
460
614
|
const __hostRoot =
|
|
@@ -2011,7 +2165,7 @@ try {
|
|
|
2011
2165
|
const __finishAutoDestroyCapture = __captureEmnapiAutoDestroyListener()
|
|
2012
2166
|
try {
|
|
2013
2167
|
__emnapiContext = __wrapEmnapiContextDestroyForSettlement(
|
|
2014
|
-
__emnapiCreateContext({ autoDestroy: false }),
|
|
2168
|
+
__emnapiCreateContext({ autoDestroy: false, features: { setImmediate: __wasiSetImmediate } }),
|
|
2015
2169
|
__prepareWasmEnvCleanup,
|
|
2016
2170
|
__isPreparingWasmEnvCleanup,
|
|
2017
2171
|
)
|
|
@@ -2108,6 +2262,7 @@ try {
|
|
|
2108
2262
|
},
|
|
2109
2263
|
}))
|
|
2110
2264
|
__publishWasiDispose(__napiModule.exports)
|
|
2265
|
+
__publishWasiThreadPoolReconcile(__napiModule.exports)
|
|
2111
2266
|
// The CommonJS tail below aliases `__napiModule.exports`; a named module
|
|
2112
2267
|
// export does not travel with it, so carry the marker on the binding itself
|
|
2113
2268
|
// too. Three things pin the stamp to exactly this spot:
|
|
@@ -2136,8 +2291,13 @@ try {
|
|
|
2136
2291
|
__runWasiInitializationRollback(rollback)
|
|
2137
2292
|
throw rollback.error
|
|
2138
2293
|
}
|
|
2294
|
+
// Preload the pool for the count the addon configured during registration.
|
|
2295
|
+
// See `__reconcileWasiThreadPool`.
|
|
2296
|
+
try {
|
|
2297
|
+
__reconcileWasiThreadPool()
|
|
2298
|
+
} catch {}
|
|
2139
2299
|
module.exports = __napiModule.exports
|
|
2140
2300
|
module.exports.Peisar = __napiModule.exports.Peisar
|
|
2141
|
-
module.exports.
|
|
2142
|
-
module.exports.
|
|
2143
|
-
module.exports.
|
|
2301
|
+
module.exports.PeisarCache = __napiModule.exports.PeisarCache
|
|
2302
|
+
module.exports.frontmatter = __napiModule.exports.frontmatter
|
|
2303
|
+
module.exports.yamlParser = __napiModule.exports.yamlParser
|
package/peisar.wasi.d.cts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
export type PeisarEmphasisLevel = "Italic" | "Bold";
|
|
2
|
+
export type PeisarTableCellAlignment = "Default" | "Left" | "Center" | "Right";
|
|
3
|
+
export type PeisarTableCellAlignments = PeisarTableCellAlignment[];
|
|
4
|
+
export type PeisarTaskState = "Unchecked" | "Checked";
|
|
3
5
|
|
|
4
6
|
/** The WASI flavor this loader instantiates. */
|
|
5
7
|
export declare const __napiBindingTarget: 'wasm32-wasi'
|
|
@@ -65,6 +67,73 @@ export declare class Peisar {
|
|
|
65
67
|
get astJson(): string
|
|
66
68
|
}
|
|
67
69
|
|
|
70
|
+
/**
|
|
71
|
+
* In-memory cache of the Markdown and asset files under a directory tree.
|
|
72
|
+
*
|
|
73
|
+
* The cache maps absolute source paths to [`CachedContent`] entries, is
|
|
74
|
+
* mirrored to a `.peisar_cache` directory on disk, and — after
|
|
75
|
+
* [`PeisarCache::start_watching`] — tracks the source directories with a
|
|
76
|
+
* recursive file watcher.
|
|
77
|
+
*
|
|
78
|
+
* Rust consumers read the cache with [`PeisarCache::get`] and
|
|
79
|
+
* [`PeisarCache::all`]; JavaScript consumers use the N-API methods below
|
|
80
|
+
* (`getText`, `getBinary`, `listFiles`, `markdownFiles`, `assetFiles`, …).
|
|
81
|
+
*/
|
|
82
|
+
export declare class PeisarCache {
|
|
83
|
+
/**
|
|
84
|
+
* Construct a new PeisarCache using the default discovery behavior.
|
|
85
|
+
*
|
|
86
|
+
* JS: `new PeisarCache(entryDir, assetsDir?)` — both plain strings.
|
|
87
|
+
*/
|
|
88
|
+
constructor(entryDir: string, assetsDir?: string | undefined | null)
|
|
89
|
+
/**
|
|
90
|
+
* JS: same as the constructor, for callers that prefer a factory shape.
|
|
91
|
+
* Kept non-generic so NAPI can export it.
|
|
92
|
+
*/
|
|
93
|
+
static withConfigJs(entryDir: string, assetsDir?: string | undefined | null): PeisarCache
|
|
94
|
+
/**
|
|
95
|
+
* JS: `cache.startWatchingJs()` — start watching the entry (and
|
|
96
|
+
* assets) directories recursively; errors surface as JS exceptions.
|
|
97
|
+
*/
|
|
98
|
+
startWatchingJs(): void
|
|
99
|
+
/**
|
|
100
|
+
* ----------------------------------------------------------------
|
|
101
|
+
* JavaScript (NAPI) surface
|
|
102
|
+
* ----------------------------------------------------------------
|
|
103
|
+
* All JS methods take/return plain strings because `&Path`/`PathBuf`
|
|
104
|
+
* do not cross the NAPI boundary.
|
|
105
|
+
* JS: `cache.getText(absPath)` — cached text of a file, or null.
|
|
106
|
+
*/
|
|
107
|
+
getText(absPath: string): string | null
|
|
108
|
+
/** JS: `cache.getBinary(absPath)` — cached bytes of a binary asset, or null. */
|
|
109
|
+
getBinary(absPath: string): Array<number> | null
|
|
110
|
+
/** JS: `cache.listFiles()` — absolute paths of everything cached. */
|
|
111
|
+
listFiles(): Array<string>
|
|
112
|
+
/** JS: `cache.markdownFiles()` — absolute paths of cached markdown files. */
|
|
113
|
+
markdownFiles(): Array<string>
|
|
114
|
+
/** JS: `cache.assetFiles()` — absolute paths of cached non-markdown files. */
|
|
115
|
+
assetFiles(): Array<string>
|
|
116
|
+
/**
|
|
117
|
+
* JS: `cache.onChange(cb)` — invoke `cb(event)` on every file change the
|
|
118
|
+
* watcher detects while watching is active. Returns a subscription id
|
|
119
|
+
* that can be passed to `offChange(id)`.
|
|
120
|
+
*
|
|
121
|
+
* The callback is wrapped in a `ThreadsafeFunction` because notify
|
|
122
|
+
* events fire on the watcher thread, not the JS main thread.
|
|
123
|
+
*/
|
|
124
|
+
onChange(callback: (event: CacheChangeEvent) => void): number
|
|
125
|
+
/** JS: `cache.offChange(id)` — remove a previously registered callback. */
|
|
126
|
+
offChange(id: number): void
|
|
127
|
+
/**
|
|
128
|
+
* JS: `cache.dispose()` — stop the watcher and drop JS change callbacks.
|
|
129
|
+
* Safe to call more than once.
|
|
130
|
+
*
|
|
131
|
+
* Rust consumers do not need this: dropping the [`PeisarCache`] stops
|
|
132
|
+
* the watcher, closes the persistence channel, and joins the worker.
|
|
133
|
+
*/
|
|
134
|
+
dispose(): void
|
|
135
|
+
}
|
|
136
|
+
|
|
68
137
|
/**
|
|
69
138
|
* Options that control how Markdown is parsed.
|
|
70
139
|
*
|
|
@@ -149,13 +218,13 @@ export type Block =
|
|
|
149
218
|
* Synchronous block-visitor callback. Receives a `Block`, returns
|
|
150
219
|
* `VisitControlJs` (or `undefined` for no changes).
|
|
151
220
|
*/
|
|
152
|
-
export type BlockCallback = (arg: [Block]) =>
|
|
221
|
+
export type BlockCallback = (arg: [Block]) => VisitorControl | null
|
|
153
222
|
|
|
154
223
|
/**
|
|
155
224
|
* Synchronous block parser hook. Receives a [`BlockParseContext`], returns
|
|
156
225
|
* a [`BlockParseResultJs`] (or `undefined` to decline).
|
|
157
226
|
*/
|
|
158
|
-
export type BlockParseCallback = (arg: [BlockParseContext]) =>
|
|
227
|
+
export type BlockParseCallback = (arg: [BlockParseContext]) => BlockParseResult | null
|
|
159
228
|
|
|
160
229
|
/**
|
|
161
230
|
* Context passed to block parser hooks.
|
|
@@ -178,13 +247,35 @@ export interface BlockParseContext {
|
|
|
178
247
|
* All fields are optional; omitting `block` (or returning `undefined`)
|
|
179
248
|
* declines the position so the next hook / built-in parser handles it.
|
|
180
249
|
*/
|
|
181
|
-
export interface
|
|
250
|
+
export interface BlockParseResult {
|
|
182
251
|
/** The parsed block node. */
|
|
183
252
|
block?: Block
|
|
184
253
|
/** Number of source lines consumed (must be at least `1`). */
|
|
185
254
|
consumed?: number
|
|
186
255
|
}
|
|
187
256
|
|
|
257
|
+
/**
|
|
258
|
+
* A file-change event delivered to change callbacks
|
|
259
|
+
* (see [`PeisarCache::on_change`]).
|
|
260
|
+
*/
|
|
261
|
+
export interface CacheChangeEvent {
|
|
262
|
+
/** Absolute path of the changed file. */
|
|
263
|
+
path: string
|
|
264
|
+
/** `"create"`, `"modify"`, `"remove"`, or `"other"`. */
|
|
265
|
+
kind: string
|
|
266
|
+
/** `true` when the file is under the markdown entry directory. */
|
|
267
|
+
isMarkdown: boolean
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* An entry stored in the cache: raw UTF-8 text (markdown and textual
|
|
272
|
+
* assets) or raw bytes (binary assets). Exposed to JavaScript so JS
|
|
273
|
+
* consumers can branch on the variant.
|
|
274
|
+
*/
|
|
275
|
+
export type CachedContent =
|
|
276
|
+
| { type: 'Text'; field0: string }
|
|
277
|
+
| { type: 'Binary'; field0: Array<number> }
|
|
278
|
+
|
|
188
279
|
/**
|
|
189
280
|
* A Markdown document — the root of the AST.
|
|
190
281
|
*
|
|
@@ -204,12 +295,14 @@ export interface Document {
|
|
|
204
295
|
linkReferences: Array<LinkReferenceDefinition>
|
|
205
296
|
}
|
|
206
297
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
/**
|
|
212
|
-
|
|
298
|
+
export declare function frontmatter(content: string): FrontmatterResult
|
|
299
|
+
|
|
300
|
+
/** The Markdown body and YAML metadata parsed from a front-matter document. */
|
|
301
|
+
export interface FrontmatterResult {
|
|
302
|
+
/** Markdown source after the leading YAML front matter is removed. */
|
|
303
|
+
pureMarkdownContent: string
|
|
304
|
+
/** Deserialized YAML front matter, or `null` when no front matter exists. */
|
|
305
|
+
yamlData?: Record<string, any>
|
|
213
306
|
}
|
|
214
307
|
|
|
215
308
|
/** Inline-level nodes. */
|
|
@@ -218,7 +311,7 @@ export type Inline =
|
|
|
218
311
|
value: string; /** Source span. */
|
|
219
312
|
pos: Span }
|
|
220
313
|
| { type: 'Emphasis'; /** Emphasis level (italic or bold). */
|
|
221
|
-
level:
|
|
314
|
+
level: PeisarEmphasisLevel; /** Nested inline content. */
|
|
222
315
|
children: Array<Inline>; /** Source span. */
|
|
223
316
|
pos: Span }
|
|
224
317
|
| { type: 'Code'; /** The code text. */
|
|
@@ -256,13 +349,13 @@ export type Inline =
|
|
|
256
349
|
* Synchronous inline-visitor callback. Receives an `Inline`, returns
|
|
257
350
|
* `InlineVisitControlJs` (or `undefined` for no changes).
|
|
258
351
|
*/
|
|
259
|
-
export type InlineCallback = (arg: [Inline]) =>
|
|
352
|
+
export type InlineCallback = (arg: [Inline]) => InlineVisitorControl | null
|
|
260
353
|
|
|
261
354
|
/**
|
|
262
355
|
* Synchronous inline parser hook. Receives an [`InlineParseContext`],
|
|
263
356
|
* returns an [`InlineParseResultJs`] (or `undefined` to decline).
|
|
264
357
|
*/
|
|
265
|
-
export type InlineParseCallback = (arg: [InlineParseContext]) =>
|
|
358
|
+
export type InlineParseCallback = (arg: [InlineParseContext]) => InlineParseResult | null
|
|
266
359
|
|
|
267
360
|
/**
|
|
268
361
|
* Context passed to inline parser hooks.
|
|
@@ -282,7 +375,7 @@ export interface InlineParseContext {
|
|
|
282
375
|
* All fields are optional; omitting `inline` (or returning `undefined`)
|
|
283
376
|
* declines the position so the next hook / built-in parser handles it.
|
|
284
377
|
*/
|
|
285
|
-
export interface
|
|
378
|
+
export interface InlineParseResult {
|
|
286
379
|
/** The parsed inline node. */
|
|
287
380
|
inline?: Inline
|
|
288
381
|
/** Number of characters consumed (`0` or missing declines). */
|
|
@@ -295,7 +388,7 @@ export interface InlineParseResultJs {
|
|
|
295
388
|
* Returned from the JS `visitInline` callback. All fields are optional;
|
|
296
389
|
* omitting a field means "no change" for that operation.
|
|
297
390
|
*/
|
|
298
|
-
export interface
|
|
391
|
+
export interface InlineVisitorControl {
|
|
299
392
|
/** Nodes to insert before the current node. */
|
|
300
393
|
insertBefore?: Array<Inline>
|
|
301
394
|
/** Nodes to insert after the current node. */
|
|
@@ -325,39 +418,12 @@ export interface ListItem {
|
|
|
325
418
|
/** Nested block content of the item. */
|
|
326
419
|
children: Array<Block>
|
|
327
420
|
/** GFM task-list state: `None` = not a task, `Some` = checked / unchecked. */
|
|
328
|
-
task?:
|
|
421
|
+
task?: PeisarTaskState
|
|
329
422
|
/** Span of the item in the *sub-document* of its enclosing list. */
|
|
330
423
|
pos: Span
|
|
331
424
|
}
|
|
332
425
|
|
|
333
|
-
/**
|
|
334
|
-
* JavaScript object shape for a parser hook pair.
|
|
335
|
-
*
|
|
336
|
-
* ```js
|
|
337
|
-
* const myParser = {
|
|
338
|
-
* parseBlock(ctx) {
|
|
339
|
-
* if (!ctx.line.startsWith(':::')) return; // decline
|
|
340
|
-
* const name = ctx.line.slice(3).trim();
|
|
341
|
-
* return {
|
|
342
|
-
* block: { type: 'HtmlBlock', html: `<div data-name="${name}"></div>`, pos: { start: {}, end: {} } },
|
|
343
|
-
* consumed: 1,
|
|
344
|
-
* };
|
|
345
|
-
* },
|
|
346
|
-
* parseInline(ctx) {
|
|
347
|
-
* if (!ctx.rest.startsWith('@@')) return; // decline
|
|
348
|
-
* const end = ctx.rest.indexOf(' ', 2);
|
|
349
|
-
* const name = end === -1 ? ctx.rest.slice(2) : ctx.rest.slice(2, end);
|
|
350
|
-
* return {
|
|
351
|
-
* inline: { type: 'HtmlInline', html: `<span data-name="${name}"></span>`, pos: { start: {}, end: {} } },
|
|
352
|
-
* consumed: name.length + 2,
|
|
353
|
-
* };
|
|
354
|
-
* },
|
|
355
|
-
* };
|
|
356
|
-
* document.useParser(myParser);
|
|
357
|
-
* ```
|
|
358
|
-
*
|
|
359
|
-
* Either property may be omitted / `null` to skip that phase.
|
|
360
|
-
*/
|
|
426
|
+
/** Either property may be omitted / `null` to skip that phase. */
|
|
361
427
|
export interface Parser {
|
|
362
428
|
/** Optional JS block parser hook (JS: `parseBlock`). */
|
|
363
429
|
parseBlock?: BlockParseCallback
|
|
@@ -365,14 +431,6 @@ export interface Parser {
|
|
|
365
431
|
parseInline?: InlineParseCallback
|
|
366
432
|
}
|
|
367
433
|
|
|
368
|
-
/** The Markdown body and YAML metadata parsed from a front-matter document. */
|
|
369
|
-
export interface ParseResult {
|
|
370
|
-
/** Markdown source after the leading YAML front matter is removed. */
|
|
371
|
-
pureMarkdownContent: string
|
|
372
|
-
/** Deserialized YAML front matter, or `null` when no front matter exists. */
|
|
373
|
-
yamlData?: Record<string, any>
|
|
374
|
-
}
|
|
375
|
-
|
|
376
434
|
/**
|
|
377
435
|
* JavaScript options for Markdown parsing and HTML rendering.
|
|
378
436
|
*
|
|
@@ -507,7 +565,7 @@ export interface Table {
|
|
|
507
565
|
/** Body rows. */
|
|
508
566
|
rows: Array<TableRow>
|
|
509
567
|
/** Column alignment specifications (one per column). */
|
|
510
|
-
alignments:
|
|
568
|
+
alignments: PeisarTableCellAlignments
|
|
511
569
|
}
|
|
512
570
|
|
|
513
571
|
/** A single table cell. */
|
|
@@ -516,30 +574,33 @@ export interface TableCell {
|
|
|
516
574
|
children: Array<Inline>
|
|
517
575
|
}
|
|
518
576
|
|
|
519
|
-
/** Column alignment for table cells. */
|
|
520
|
-
export declare const enum TableCellAlignment {
|
|
521
|
-
/** `:---` or `---` — default (left) */
|
|
522
|
-
Default = 0,
|
|
523
|
-
/** `:---` */
|
|
524
|
-
Left = 1,
|
|
525
|
-
/** `:---:` */
|
|
526
|
-
Center = 2,
|
|
527
|
-
/** `---:` */
|
|
528
|
-
Right = 3,
|
|
529
|
-
}
|
|
530
|
-
|
|
531
577
|
/** A single table row (header or body). */
|
|
532
578
|
export interface TableRow {
|
|
533
579
|
/** The cells in this row. */
|
|
534
580
|
cells: Array<TableCell>
|
|
535
581
|
}
|
|
536
582
|
|
|
537
|
-
/**
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
583
|
+
/**
|
|
584
|
+
* JavaScript object shape for a visitor callback pair.
|
|
585
|
+
*
|
|
586
|
+
* On the JS side it is a plain object with two optional
|
|
587
|
+
* function properties:
|
|
588
|
+
*
|
|
589
|
+
* ```js
|
|
590
|
+
* const myPlugin = {
|
|
591
|
+
* visitBlock(block) { return { recurse: true }; },
|
|
592
|
+
* visitInline(inline) { return {}; },
|
|
593
|
+
* };
|
|
594
|
+
* ast.addVisitor(myPlugin);
|
|
595
|
+
* ```
|
|
596
|
+
*
|
|
597
|
+
* Either property may be omitted / `null` to skip that node kind.
|
|
598
|
+
*/
|
|
599
|
+
export interface Visitor {
|
|
600
|
+
/** Optional JS callback for block nodes (JS: `visitBlock`). */
|
|
601
|
+
visitBlock?: BlockCallback
|
|
602
|
+
/** Optional JS callback for inline nodes (JS: `visitInline`). */
|
|
603
|
+
visitInline?: InlineCallback
|
|
543
604
|
}
|
|
544
605
|
|
|
545
606
|
/**
|
|
@@ -548,7 +609,7 @@ export declare const enum TaskState {
|
|
|
548
609
|
* Returned from the JS `visitBlock` callback. All fields are optional;
|
|
549
610
|
* omitting a field means "no change" for that operation.
|
|
550
611
|
*/
|
|
551
|
-
export interface
|
|
612
|
+
export interface VisitorControl {
|
|
552
613
|
/** Nodes to insert before the current node. */
|
|
553
614
|
insertBefore?: Array<Block>
|
|
554
615
|
/** Nodes to insert after the current node. */
|
|
@@ -562,24 +623,13 @@ export interface VisitControlJs {
|
|
|
562
623
|
}
|
|
563
624
|
|
|
564
625
|
/**
|
|
565
|
-
*
|
|
626
|
+
* Parses a YAML document into a JSON-compatible value.
|
|
566
627
|
*
|
|
567
|
-
*
|
|
568
|
-
*
|
|
628
|
+
* When consumed from Node.js, the result is exposed as a JavaScript object
|
|
629
|
+
* with the TypeScript type `Record<string, any>`.
|
|
569
630
|
*
|
|
570
|
-
*
|
|
571
|
-
* const myPlugin = {
|
|
572
|
-
* visitBlock(block) { return { recurse: true }; },
|
|
573
|
-
* visitInline(inline) { return {}; },
|
|
574
|
-
* };
|
|
575
|
-
* ast.addVisitor(myPlugin);
|
|
576
|
-
* ```
|
|
631
|
+
* # Panics
|
|
577
632
|
*
|
|
578
|
-
*
|
|
633
|
+
* Panics when `yaml_str` is not valid YAML.
|
|
579
634
|
*/
|
|
580
|
-
export
|
|
581
|
-
/** Optional JS callback for block nodes (JS: `visitBlock`). */
|
|
582
|
-
visitBlock?: BlockCallback
|
|
583
|
-
/** Optional JS callback for inline nodes (JS: `visitInline`). */
|
|
584
|
-
visitInline?: InlineCallback
|
|
585
|
-
}
|
|
635
|
+
export declare function yamlParser(yamlStr: string): Record<string, any>
|
package/peisar.wasm32-wasi.wasm
CHANGED
|
Binary file
|