fix: map char level ranges to prosemirror positions

ProseMirror's document model is a tree structure where positions are
calculated by traversing nodes, accounting for structural elements
(opening/closing tags of nodes like paragraphs, lists, etc.). A position
in ProseMirror is not "character index N". Structual boundaries like
"start of paragraph" also get their own index. A document with two
paragraphs "ab" and "cd" has positions:

  0   1 2 3   4   5 6 7   8
  <p> a b </p><p> c d </p>

So when I serialize a ProseMirror document to plain text for external
processing:

   01 234
  "ab\ncd"

I need to save this mapping information so when the external system
says "there's something interesting at characters [3,4]", I can map that
back to ProseMirror positions to do something useful: highlighting,
applying marks, or making selections.

fix: measure site visits
This commit is contained in:
nobody 2025-12-03 10:41:07 -08:00
commit 82bf67fc38
Signed by: GrocerPublishAgent
GPG key ID: D460CD54A9E3AB86
5 changed files with 539 additions and 10 deletions

View file

@ -40,10 +40,12 @@
"globals": "16.4.0",
"prettier": "3.6.2",
"tailwindcss": "^4.1.16",
"tsx": "^4.21.0",
"typescript": "5.4.5",
"typescript-eslint": "8.38.0",
"typescript-plugin-css-modules": "latest",
"undici": "*",
"uvu": "^0.5.6",
"vite": "7.1.11",
"vite-tsconfig-paths": "^4.2.1"
},

View file

