@backmatter/core 0.0.32 → 0.0.33
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 +1 -1
- package/src/preview-channel.ts +44 -3
package/package.json
CHANGED
package/src/preview-channel.ts
CHANGED
|
@@ -59,11 +59,17 @@ export type PreviewPointMessage = Envelope & {
|
|
|
59
59
|
|
|
60
60
|
export type PreviewGrabMessage = Envelope & {
|
|
61
61
|
type: "backmatter:grab";
|
|
62
|
-
|
|
62
|
+
/** Null when the click is not inside a page block. */
|
|
63
|
+
blockId: string | null;
|
|
63
64
|
blockType: string | null;
|
|
64
65
|
blockIndex: number | null;
|
|
65
66
|
quote: string;
|
|
66
67
|
shift: boolean;
|
|
68
|
+
component?: string;
|
|
69
|
+
file?: string;
|
|
70
|
+
line?: number;
|
|
71
|
+
column?: number;
|
|
72
|
+
stack?: string[];
|
|
67
73
|
};
|
|
68
74
|
|
|
69
75
|
export type PreviewHighlightMessage = Envelope & {
|
|
@@ -119,6 +125,37 @@ function readEnvelope(value: Record<string, unknown>): Envelope | null {
|
|
|
119
125
|
return { v: PREVIEW_CHANNEL_VERSION, ref };
|
|
120
126
|
}
|
|
121
127
|
|
|
128
|
+
const GRAB_FILE = /^[\w./@+-]+\.(?:tsx|ts|jsx|js|mdx)$/;
|
|
129
|
+
|
|
130
|
+
function readGrabPlace(data: Record<string, unknown>): Pick<
|
|
131
|
+
PreviewGrabMessage,
|
|
132
|
+
"component" | "file" | "line" | "column" | "stack"
|
|
133
|
+
> {
|
|
134
|
+
const component =
|
|
135
|
+
typeof data.component === "string" && data.component.length > 0 && data.component.length <= 80
|
|
136
|
+
? data.component
|
|
137
|
+
: undefined;
|
|
138
|
+
const file =
|
|
139
|
+
typeof data.file === "string" && data.file.length <= 240 && GRAB_FILE.test(data.file) && !data.file.includes("..")
|
|
140
|
+
? data.file
|
|
141
|
+
: undefined;
|
|
142
|
+
const line = typeof data.line === "number" && Number.isInteger(data.line) && data.line > 0 ? data.line : undefined;
|
|
143
|
+
const column =
|
|
144
|
+
typeof data.column === "number" && Number.isInteger(data.column) && data.column > 0 ? data.column : undefined;
|
|
145
|
+
const stack = Array.isArray(data.stack)
|
|
146
|
+
? data.stack
|
|
147
|
+
.filter((item): item is string => typeof item === "string" && item.length > 0 && item.length <= 80)
|
|
148
|
+
.slice(0, 4)
|
|
149
|
+
: [];
|
|
150
|
+
return {
|
|
151
|
+
...(component ? { component } : {}),
|
|
152
|
+
...(file ? { file } : {}),
|
|
153
|
+
...(line ? { line } : {}),
|
|
154
|
+
...(column ? { column } : {}),
|
|
155
|
+
...(stack.length > 0 ? { stack } : {}),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
|
|
122
159
|
/** Parse a channel payload. Legacy hotkey messages (no `v`) still parse. */
|
|
123
160
|
export function parsePreviewMessage(data: unknown): PreviewChannelMessage | null {
|
|
124
161
|
const hotkey = parsePreviewHotkey(data);
|
|
@@ -167,7 +204,8 @@ export function parsePreviewMessage(data: unknown): PreviewChannelMessage | null
|
|
|
167
204
|
return { type: "backmatter:point", ...envelope, on: data.on };
|
|
168
205
|
}
|
|
169
206
|
case "backmatter:grab": {
|
|
170
|
-
|
|
207
|
+
const blockId = data.blockId === null ? null : typeof data.blockId === "string" ? data.blockId : undefined;
|
|
208
|
+
if (blockId === undefined || blockId === "") return null;
|
|
171
209
|
if (data.blockType !== null && typeof data.blockType !== "string") return null;
|
|
172
210
|
if (
|
|
173
211
|
data.blockIndex !== null &&
|
|
@@ -176,14 +214,17 @@ export function parsePreviewMessage(data: unknown): PreviewChannelMessage | null
|
|
|
176
214
|
return null;
|
|
177
215
|
}
|
|
178
216
|
if (typeof data.quote !== "string" || typeof data.shift !== "boolean") return null;
|
|
217
|
+
const place = readGrabPlace(data);
|
|
218
|
+
if (blockId === null && !normalizePointerQuote(data.quote) && !place.component && !place.file) return null;
|
|
179
219
|
return {
|
|
180
220
|
type: "backmatter:grab",
|
|
181
221
|
...envelope,
|
|
182
|
-
blockId
|
|
222
|
+
blockId,
|
|
183
223
|
blockType: data.blockType,
|
|
184
224
|
blockIndex: data.blockIndex,
|
|
185
225
|
quote: normalizePointerQuote(data.quote),
|
|
186
226
|
shift: data.shift,
|
|
227
|
+
...place,
|
|
187
228
|
};
|
|
188
229
|
}
|
|
189
230
|
case "backmatter:highlight": {
|