@silverbulletmd/silverbullet 2.7.0 → 2.8.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/README.md +0 -2
- package/client/plugos/syscalls/client_code_widget.ts +3 -1
- package/client/plugos/syscalls/editor.ts +17 -12
- package/client/plugos/syscalls/index.ts +47 -1
- package/dist/plug-compile.js +1 -1
- package/package.json +1 -1
- package/plug-api/syscalls/editor.ts +5 -0
- package/plug-api/syscalls/index.ts +101 -1
- package/plug-api/types/client.ts +12 -0
package/README.md
CHANGED
|
@@ -27,8 +27,6 @@ SilverBullet's frontend is written in [TypeScript](https://www.typescriptlang.or
|
|
|
27
27
|
|
|
28
28
|
The server backend is written in Go.
|
|
29
29
|
|
|
30
|
-
If you're considering contributing changes, be aware of the [LLM use policy](https://silverbullet.md/LLM%20Use).
|
|
31
|
-
|
|
32
30
|
## Code structure
|
|
33
31
|
* `client/`: The SilverBullet client, implemented with TypeScript
|
|
34
32
|
* `server/`: The SilverBullet server, written in Go
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import type { SysCallMapping } from "../../plugos/system.ts";
|
|
2
|
+
import type { Client } from "../../client.ts";
|
|
2
3
|
import { reloadAllWidgets } from "../../codemirror/code_widget.ts";
|
|
3
4
|
import { broadcastReload } from "../../components/widget_sandbox_iframe.ts";
|
|
4
5
|
|
|
5
|
-
export function clientCodeWidgetSyscalls(): SysCallMapping {
|
|
6
|
+
export function clientCodeWidgetSyscalls(client: Client): SysCallMapping {
|
|
6
7
|
return {
|
|
7
8
|
"codeWidget.refreshAll": () => {
|
|
9
|
+
client.widgetCache.clearPrewarm();
|
|
8
10
|
broadcastReload();
|
|
9
11
|
return reloadAllWidgets();
|
|
10
12
|
},
|
|
@@ -71,6 +71,8 @@ import type {
|
|
|
71
71
|
UploadFile,
|
|
72
72
|
} from "@silverbulletmd/silverbullet/type/client";
|
|
73
73
|
import { openSearchPanel } from "@codemirror/search";
|
|
74
|
+
import { forceLinting } from "@codemirror/lint";
|
|
75
|
+
import { refreshLintEffect } from "../../codemirror/lint.ts";
|
|
74
76
|
import {
|
|
75
77
|
isValidPath,
|
|
76
78
|
parseToRef,
|
|
@@ -249,6 +251,15 @@ export function editorSyscalls(client: Client): SysCallMapping {
|
|
|
249
251
|
"editor.reloadPage": async () => {
|
|
250
252
|
await client.reloadEditor();
|
|
251
253
|
},
|
|
254
|
+
"editor.forceLint": () => {
|
|
255
|
+
// `forceLinting` alone is a no-op on unchanged content after the
|
|
256
|
+
// linter's internal "scheduled" flag has been cleared; the effect
|
|
257
|
+
// re-arms it via `needsRefresh`.
|
|
258
|
+
client.editorView.dispatch({
|
|
259
|
+
effects: refreshLintEffect.of(null),
|
|
260
|
+
});
|
|
261
|
+
forceLinting(client.editorView);
|
|
262
|
+
},
|
|
252
263
|
"editor.reloadUI": () => {
|
|
253
264
|
location.reload();
|
|
254
265
|
},
|
|
@@ -453,20 +464,14 @@ export function editorSyscalls(client: Client): SysCallMapping {
|
|
|
453
464
|
}
|
|
454
465
|
},
|
|
455
466
|
"editor.moveCursor": (_ctx, pos: number, center = false) => {
|
|
467
|
+
// Always scroll into view so callers don't strand the cursor
|
|
468
|
+
// off-screen; `nearest` (default) is a no-op when already visible.
|
|
456
469
|
client.editorView.dispatch({
|
|
457
|
-
selection: {
|
|
458
|
-
|
|
459
|
-
|
|
470
|
+
selection: { anchor: pos },
|
|
471
|
+
effects: [
|
|
472
|
+
EditorView.scrollIntoView(pos, center ? { y: "center" } : {}),
|
|
473
|
+
],
|
|
460
474
|
});
|
|
461
|
-
if (center) {
|
|
462
|
-
client.editorView.dispatch({
|
|
463
|
-
effects: [
|
|
464
|
-
EditorView.scrollIntoView(pos, {
|
|
465
|
-
y: "center",
|
|
466
|
-
}),
|
|
467
|
-
],
|
|
468
|
-
});
|
|
469
|
-
}
|
|
470
475
|
client.editorView.focus();
|
|
471
476
|
},
|
|
472
477
|
"editor.moveCursorToLine": (
|
|
@@ -17,8 +17,25 @@ export function indexSyscalls(
|
|
|
17
17
|
client: Client,
|
|
18
18
|
): SysCallMapping {
|
|
19
19
|
return {
|
|
20
|
+
// Query collection API
|
|
20
21
|
"index.tag": (_ctx, tagName: string): LuaQueryCollection => {
|
|
21
|
-
return objectIndex.
|
|
22
|
+
return objectIndex.objectsWithTag(tagName);
|
|
23
|
+
},
|
|
24
|
+
// Alias for tag
|
|
25
|
+
"index.objects": (_ctx, tagName: string): LuaQueryCollection => {
|
|
26
|
+
return objectIndex.objectsWithTag(tagName);
|
|
27
|
+
},
|
|
28
|
+
"index.pages": (_ctx, tagName?: string): LuaQueryCollection => {
|
|
29
|
+
return objectIndex.rootTaggedObjects("page", tagName);
|
|
30
|
+
},
|
|
31
|
+
"index.subPages": (_ctx, pageName: string): LuaQueryCollection => {
|
|
32
|
+
return objectIndex.subPages(pageName);
|
|
33
|
+
},
|
|
34
|
+
"index.documents": (): LuaQueryCollection => {
|
|
35
|
+
return objectIndex.objectsWithTag("document");
|
|
36
|
+
},
|
|
37
|
+
"index.links": (): LuaQueryCollection => {
|
|
38
|
+
return objectIndex.objectsWithTag("link");
|
|
22
39
|
},
|
|
23
40
|
"index.contentPages": (): LuaQueryCollection => {
|
|
24
41
|
return objectIndex.contentPages();
|
|
@@ -26,6 +43,28 @@ export function indexSyscalls(
|
|
|
26
43
|
"index.metaPages": (): LuaQueryCollection => {
|
|
27
44
|
return objectIndex.metaPages();
|
|
28
45
|
},
|
|
46
|
+
"index.tasks": (_ctx, tagName?: string): LuaQueryCollection => {
|
|
47
|
+
return objectIndex.rootTaggedObjects("task", tagName);
|
|
48
|
+
},
|
|
49
|
+
"index.headers": (_ctx, tagName?: string): LuaQueryCollection => {
|
|
50
|
+
return objectIndex.rootTaggedObjects("header", tagName);
|
|
51
|
+
},
|
|
52
|
+
"index.items": (_ctx, tagName?: string): LuaQueryCollection => {
|
|
53
|
+
return objectIndex.rootTaggedObjects("item", tagName);
|
|
54
|
+
},
|
|
55
|
+
"index.paragraphs": (_ctx, tagName?: string): LuaQueryCollection => {
|
|
56
|
+
return objectIndex.rootTaggedObjects("paragraph", tagName);
|
|
57
|
+
},
|
|
58
|
+
"index.tables": (_ctx, tagName?: string): LuaQueryCollection => {
|
|
59
|
+
return objectIndex.rootTaggedObjects("table", tagName);
|
|
60
|
+
},
|
|
61
|
+
"index.tags": (): LuaQueryCollection => {
|
|
62
|
+
return objectIndex.objectsWithTag("tag");
|
|
63
|
+
},
|
|
64
|
+
"index.aspiringPages": (): LuaQueryCollection => {
|
|
65
|
+
return objectIndex.aspiringPages();
|
|
66
|
+
},
|
|
67
|
+
// Internals
|
|
29
68
|
"index.aggregates": (): LuaQueryCollection => {
|
|
30
69
|
return objectIndex.aggregates();
|
|
31
70
|
},
|
|
@@ -61,6 +100,13 @@ export function indexSyscalls(
|
|
|
61
100
|
}
|
|
62
101
|
}
|
|
63
102
|
},
|
|
103
|
+
"index.previewProcessedObjects": (
|
|
104
|
+
_ctx,
|
|
105
|
+
page: string,
|
|
106
|
+
objects: ObjectValue[],
|
|
107
|
+
): Promise<{ tag: string; object: ObjectValue }[]> => {
|
|
108
|
+
return objectIndex.previewProcessedObjects(page, objects);
|
|
109
|
+
},
|
|
64
110
|
"index.getObjectByRef": (
|
|
65
111
|
_ctx,
|
|
66
112
|
page: string,
|
package/dist/plug-compile.js
CHANGED
package/package.json
CHANGED
|
@@ -153,6 +153,11 @@ export function reloadPage(): Promise<void> {
|
|
|
153
153
|
return syscall("editor.reloadPage");
|
|
154
154
|
}
|
|
155
155
|
|
|
156
|
+
/** Useful when a plug toggles a piece of state that lint subscribers consult. */
|
|
157
|
+
export function forceLint(): Promise<void> {
|
|
158
|
+
return syscall("editor.forceLint");
|
|
159
|
+
}
|
|
160
|
+
|
|
156
161
|
/**
|
|
157
162
|
* Force reloads the browser UI
|
|
158
163
|
*/
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
LuaCollectionQuery,
|
|
3
|
+
LuaQueryCollection,
|
|
4
|
+
} from "../../client/space_lua/query_collection.ts";
|
|
2
5
|
import { syscall } from "@silverbulletmd/silverbullet/syscall";
|
|
3
6
|
import type { ObjectValue } from "../../plug-api/types/index.ts";
|
|
4
7
|
|
|
@@ -27,6 +30,103 @@ export function validateObjects<T>(
|
|
|
27
30
|
return syscall("index.validateObjects", page, objects);
|
|
28
31
|
}
|
|
29
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Run the full indexing pipeline (validation, multi-tag expansion,
|
|
35
|
+
* tag transforms) and return the resulting objects each paired with
|
|
36
|
+
* the tag they're indexed under. Read-only — no DB writes.
|
|
37
|
+
*/
|
|
38
|
+
export function previewProcessedObjects(
|
|
39
|
+
page: string,
|
|
40
|
+
objects: ObjectValue[],
|
|
41
|
+
): Promise<{ tag: string; object: ObjectValue }[]> {
|
|
42
|
+
return syscall("index.previewProcessedObjects", page, objects);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Returns objects carrying the given tag as a query collection.
|
|
47
|
+
*/
|
|
48
|
+
export function objects(tagName: string): Promise<LuaQueryCollection> {
|
|
49
|
+
return syscall("index.objects", tagName);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Returns all pages (optionally filtered by an additional tag) as a query collection.
|
|
54
|
+
*/
|
|
55
|
+
export function pages(tagName?: string): Promise<LuaQueryCollection> {
|
|
56
|
+
return syscall("index.pages", tagName);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Returns all sub-pages of the given page (pages whose name starts with `<pageName>/`)
|
|
61
|
+
* as a query collection.
|
|
62
|
+
*/
|
|
63
|
+
export function subPages(pageName: string): Promise<LuaQueryCollection> {
|
|
64
|
+
return syscall("index.subPages", pageName);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Returns all documents as a query collection.
|
|
69
|
+
*/
|
|
70
|
+
export function documents(): Promise<LuaQueryCollection> {
|
|
71
|
+
return syscall("index.documents");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Returns all links as a query collection.
|
|
76
|
+
*/
|
|
77
|
+
export function links(): Promise<LuaQueryCollection> {
|
|
78
|
+
return syscall("index.links");
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Returns all tasks (optionally filtered by an additional tag) as a query collection.
|
|
83
|
+
*/
|
|
84
|
+
export function tasks(tagName?: string): Promise<LuaQueryCollection> {
|
|
85
|
+
return syscall("index.tasks", tagName);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Returns all headers (optionally filtered by an additional tag) as a query collection.
|
|
90
|
+
*/
|
|
91
|
+
export function headers(tagName?: string): Promise<LuaQueryCollection> {
|
|
92
|
+
return syscall("index.headers", tagName);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Returns all list items (optionally filtered by an additional tag) as a query collection.
|
|
97
|
+
*/
|
|
98
|
+
export function items(tagName?: string): Promise<LuaQueryCollection> {
|
|
99
|
+
return syscall("index.items", tagName);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Returns all paragraphs (optionally filtered by an additional tag) as a query collection.
|
|
104
|
+
*/
|
|
105
|
+
export function paragraphs(tagName?: string): Promise<LuaQueryCollection> {
|
|
106
|
+
return syscall("index.paragraphs", tagName);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* Returns all tables (optionally filtered by an additional tag) as a query collection.
|
|
111
|
+
*/
|
|
112
|
+
export function tables(tagName?: string): Promise<LuaQueryCollection> {
|
|
113
|
+
return syscall("index.tables", tagName);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Returns all aspiring (referenced but not yet created) pages as a query collection.
|
|
118
|
+
*/
|
|
119
|
+
export function aspiringPages(): Promise<LuaQueryCollection> {
|
|
120
|
+
return syscall("index.aspiringPages");
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* Returns all tag objects as a query collection.
|
|
125
|
+
*/
|
|
126
|
+
export function tags(): Promise<LuaQueryCollection> {
|
|
127
|
+
return syscall("index.tags");
|
|
128
|
+
}
|
|
129
|
+
|
|
30
130
|
/**
|
|
31
131
|
* Queries objects using a Lua-based collection query
|
|
32
132
|
* @param tag - The tag to filter objects by
|
package/plug-api/types/client.ts
CHANGED
|
@@ -54,6 +54,18 @@ export type LintDiagnostic = {
|
|
|
54
54
|
to: number;
|
|
55
55
|
severity: "error" | "warning" | "info" | "hint";
|
|
56
56
|
message: string;
|
|
57
|
+
/**
|
|
58
|
+
* Optional HTML rendered into the hover tooltip for this diagnostic.
|
|
59
|
+
* When present, takes precedence over `message` for tooltip display.
|
|
60
|
+
* `message` is still used as a plain-text fallback (e.g. in the lint
|
|
61
|
+
* panel) and as the diagnostic's accessible label.
|
|
62
|
+
*/
|
|
63
|
+
messageHtml?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Optional CSS class added to the inline range mark for this diagnostic,
|
|
66
|
+
* in addition to CodeMirror's default `.cm-lintRange-<severity>` class.
|
|
67
|
+
*/
|
|
68
|
+
markClass?: string;
|
|
57
69
|
};
|
|
58
70
|
|
|
59
71
|
export type UploadFile = {
|