@ -19,10 +19,11 @@ import * as math from "mathjs";
import exampleDoc from "~/assets/example-doc-1.txt?raw";
import { DebugPanel } from "~/components/debug-panel/debug-panel";
import { autoSolveParameters } from "~/utils/autosolver";
import { serializeDoc, mapRangeToPM } from "~/utils/pm-text-mapping";
import "~/global.css";
// API Configuration
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:5000';
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL || 'http://127.0.0.1:15000';
// Types
interface SalienceData {
@ -394,8 +395,9 @@ async function fetchSalienceData(
pendingRequest.value = controller;
syncState.value = "loading";
// Get current document text
const text = view.state.doc.textContent;
// Serialize document with position mapping
const doc = view.state.doc;
const { text, posMap } = serializeDoc(doc);
try {
const res = await fetch(`${API_BASE_URL}/salience?model=${encodeURIComponent(model)}`, {
@ -406,16 +408,27 @@ async function fetchSalienceData(
});
const data: SalienceData = await res.json();
// Check if document changed while request was in flight
if (view.state.doc !== doc) {
syncState.value = "dirty";
pendingRequest.value = null;
return;
}
salienceData.value = data;
adjacencyMatrix.value = data.adjacency;
// Set decorations with positions and zero salience
// The reactive task will compute and update the salience values
sentenceDecorations.value = data.intervals.map(([start, end]) => ({
from: start,
to: end,
salience: 0,
}));
sentenceDecorations.value = data.intervals.map(([start, end]) => {
const pmRange = mapRangeToPM(posMap, start, end);
return {
from: pmRange.from,
to: pmRange.to,
// Resetting salience to zero is part of the plan, there is a reactive
// task which will compute and update the salience values in place when
// the sentenceDecorations Signal is changed.
salience: 0,
};
});
syncState.value = "clean";
pendingRequest.value = null;

View file

@ -0,0 +1,104 @@
import { test } from "uvu";
import * as assert from "uvu/assert";
import { Schema } from "prosemirror-model";
import { schema as basicSchema } from "prosemirror-schema-basic";
import { serializeDoc, mapRangeToPM } from "./pm-text-mapping.js";
const schema = new Schema({
nodes: basicSchema.spec.nodes,
marks: basicSchema.spec.marks,
});
function createDoc(paragraphs: string[]) {
return schema.node(
"doc",
null,
paragraphs.map((text) =>
schema.node(
"paragraph",
null,
text.length > 0 ? [schema.text(text)] : []
)
)
);
}
function getTextSlice(doc: any, from: number, to: number): string {
return doc.textBetween(from, to);
}
// Test: random ranges round-trip correctly
test("random ranges map back to correct text", () => {
const doc = createDoc(["Hello world", "This is a test", "Third paragraph"]);
const { text, posMap } = serializeDoc(doc);
// text should be "Hello world\nThis is a test\nThird paragraph"
assert.is(text, "Hello world\nThis is a test\nThird paragraph");
// Try many random ranges
for (let i = 0; i < 100; i++) {
const from = Math.floor(Math.random() * text.length);
const to = from + 1 + Math.floor(Math.random() * (text.length - from));
const serializedSlice = text.slice(from, to);
const pmRange = mapRangeToPM(posMap, from, to);
const pmSlice = getTextSlice(doc, pmRange.from, pmRange.to);
// The slices should match, except newlines become empty (PM doesn't have newline chars)
const expected = serializedSlice.replace(/\n/g, "");
assert.is(pmSlice, expected, `Range [${from}, ${to}): "${serializedSlice}"`);
}
});
test("single paragraph", () => {
const doc = createDoc(["Just one paragraph"]);
const { text, posMap } = serializeDoc(doc);
assert.is(text, "Just one paragraph");
assert.is(posMap.length, text.length);
const pmRange = mapRangeToPM(posMap, 0, text.length);
assert.is(getTextSlice(doc, pmRange.from, pmRange.to), text);
});
test("empty paragraphs", () => {
const doc = createDoc(["First", "", "Third"]);
const { text, posMap } = serializeDoc(doc);
assert.is(text, "First\n\nThird");
// Range spanning the empty paragraph
const pmRange = mapRangeToPM(posMap, 0, text.length);
assert.is(getTextSlice(doc, pmRange.from, pmRange.to), "FirstThird");
});
test("range within single paragraph", () => {
const doc = createDoc(["Hello world", "Second para"]);
const { text, posMap } = serializeDoc(doc);
// Select "world" from first paragraph
const from = 6;
const to = 11;
assert.is(text.slice(from, to), "world");
const pmRange = mapRangeToPM(posMap, from, to);
assert.is(getTextSlice(doc, pmRange.from, pmRange.to), "world");
});
test("range spanning paragraph boundary", () => {
const doc = createDoc(["Hello", "World"]);
const { text, posMap } = serializeDoc(doc);
assert.is(text, "Hello\nWorld");
// Select "lo\nWor" (crossing the boundary)
const from = 3;
const to = 9;
assert.is(text.slice(from, to), "lo\nWor");
const pmRange = mapRangeToPM(posMap, from, to);
// PM textBetween won't include newline, so we get "loWor"
assert.is(getTextSlice(doc, pmRange.from, pmRange.to), "loWor");
});
test.run();

View file

@ -0,0 +1,61 @@
import { Node as PMNode } from "prosemirror-model";
/*
* ProseMirror positions are tree positions, not character offsets.
* A document with two paragraphs "ab" and "cd" has positions:
*
* 0 1 2 3 4 5 6 7 8
* <p> a b </p><p> c d </p>
*
* External tools (spell checkers, search, ML models) see plain text: "ab\ncd".
* They report findings as character ranges. To act on these findings
* in the editor, we must map back to ProseMirror positions.
*
* posMap[i] holds the PM position of character i in the serialized text.
* This is the only reliable way to roundtrip between the two worlds.
* There is no formula; the mapping depends on document structure.
*/
export interface SerializedDoc {
text: string;
// Maps each character index in `text` to its ProseMirror position
posMap: number[];
}
// Serialize document to plain text with newlines between paragraphs,
// building a position map as we go
export function serializeDoc(doc: PMNode): SerializedDoc {
const chars: string[] = [];
const posMap: number[] = [];
let isFirstParagraph = true;
doc.descendants((node, pos) => {
if (node.type.name === "paragraph") {
if (!isFirstParagraph) {
chars.push("\n");
posMap.push(pos); // newline maps to start of this paragraph
}
isFirstParagraph = false;
} else if (node.isText && node.text) {
for (let i = 0; i < node.text.length; i++) {
chars.push(node.text[i]);
posMap.push(pos + i);
}
}
return true;
});
return { text: chars.join(""), posMap };
}
// Convert a range from serialized text coordinates to ProseMirror positions
export function mapRangeToPM(
posMap: number[],
from: number,
to: number
): { from: number; to: number } {
return {
from: posMap[from],
to: posMap[to - 1] + 1, // to is exclusive
};
}

View file

@ -87,6 +87,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/aix-ppc64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/aix-ppc64@npm:0.27.0"
conditions: os=aix & cpu=ppc64
languageName: node
linkType: hard
"@esbuild/android-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/android-arm64@npm:0.25.12"
@ -94,6 +101,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/android-arm64@npm:0.27.0"
conditions: os=android & cpu=arm64
languageName: node
linkType: hard
"@esbuild/android-arm@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/android-arm@npm:0.25.12"
@ -101,6 +115,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-arm@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/android-arm@npm:0.27.0"
conditions: os=android & cpu=arm
languageName: node
linkType: hard
"@esbuild/android-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/android-x64@npm:0.25.12"
@ -108,6 +129,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/android-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/android-x64@npm:0.27.0"
conditions: os=android & cpu=x64
languageName: node
linkType: hard
"@esbuild/darwin-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/darwin-arm64@npm:0.25.12"
@ -115,6 +143,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/darwin-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/darwin-arm64@npm:0.27.0"
conditions: os=darwin & cpu=arm64
languageName: node
linkType: hard
"@esbuild/darwin-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/darwin-x64@npm:0.25.12"
@ -122,6 +157,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/darwin-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/darwin-x64@npm:0.27.0"
conditions: os=darwin & cpu=x64
languageName: node
linkType: hard
"@esbuild/freebsd-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/freebsd-arm64@npm:0.25.12"
@ -129,6 +171,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/freebsd-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/freebsd-arm64@npm:0.27.0"
conditions: os=freebsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/freebsd-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/freebsd-x64@npm:0.25.12"
@ -136,6 +185,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/freebsd-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/freebsd-x64@npm:0.27.0"
conditions: os=freebsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/linux-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-arm64@npm:0.25.12"
@ -143,6 +199,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-arm64@npm:0.27.0"
conditions: os=linux & cpu=arm64
languageName: node
linkType: hard
"@esbuild/linux-arm@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-arm@npm:0.25.12"
@ -150,6 +213,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-arm@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-arm@npm:0.27.0"
conditions: os=linux & cpu=arm
languageName: node
linkType: hard
"@esbuild/linux-ia32@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-ia32@npm:0.25.12"
@ -157,6 +227,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-ia32@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-ia32@npm:0.27.0"
conditions: os=linux & cpu=ia32
languageName: node
linkType: hard
"@esbuild/linux-loong64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-loong64@npm:0.25.12"
@ -164,6 +241,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-loong64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-loong64@npm:0.27.0"
conditions: os=linux & cpu=loong64
languageName: node
linkType: hard
"@esbuild/linux-mips64el@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-mips64el@npm:0.25.12"
@ -171,6 +255,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-mips64el@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-mips64el@npm:0.27.0"
conditions: os=linux & cpu=mips64el
languageName: node
linkType: hard
"@esbuild/linux-ppc64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-ppc64@npm:0.25.12"
@ -178,6 +269,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-ppc64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-ppc64@npm:0.27.0"
conditions: os=linux & cpu=ppc64
languageName: node
linkType: hard
"@esbuild/linux-riscv64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-riscv64@npm:0.25.12"
@ -185,6 +283,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-riscv64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-riscv64@npm:0.27.0"
conditions: os=linux & cpu=riscv64
languageName: node
linkType: hard
"@esbuild/linux-s390x@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-s390x@npm:0.25.12"
@ -192,6 +297,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-s390x@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-s390x@npm:0.27.0"
conditions: os=linux & cpu=s390x
languageName: node
linkType: hard
"@esbuild/linux-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/linux-x64@npm:0.25.12"
@ -199,6 +311,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/linux-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/linux-x64@npm:0.27.0"
conditions: os=linux & cpu=x64
languageName: node
linkType: hard
"@esbuild/netbsd-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/netbsd-arm64@npm:0.25.12"
@ -206,6 +325,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/netbsd-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/netbsd-arm64@npm:0.27.0"
conditions: os=netbsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/netbsd-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/netbsd-x64@npm:0.25.12"
@ -213,6 +339,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/netbsd-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/netbsd-x64@npm:0.27.0"
conditions: os=netbsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/openbsd-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/openbsd-arm64@npm:0.25.12"
@ -220,6 +353,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/openbsd-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/openbsd-arm64@npm:0.27.0"
conditions: os=openbsd & cpu=arm64
languageName: node
linkType: hard
"@esbuild/openbsd-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/openbsd-x64@npm:0.25.12"
@ -227,6 +367,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/openbsd-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/openbsd-x64@npm:0.27.0"
conditions: os=openbsd & cpu=x64
languageName: node
linkType: hard
"@esbuild/openharmony-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/openharmony-arm64@npm:0.25.12"
@ -234,6 +381,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/openharmony-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/openharmony-arm64@npm:0.27.0"
conditions: os=openharmony & cpu=arm64
languageName: node
linkType: hard
"@esbuild/sunos-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/sunos-x64@npm:0.25.12"
@ -241,6 +395,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/sunos-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/sunos-x64@npm:0.27.0"
conditions: os=sunos & cpu=x64
languageName: node
linkType: hard
"@esbuild/win32-arm64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/win32-arm64@npm:0.25.12"
@ -248,6 +409,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/win32-arm64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/win32-arm64@npm:0.27.0"
conditions: os=win32 & cpu=arm64
languageName: node
linkType: hard
"@esbuild/win32-ia32@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/win32-ia32@npm:0.25.12"
@ -255,6 +423,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/win32-ia32@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/win32-ia32@npm:0.27.0"
conditions: os=win32 & cpu=ia32
languageName: node
linkType: hard
"@esbuild/win32-x64@npm:0.25.12":
version: 0.25.12
resolution: "@esbuild/win32-x64@npm:0.25.12"
@ -262,6 +437,13 @@ __metadata:
languageName: node
linkType: hard
"@esbuild/win32-x64@npm:0.27.0":
version: 0.27.0
resolution: "@esbuild/win32-x64@npm:0.27.0"
conditions: os=win32 & cpu=x64
languageName: node
linkType: hard
"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.7.0":
version: 4.9.0
resolution: "@eslint-community/eslint-utils@npm:4.9.0"
@ -2447,6 +2629,13 @@ __metadata:
languageName: node
linkType: hard
"diff@npm:^5.0.0":
version: 5.2.0
resolution: "diff@npm:5.2.0"
checksum: 10c0/aed0941f206fe261ecb258dc8d0ceea8abbde3ace5827518ff8d302f0fc9cc81ce116c4d8f379151171336caf0516b79e01abdc1ed1201b6440d895a66689eb4
languageName: node
linkType: hard
"dom-serializer@npm:^2.0.0":
version: 2.0.0
resolution: "dom-serializer@npm:2.0.0"
@ -2805,6 +2994,95 @@ __metadata:
languageName: node
linkType: hard
"esbuild@npm:~0.27.0":
version: 0.27.0
resolution: "esbuild@npm:0.27.0"
dependencies:
"@esbuild/aix-ppc64": "npm:0.27.0"
"@esbuild/android-arm": "npm:0.27.0"
"@esbuild/android-arm64": "npm:0.27.0"
"@esbuild/android-x64": "npm:0.27.0"
"@esbuild/darwin-arm64": "npm:0.27.0"
"@esbuild/darwin-x64": "npm:0.27.0"
"@esbuild/freebsd-arm64": "npm:0.27.0"
"@esbuild/freebsd-x64": "npm:0.27.0"
"@esbuild/linux-arm": "npm:0.27.0"
"@esbuild/linux-arm64": "npm:0.27.0"
"@esbuild/linux-ia32": "npm:0.27.0"
"@esbuild/linux-loong64": "npm:0.27.0"
"@esbuild/linux-mips64el": "npm:0.27.0"
"@esbuild/linux-ppc64": "npm:0.27.0"
"@esbuild/linux-riscv64": "npm:0.27.0"
"@esbuild/linux-s390x": "npm:0.27.0"
"@esbuild/linux-x64": "npm:0.27.0"
"@esbuild/netbsd-arm64": "npm:0.27.0"
"@esbuild/netbsd-x64": "npm:0.27.0"
"@esbuild/openbsd-arm64": "npm:0.27.0"
"@esbuild/openbsd-x64": "npm:0.27.0"
"@esbuild/openharmony-arm64": "npm:0.27.0"
"@esbuild/sunos-x64": "npm:0.27.0"
"@esbuild/win32-arm64": "npm:0.27.0"
"@esbuild/win32-ia32": "npm:0.27.0"
"@esbuild/win32-x64": "npm:0.27.0"
dependenciesMeta:
"@esbuild/aix-ppc64":
optional: true
"@esbuild/android-arm":
optional: true
"@esbuild/android-arm64":
optional: true
"@esbuild/android-x64":
optional: true
"@esbuild/darwin-arm64":
optional: true
"@esbuild/darwin-x64":
optional: true
"@esbuild/freebsd-arm64":
optional: true
"@esbuild/freebsd-x64":
optional: true
"@esbuild/linux-arm":
optional: true
"@esbuild/linux-arm64":
optional: true
"@esbuild/linux-ia32":
optional: true
"@esbuild/linux-loong64":
optional: true
"@esbuild/linux-mips64el":
optional: true
"@esbuild/linux-ppc64":
optional: true
"@esbuild/linux-riscv64":
optional: true
"@esbuild/linux-s390x":
optional: true
"@esbuild/linux-x64":
optional: true
"@esbuild/netbsd-arm64":
optional: true
"@esbuild/netbsd-x64":
optional: true
"@esbuild/openbsd-arm64":
optional: true
"@esbuild/openbsd-x64":
optional: true
"@esbuild/openharmony-arm64":
optional: true
"@esbuild/sunos-x64":
optional: true
"@esbuild/win32-arm64":
optional: true
"@esbuild/win32-ia32":
optional: true
"@esbuild/win32-x64":
optional: true
bin:
esbuild: bin/esbuild
checksum: 10c0/a3a1deec285337b7dfe25cbb9aa8765d27a0192b610a8477a39bf5bd907a6bdb75e98898b61fb4337114cfadb13163bd95977db14e241373115f548e235b40a2
languageName: node
linkType: hard
"escape-html@npm:~1.0.3":
version: 1.0.3
resolution: "escape-html@npm:1.0.3"
@ -3347,6 +3625,15 @@ __metadata:
languageName: node
linkType: hard
"get-tsconfig@npm:^4.7.5":
version: 4.13.0
resolution: "get-tsconfig@npm:4.13.0"
dependencies:
resolve-pkg-maps: "npm:^1.0.0"
checksum: 10c0/2c49ef8d3907047a107f229fd610386fe3b7fe9e42dfd6b42e7406499493cdda8c62e83e57e8d7a98125610774b9f604d3a0ff308d7f9de5c7ac6d1b07cb6036
languageName: node
linkType: hard
"glob-parent@npm:^5.1.2":
version: 5.1.2
resolution: "glob-parent@npm:5.1.2"
@ -4093,6 +4380,13 @@ __metadata:
languageName: node
linkType: hard
"kleur@npm:^4.0.3":
version: 4.1.5
resolution: "kleur@npm:4.1.5"
checksum: 10c0/e9de6cb49657b6fa70ba2d1448fd3d691a5c4370d8f7bbf1c2f64c24d461270f2117e1b0afe8cb3114f13bbd8e51de158c2a224953960331904e636a5e4c0f2a
languageName: node
linkType: hard
"launch-editor@npm:^2.11.1":
version: 2.12.0
resolution: "launch-editor@npm:2.12.0"
@ -5055,6 +5349,13 @@ __metadata:
languageName: node
linkType: hard
"mri@npm:^1.1.0":
version: 1.2.0
resolution: "mri@npm:1.2.0"
checksum: 10c0/a3d32379c2554cf7351db6237ddc18dc9e54e4214953f3da105b97dc3babe0deb3ffe99cf409b38ea47cc29f9430561ba6b53b24ab8f9ce97a4b50409e4a50e7
languageName: node
linkType: hard
"ms@npm:2.0.0":
version: 2.0.0
resolution: "ms@npm:2.0.0"
@ -5098,10 +5399,12 @@ __metadata:
prosemirror-view: "npm:^1.41.3"
tailwindcss: "npm:^4.1.16"
temml: "npm:^0.11.11"
tsx: "npm:^4.21.0"
typescript: "npm:5.4.5"
typescript-eslint: "npm:8.38.0"
typescript-plugin-css-modules: "npm:latest"
undici: "npm:*"
uvu: "npm:^0.5.6"
vite: "npm:7.1.11"
vite-tsconfig-paths: "npm:^4.2.1"
languageName: unknown
@ -5852,6 +6155,13 @@ __metadata:
languageName: node
linkType: hard
"resolve-pkg-maps@npm:^1.0.0":
version: 1.0.0
resolution: "resolve-pkg-maps@npm:1.0.0"
checksum: 10c0/fb8f7bbe2ca281a73b7ef423a1cbc786fb244bd7a95cbe5c3fba25b27d327150beca8ba02f622baea65919a57e061eb5005204daa5f93ed590d9b77463a567ab
languageName: node
linkType: hard
"retry@npm:^0.12.0":
version: 0.12.0
resolution: "retry@npm:0.12.0"
@ -5956,6 +6266,15 @@ __metadata:
languageName: node
linkType: hard
"sade@npm:^1.7.3":
version: 1.8.1
resolution: "sade@npm:1.8.1"
dependencies:
mri: "npm:^1.1.0"
checksum: 10c0/da8a3a5d667ad5ce3bf6d4f054bbb9f711103e5df21003c5a5c1a8a77ce12b640ed4017dd423b13c2307ea7e645adee7c2ae3afe8051b9db16a6f6d3da3f90b1
languageName: node
linkType: hard
"safe-array-concat@npm:^1.1.3":
version: 1.1.3
resolution: "safe-array-concat@npm:1.1.3"
@ -6638,6 +6957,22 @@ __metadata:
languageName: node
linkType: hard
"tsx@npm:^4.21.0":
version: 4.21.0
resolution: "tsx@npm:4.21.0"
dependencies:
esbuild: "npm:~0.27.0"
fsevents: "npm:~2.3.3"
get-tsconfig: "npm:^4.7.5"
dependenciesMeta:
fsevents:
optional: true
bin:
tsx: dist/cli.mjs
checksum: 10c0/f5072923cd8459a1f9a26df87823a2ab5754641739d69df2a20b415f61814322b751fa6be85db7c6ec73cf68ba8fac2fd1cfc76bdb0aa86ded984d84d5d2126b
languageName: node
linkType: hard
"type-check@npm:^0.4.0, type-check@npm:~0.4.0":
version: 0.4.0
resolution: "type-check@npm:0.4.0"
@ -6934,6 +7269,20 @@ __metadata:
languageName: node
linkType: hard
"uvu@npm:^0.5.6":
version: 0.5.6
resolution: "uvu@npm:0.5.6"
dependencies:
dequal: "npm:^2.0.0"
diff: "npm:^5.0.0"
kleur: "npm:^4.0.3"
sade: "npm:^1.7.3"
bin:
uvu: bin.js
checksum: 10c0/ad32eb5f7d94bdeb71f80d073003f0138e24f61ed68cecc8e15d2f30838f44c9670577bb1775c8fac894bf93d1bc1583d470a9195e49bfa6efa14cc6f4942bff
languageName: node
linkType: hard
"valibot@npm:>=0.36.0 <2":
version: 1.2.0
resolution: "valibot@npm:1.2.0"