@riebeckite/plugin-local-graph 0.0.23 → 0.0.25
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/dist/components/local-graph.d.ts +2 -2
- package/dist/components/local-graph.js +48 -9
- package/dist/index.js +92 -85
- package/package.json +4 -3
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { LocalGraphData } from "../src/local-graph.js";
|
|
2
2
|
export type LocalGraphProps = {
|
|
3
|
-
graph
|
|
3
|
+
graph?: LocalGraphData | null;
|
|
4
4
|
};
|
|
5
|
-
declare const LocalGraph: (props: Readonly<LocalGraphProps>) => import("hono/
|
|
5
|
+
declare const LocalGraph: (props: Readonly<LocalGraphProps>) => Promise<import("hono/utils/html").HtmlEscapedString>;
|
|
6
6
|
export default LocalGraph;
|
|
@@ -1,15 +1,54 @@
|
|
|
1
1
|
// components/local-graph.tsx
|
|
2
2
|
import { buildGraphEdges, layoutRadialGraph } from "@riebeckite/core";
|
|
3
|
+
import { useArticleContext, useSiteContext } from "@riebeckite/ui";
|
|
4
|
+
import { html } from "hono/html";
|
|
5
|
+
|
|
6
|
+
// src/local-graph.server.ts
|
|
7
|
+
var MAX_NEIGHBORS_PER_DIRECTION = 10;
|
|
8
|
+
var getLocalGraph = ({ view, slug }) => {
|
|
9
|
+
const current = view.findDiscoverableBySlug(slug);
|
|
10
|
+
if (!current) return null;
|
|
11
|
+
const outgoing = view.getDiscoverableOutgoing(slug).slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
12
|
+
const incoming = view.getDiscoverableIncoming(slug).slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
13
|
+
const outgoingSlugs = outgoing.map((entry) => entry.slug);
|
|
14
|
+
const incomingSlugs = incoming.map((entry) => entry.slug);
|
|
15
|
+
const entries = [current, ...outgoing, ...incoming].filter(
|
|
16
|
+
(entry, index, all) => all.findIndex((candidate) => candidate.slug === entry.slug) === index
|
|
17
|
+
);
|
|
18
|
+
return {
|
|
19
|
+
currentSlug: slug,
|
|
20
|
+
nodes: entries.map((entry) => ({
|
|
21
|
+
slug: entry.slug,
|
|
22
|
+
permalink: entry.permalink,
|
|
23
|
+
title: entry.title || entry.slug,
|
|
24
|
+
relation: getRelation(entry.slug, slug, outgoingSlugs, incomingSlugs),
|
|
25
|
+
outgoing: entry.slug === slug ? outgoingSlugs : incomingSlugs.includes(entry.slug) ? [slug] : [],
|
|
26
|
+
backlinks: entry.slug === slug ? incomingSlugs : outgoingSlugs.includes(entry.slug) ? [slug] : []
|
|
27
|
+
}))
|
|
28
|
+
};
|
|
29
|
+
};
|
|
30
|
+
function getRelation(slug, currentSlug, outgoing, backlinks) {
|
|
31
|
+
if (slug === currentSlug) return "current";
|
|
32
|
+
const isOutgoing = outgoing.includes(slug);
|
|
33
|
+
const isBacklink = backlinks.includes(slug);
|
|
34
|
+
if (isOutgoing && isBacklink) return "both";
|
|
35
|
+
return isOutgoing ? "outgoing" : "backlink";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// components/local-graph.tsx
|
|
3
39
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
4
40
|
var GRAPH_WIDTH = 640;
|
|
5
41
|
var GRAPH_HEIGHT = 320;
|
|
6
|
-
var LocalGraph = ((props) => {
|
|
7
|
-
|
|
8
|
-
const
|
|
9
|
-
const
|
|
42
|
+
var LocalGraph = (async (props) => {
|
|
43
|
+
const site = useSiteContext();
|
|
44
|
+
const article = useArticleContext();
|
|
45
|
+
const graph = props.graph ?? (site && article?.entry ? await getLocalGraph({ view: site.view, slug: article.entry.slug }) : null);
|
|
46
|
+
if (!graph || graph.nodes.length <= 1) return html``;
|
|
47
|
+
const edges = buildGraphEdges(graph.nodes);
|
|
48
|
+
const layout = layoutRadialGraph(graph.nodes, {
|
|
10
49
|
width: GRAPH_WIDTH,
|
|
11
50
|
height: GRAPH_HEIGHT,
|
|
12
|
-
centerSlug:
|
|
51
|
+
centerSlug: graph.currentSlug,
|
|
13
52
|
radiusRatio: 0.34,
|
|
14
53
|
minNodeRadius: 7,
|
|
15
54
|
maxNodeRadius: 12
|
|
@@ -24,7 +63,7 @@ var LocalGraph = ((props) => {
|
|
|
24
63
|
"a",
|
|
25
64
|
{
|
|
26
65
|
class: "rr-local-graph__explorer-link",
|
|
27
|
-
href: `/explore?note=${encodeURIComponent(
|
|
66
|
+
href: `/explore?note=${encodeURIComponent(graph.currentSlug)}`,
|
|
28
67
|
children: "Open in Explorer →"
|
|
29
68
|
}
|
|
30
69
|
)
|
|
@@ -45,7 +84,7 @@ var LocalGraph = ((props) => {
|
|
|
45
84
|
"line",
|
|
46
85
|
{
|
|
47
86
|
class: "rr-local-graph__edge",
|
|
48
|
-
"data-direction": edge.source ===
|
|
87
|
+
"data-direction": edge.source === graph.currentSlug ? "outgoing" : "backlink",
|
|
49
88
|
x1: source.x,
|
|
50
89
|
y1: source.y,
|
|
51
90
|
x2: target.x,
|
|
@@ -54,10 +93,10 @@ var LocalGraph = ((props) => {
|
|
|
54
93
|
`${edge.source}-${edge.target}`
|
|
55
94
|
);
|
|
56
95
|
}),
|
|
57
|
-
|
|
96
|
+
graph.nodes.map((node) => {
|
|
58
97
|
const point = layout.get(node.slug);
|
|
59
98
|
if (!point) return null;
|
|
60
|
-
const isCurrent = node.slug ===
|
|
99
|
+
const isCurrent = node.slug === graph.currentSlug;
|
|
61
100
|
return /* @__PURE__ */ jsx(
|
|
62
101
|
"g",
|
|
63
102
|
{
|
package/dist/index.js
CHANGED
|
@@ -7,16 +7,99 @@ import {
|
|
|
7
7
|
|
|
8
8
|
// components/local-graph.tsx
|
|
9
9
|
import { buildGraphEdges, layoutRadialGraph } from "@riebeckite/core";
|
|
10
|
+
import { useArticleContext, useSiteContext } from "@riebeckite/ui";
|
|
11
|
+
import { html } from "hono/html";
|
|
12
|
+
|
|
13
|
+
// src/local-graph.server.ts
|
|
14
|
+
var MAX_NEIGHBORS_PER_DIRECTION = 10;
|
|
15
|
+
function buildLocalGraph(args) {
|
|
16
|
+
const graph = args.manifest.graph;
|
|
17
|
+
const current = graph.get(args.slug);
|
|
18
|
+
const discoverableSlugs = new Set(
|
|
19
|
+
args.manifest.discoverableEntries.map((entry) => entry.slug)
|
|
20
|
+
);
|
|
21
|
+
if (!current || !discoverableSlugs.has(current.slug)) return null;
|
|
22
|
+
const { outgoingSlugs, incomingSlugs } = graph.filterNeighbors(
|
|
23
|
+
args.slug,
|
|
24
|
+
isPublishedSlug
|
|
25
|
+
);
|
|
26
|
+
const visibleOutgoing = outgoingSlugs.slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
27
|
+
const visibleBacklinks = incomingSlugs.slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
28
|
+
const visibleSlugs = /* @__PURE__ */ new Set([
|
|
29
|
+
args.slug,
|
|
30
|
+
...visibleOutgoing,
|
|
31
|
+
...visibleBacklinks
|
|
32
|
+
]);
|
|
33
|
+
const nodes = Array.from(visibleSlugs).map(
|
|
34
|
+
(nodeSlug) => toLocalGraphNode(nodeSlug, args.slug, visibleOutgoing, visibleBacklinks)
|
|
35
|
+
).filter((node) => node !== null);
|
|
36
|
+
return { currentSlug: args.slug, nodes };
|
|
37
|
+
function isPublishedSlug(nodeSlug) {
|
|
38
|
+
const entry = graph.get(nodeSlug);
|
|
39
|
+
return entry !== null && discoverableSlugs.has(entry.slug);
|
|
40
|
+
}
|
|
41
|
+
function toLocalGraphNode(nodeSlug, currentSlug, outgoingSlugs2, backlinkSlugs) {
|
|
42
|
+
const entry = graph.get(nodeSlug);
|
|
43
|
+
if (!entry) return null;
|
|
44
|
+
return {
|
|
45
|
+
slug: entry.slug,
|
|
46
|
+
permalink: entry.permalink,
|
|
47
|
+
title: args.resolveTitle(entry.slug, entry.frontmatter.title),
|
|
48
|
+
relation: getRelation(
|
|
49
|
+
nodeSlug,
|
|
50
|
+
currentSlug,
|
|
51
|
+
outgoingSlugs2,
|
|
52
|
+
backlinkSlugs
|
|
53
|
+
),
|
|
54
|
+
outgoing: nodeSlug === currentSlug ? outgoingSlugs2 : backlinkSlugs.includes(nodeSlug) ? [currentSlug] : [],
|
|
55
|
+
backlinks: nodeSlug === currentSlug ? backlinkSlugs : outgoingSlugs2.includes(nodeSlug) ? [currentSlug] : []
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
var getLocalGraph = ({ view, slug }) => {
|
|
60
|
+
const current = view.findDiscoverableBySlug(slug);
|
|
61
|
+
if (!current) return null;
|
|
62
|
+
const outgoing = view.getDiscoverableOutgoing(slug).slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
63
|
+
const incoming = view.getDiscoverableIncoming(slug).slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
64
|
+
const outgoingSlugs = outgoing.map((entry) => entry.slug);
|
|
65
|
+
const incomingSlugs = incoming.map((entry) => entry.slug);
|
|
66
|
+
const entries = [current, ...outgoing, ...incoming].filter(
|
|
67
|
+
(entry, index, all) => all.findIndex((candidate) => candidate.slug === entry.slug) === index
|
|
68
|
+
);
|
|
69
|
+
return {
|
|
70
|
+
currentSlug: slug,
|
|
71
|
+
nodes: entries.map((entry) => ({
|
|
72
|
+
slug: entry.slug,
|
|
73
|
+
permalink: entry.permalink,
|
|
74
|
+
title: entry.title || entry.slug,
|
|
75
|
+
relation: getRelation(entry.slug, slug, outgoingSlugs, incomingSlugs),
|
|
76
|
+
outgoing: entry.slug === slug ? outgoingSlugs : incomingSlugs.includes(entry.slug) ? [slug] : [],
|
|
77
|
+
backlinks: entry.slug === slug ? incomingSlugs : outgoingSlugs.includes(entry.slug) ? [slug] : []
|
|
78
|
+
}))
|
|
79
|
+
};
|
|
80
|
+
};
|
|
81
|
+
function getRelation(slug, currentSlug, outgoing, backlinks) {
|
|
82
|
+
if (slug === currentSlug) return "current";
|
|
83
|
+
const isOutgoing = outgoing.includes(slug);
|
|
84
|
+
const isBacklink = backlinks.includes(slug);
|
|
85
|
+
if (isOutgoing && isBacklink) return "both";
|
|
86
|
+
return isOutgoing ? "outgoing" : "backlink";
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// components/local-graph.tsx
|
|
10
90
|
import { jsx, jsxs } from "hono/jsx/jsx-runtime";
|
|
11
91
|
var GRAPH_WIDTH = 640;
|
|
12
92
|
var GRAPH_HEIGHT = 320;
|
|
13
|
-
var LocalGraph = ((props) => {
|
|
14
|
-
|
|
15
|
-
const
|
|
16
|
-
const
|
|
93
|
+
var LocalGraph = (async (props) => {
|
|
94
|
+
const site = useSiteContext();
|
|
95
|
+
const article = useArticleContext();
|
|
96
|
+
const graph = props.graph ?? (site && article?.entry ? await getLocalGraph({ view: site.view, slug: article.entry.slug }) : null);
|
|
97
|
+
if (!graph || graph.nodes.length <= 1) return html``;
|
|
98
|
+
const edges = buildGraphEdges(graph.nodes);
|
|
99
|
+
const layout = layoutRadialGraph(graph.nodes, {
|
|
17
100
|
width: GRAPH_WIDTH,
|
|
18
101
|
height: GRAPH_HEIGHT,
|
|
19
|
-
centerSlug:
|
|
102
|
+
centerSlug: graph.currentSlug,
|
|
20
103
|
radiusRatio: 0.34,
|
|
21
104
|
minNodeRadius: 7,
|
|
22
105
|
maxNodeRadius: 12
|
|
@@ -31,7 +114,7 @@ var LocalGraph = ((props) => {
|
|
|
31
114
|
"a",
|
|
32
115
|
{
|
|
33
116
|
class: "rr-local-graph__explorer-link",
|
|
34
|
-
href: `/explore?note=${encodeURIComponent(
|
|
117
|
+
href: `/explore?note=${encodeURIComponent(graph.currentSlug)}`,
|
|
35
118
|
children: "Open in Explorer →"
|
|
36
119
|
}
|
|
37
120
|
)
|
|
@@ -52,7 +135,7 @@ var LocalGraph = ((props) => {
|
|
|
52
135
|
"line",
|
|
53
136
|
{
|
|
54
137
|
class: "rr-local-graph__edge",
|
|
55
|
-
"data-direction": edge.source ===
|
|
138
|
+
"data-direction": edge.source === graph.currentSlug ? "outgoing" : "backlink",
|
|
56
139
|
x1: source.x,
|
|
57
140
|
y1: source.y,
|
|
58
141
|
x2: target.x,
|
|
@@ -61,10 +144,10 @@ var LocalGraph = ((props) => {
|
|
|
61
144
|
`${edge.source}-${edge.target}`
|
|
62
145
|
);
|
|
63
146
|
}),
|
|
64
|
-
|
|
147
|
+
graph.nodes.map((node) => {
|
|
65
148
|
const point = layout.get(node.slug);
|
|
66
149
|
if (!point) return null;
|
|
67
|
-
const isCurrent = node.slug ===
|
|
150
|
+
const isCurrent = node.slug === graph.currentSlug;
|
|
68
151
|
return /* @__PURE__ */ jsx(
|
|
69
152
|
"g",
|
|
70
153
|
{
|
|
@@ -122,82 +205,6 @@ var LocalGraph = ((props) => {
|
|
|
122
205
|
});
|
|
123
206
|
var local_graph_default = LocalGraph;
|
|
124
207
|
|
|
125
|
-
// src/local-graph.server.ts
|
|
126
|
-
var MAX_NEIGHBORS_PER_DIRECTION = 10;
|
|
127
|
-
function buildLocalGraph(args) {
|
|
128
|
-
const graph = args.manifest.graph;
|
|
129
|
-
const current = graph.get(args.slug);
|
|
130
|
-
const discoverableSlugs = new Set(
|
|
131
|
-
args.manifest.discoverableEntries.map((entry) => entry.slug)
|
|
132
|
-
);
|
|
133
|
-
if (!current || !discoverableSlugs.has(current.slug)) return null;
|
|
134
|
-
const { outgoingSlugs, incomingSlugs } = graph.filterNeighbors(
|
|
135
|
-
args.slug,
|
|
136
|
-
isPublishedSlug
|
|
137
|
-
);
|
|
138
|
-
const visibleOutgoing = outgoingSlugs.slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
139
|
-
const visibleBacklinks = incomingSlugs.slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
140
|
-
const visibleSlugs = /* @__PURE__ */ new Set([
|
|
141
|
-
args.slug,
|
|
142
|
-
...visibleOutgoing,
|
|
143
|
-
...visibleBacklinks
|
|
144
|
-
]);
|
|
145
|
-
const nodes = Array.from(visibleSlugs).map(
|
|
146
|
-
(nodeSlug) => toLocalGraphNode(nodeSlug, args.slug, visibleOutgoing, visibleBacklinks)
|
|
147
|
-
).filter((node) => node !== null);
|
|
148
|
-
return { currentSlug: args.slug, nodes };
|
|
149
|
-
function isPublishedSlug(nodeSlug) {
|
|
150
|
-
const entry = graph.get(nodeSlug);
|
|
151
|
-
return entry !== null && discoverableSlugs.has(entry.slug);
|
|
152
|
-
}
|
|
153
|
-
function toLocalGraphNode(nodeSlug, currentSlug, outgoingSlugs2, backlinkSlugs) {
|
|
154
|
-
const entry = graph.get(nodeSlug);
|
|
155
|
-
if (!entry) return null;
|
|
156
|
-
return {
|
|
157
|
-
slug: entry.slug,
|
|
158
|
-
permalink: entry.permalink,
|
|
159
|
-
title: args.resolveTitle(entry.slug, entry.frontmatter.title),
|
|
160
|
-
relation: getRelation(
|
|
161
|
-
nodeSlug,
|
|
162
|
-
currentSlug,
|
|
163
|
-
outgoingSlugs2,
|
|
164
|
-
backlinkSlugs
|
|
165
|
-
),
|
|
166
|
-
outgoing: nodeSlug === currentSlug ? outgoingSlugs2 : backlinkSlugs.includes(nodeSlug) ? [currentSlug] : [],
|
|
167
|
-
backlinks: nodeSlug === currentSlug ? backlinkSlugs : outgoingSlugs2.includes(nodeSlug) ? [currentSlug] : []
|
|
168
|
-
};
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
var getLocalGraph = ({ view, slug }) => {
|
|
172
|
-
const current = view.findDiscoverableBySlug(slug);
|
|
173
|
-
if (!current) return null;
|
|
174
|
-
const outgoing = view.getDiscoverableOutgoing(slug).slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
175
|
-
const incoming = view.getDiscoverableIncoming(slug).slice(0, MAX_NEIGHBORS_PER_DIRECTION);
|
|
176
|
-
const outgoingSlugs = outgoing.map((entry) => entry.slug);
|
|
177
|
-
const incomingSlugs = incoming.map((entry) => entry.slug);
|
|
178
|
-
const entries = [current, ...outgoing, ...incoming].filter(
|
|
179
|
-
(entry, index, all) => all.findIndex((candidate) => candidate.slug === entry.slug) === index
|
|
180
|
-
);
|
|
181
|
-
return {
|
|
182
|
-
currentSlug: slug,
|
|
183
|
-
nodes: entries.map((entry) => ({
|
|
184
|
-
slug: entry.slug,
|
|
185
|
-
permalink: entry.permalink,
|
|
186
|
-
title: entry.title || entry.slug,
|
|
187
|
-
relation: getRelation(entry.slug, slug, outgoingSlugs, incomingSlugs),
|
|
188
|
-
outgoing: entry.slug === slug ? outgoingSlugs : incomingSlugs.includes(entry.slug) ? [slug] : [],
|
|
189
|
-
backlinks: entry.slug === slug ? incomingSlugs : outgoingSlugs.includes(entry.slug) ? [slug] : []
|
|
190
|
-
}))
|
|
191
|
-
};
|
|
192
|
-
};
|
|
193
|
-
function getRelation(slug, currentSlug, outgoing, backlinks) {
|
|
194
|
-
if (slug === currentSlug) return "current";
|
|
195
|
-
const isOutgoing = outgoing.includes(slug);
|
|
196
|
-
const isBacklink = backlinks.includes(slug);
|
|
197
|
-
if (isOutgoing && isBacklink) return "both";
|
|
198
|
-
return isOutgoing ? "outgoing" : "backlink";
|
|
199
|
-
}
|
|
200
|
-
|
|
201
208
|
// index.ts
|
|
202
209
|
function localGraphPlugin(options = {}) {
|
|
203
210
|
return definePlugin({
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@riebeckite/plugin-local-graph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.25",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -22,11 +22,12 @@
|
|
|
22
22
|
},
|
|
23
23
|
"dependencies": {
|
|
24
24
|
"hono": "^4.12.25",
|
|
25
|
-
"@riebeckite/core": "0.0.
|
|
25
|
+
"@riebeckite/core": "0.0.25",
|
|
26
|
+
"@riebeckite/ui": "0.0.25"
|
|
26
27
|
},
|
|
27
28
|
"devDependencies": {
|
|
28
29
|
"tsx": "^4.22.4",
|
|
29
|
-
"@riebeckite/test": "0.0.
|
|
30
|
+
"@riebeckite/test": "0.0.25"
|
|
30
31
|
},
|
|
31
32
|
"publishConfig": {
|
|
32
33
|
"access": "public"
|