@lapis-notes/graph 0.1.2 → 0.1.4

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/CHANGELOG.md CHANGED
@@ -1,5 +1,34 @@
1
1
  # Graph changelog
2
2
 
3
+ ## 0.1.4
4
+
5
+ ### Patch Changes
6
+
7
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`d27467e`](https://github.com/lapismd/lapis-plugins/commit/d27467ee80c273011b7eb6ae792fa8e0330a11c1) Thanks [@stevejuma](https://github.com/stevejuma)! - Align shared presentation dependencies with the Design Core 0.6 public boundary used by current Notes hosts.
8
+
9
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`f4b9136`](https://github.com/lapismd/lapis-plugins/commit/f4b9136e4f47965700e06f52f82e8e2bc884eb11) Thanks [@stevejuma](https://github.com/stevejuma)! - Accept Design Core 0.5.1 alongside the existing 0.4 release line so current local
10
+ Desktop builds can use one compatible framework graph.
11
+
12
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`56b5d6c`](https://github.com/lapismd/lapis-plugins/commit/56b5d6c1a016ef9bca43703b5fecf57f8234d1af) Thanks [@stevejuma](https://github.com/stevejuma)! - Consume published Design Core 0.4.0 with prepared browser CSS and bundled font assets through normal npm ranges.
13
+
14
+ Restore Bases picker input/list accessibility relationships and name property actions.
15
+
16
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`c9febb1`](https://github.com/lapismd/lapis-plugins/commit/c9febb1c8b431db30ecdcf7507cfff8f727bc4ed) Thanks [@stevejuma](https://github.com/stevejuma)! - Consume the published Notes next packages, Mira 0.1.2, and Design Core 0.7.0 through the existing semver floors. Markdown dependents accept ^0.2.0. History keeps its public repository entrypoints, and Bases keeps the file-icon contract on API 0.2.0.
17
+
18
+ - [#28](https://github.com/lapismd/lapis-plugins/pull/28) [`fbdd341`](https://github.com/lapismd/lapis-plugins/commit/fbdd341e6df180ff4ef39b6c5091ed3e77802a3b) Thanks [@stevejuma](https://github.com/stevejuma)! - Admit debounced settings before native close and refresh open Graph views after explicit disk recovery.
19
+
20
+ - Updated dependencies [[`d27467e`](https://github.com/lapismd/lapis-plugins/commit/d27467ee80c273011b7eb6ae792fa8e0330a11c1), [`f4b9136`](https://github.com/lapismd/lapis-plugins/commit/f4b9136e4f47965700e06f52f82e8e2bc884eb11), [`ae5b5d9`](https://github.com/lapismd/lapis-plugins/commit/ae5b5d9bf7d8f84296280581a8f95fd198265e62), [`ae5b5d9`](https://github.com/lapismd/lapis-plugins/commit/ae5b5d9bf7d8f84296280581a8f95fd198265e62), [`ae5b5d9`](https://github.com/lapismd/lapis-plugins/commit/ae5b5d9bf7d8f84296280581a8f95fd198265e62), [`56b5d6c`](https://github.com/lapismd/lapis-plugins/commit/56b5d6c1a016ef9bca43703b5fecf57f8234d1af)]:
21
+ - @lapis-notes/markdown@0.2.0
22
+
23
+ ## 0.1.3
24
+
25
+ ### Patch Changes
26
+
27
+ - Add official author avatars and deterministic split, light, and dark registry media for plugin banners, overviews, and galleries.
28
+
29
+ - Updated dependencies []:
30
+ - @lapis-notes/markdown@0.1.5
31
+
3
32
  ## 0.1.2
4
33
 
5
34
  - Initial independent public package extracted from Lapis Notes without changing
package/LICENSE.md CHANGED
@@ -1,8 +1,4 @@
1
- # License
1
+ Apache-2.0
2
2
 
3
- Copyright (c) LapisMD contributors.
4
-
5
- This software is licensed under the GNU Affero General Public License, version
6
- 3 or (at your option) any later version (`AGPL-3.0-or-later`). The complete
7
- license text is available from the
8
- [GNU Project](https://www.gnu.org/licenses/agpl-3.0.html).
3
+ This project is licensed under the Apache License 2.0.
4
+ See <https://www.apache.org/licenses/LICENSE-2.0>.
package/README.md CHANGED
@@ -13,7 +13,7 @@ Register the exported plugin class in the application's `PluginProfile`. Import
13
13
  registration so the host owns its lifecycle.
14
14
 
15
15
  The runtime plugin ID is `lapis-graph`. A matching signed
16
- `lapis-graph-0.1.2.lapis-plugin` archive is attached to the
16
+ `lapis-graph-0.1.4.lapis-plugin` archive is attached to the
17
17
  package-scoped GitHub release for manual or registry installation.
18
18
 
19
19
  See the [repository README](https://github.com/lapismd/lapis-plugins#readme) for
@@ -13,7 +13,8 @@ export declare class GraphPlugin extends Plugin {
13
13
  private readonly graphCoordinator;
14
14
  private settings;
15
15
  private settingsSaveTimer;
16
- private pendingSettingsSave;
16
+ private releaseSettingsSave;
17
+ private settingsSaveTask;
17
18
  private graphProblems;
18
19
  private readonly pathQueryCache;
19
20
  constructor(app: App, manifest?: PluginManifest);
@@ -21,6 +22,7 @@ export declare class GraphPlugin extends Plugin {
21
22
  onunload(): Promise<void>;
22
23
  getSettings(): GraphSettings;
23
24
  updateSettings(nextSettings: GraphSettings): Promise<void>;
25
+ private applySettings;
24
26
  subscribeToGlobalGraph(listener: (state: GraphCoordinatorState) => void): () => void;
25
27
  refreshGlobalGraph(force?: boolean): Promise<void>;
26
28
  reportGraphBuildFailure(scope: GraphProblemScope, path: string | null, error: unknown): void;
@@ -1,4 +1,4 @@
1
- import { Plugin, } from "@lapis-notes/api";
1
+ import { Plugin, Notice, } from "@lapis-notes/api";
2
2
  import { DEFAULT_GRAPH_SETTINGS, loadPersistedGraphSettings, mergeGraphSettings, serializeGraphSettings, } from "./graph-settings";
3
3
  import { GraphDataCoordinator, } from "./graph-data-coordinator";
4
4
  import { filterGraphBySettings } from "./graph-data";
@@ -11,7 +11,8 @@ export class GraphPlugin extends Plugin {
11
11
  graphCoordinator;
12
12
  settings = mergeGraphSettings(DEFAULT_GRAPH_SETTINGS);
13
13
  settingsSaveTimer = null;
14
- pendingSettingsSave = null;
14
+ releaseSettingsSave = null;
15
+ settingsSaveTask = null;
15
16
  graphProblems = null;
16
17
  pathQueryCache = new Map();
17
18
  constructor(app, manifest = manifestSpec) {
@@ -20,6 +21,12 @@ export class GraphPlugin extends Plugin {
20
21
  }
21
22
  async onload() {
22
23
  await this.initializeSettings();
24
+ this.registerEvent(this.app.configuration.on("plugin-data-updated", (event) => {
25
+ if (event.pluginId !== this.manifest.id ||
26
+ event.origin === "plugin-save")
27
+ return;
28
+ this.applySettings(loadPersistedGraphSettings(event.value).settings);
29
+ }));
23
30
  this.graphProblems = createGraphProblemReporter(this);
24
31
  this.register(this.graphCoordinator.subscribe((state) => {
25
32
  if (state.status === "error") {
@@ -77,21 +84,23 @@ export class GraphPlugin extends Plugin {
77
84
  if (this.settingsSaveTimer)
78
85
  clearTimeout(this.settingsSaveTimer);
79
86
  this.settingsSaveTimer = null;
80
- const pending = this.pendingSettingsSave;
81
- this.pendingSettingsSave = null;
82
- if (pending)
83
- await this.saveData(pending);
87
+ this.releaseSettingsSave?.(true);
88
+ this.releaseSettingsSave = null;
89
+ await this.settingsSaveTask;
84
90
  }
85
91
  getSettings() {
86
92
  return mergeGraphSettings(this.settings);
87
93
  }
88
94
  async updateSettings(nextSettings) {
95
+ this.applySettings(nextSettings);
96
+ this.scheduleSettingsSave(this.getSettings());
97
+ }
98
+ applySettings(nextSettings) {
89
99
  this.settings = mergeGraphSettings(nextSettings);
90
100
  const snapshot = this.getSettings();
91
101
  this.views.forEach((view) => {
92
102
  view.applyGraphSettings(snapshot);
93
103
  });
94
- this.scheduleSettingsSave(snapshot);
95
104
  }
96
105
  subscribeToGlobalGraph(listener) {
97
106
  return this.graphCoordinator.subscribe(listener);
@@ -127,15 +136,29 @@ export class GraphPlugin extends Plugin {
127
136
  }
128
137
  }
129
138
  scheduleSettingsSave(settings) {
130
- this.pendingSettingsSave = serializeGraphSettings(settings);
131
139
  if (this.settingsSaveTimer)
132
140
  clearTimeout(this.settingsSaveTimer);
141
+ this.releaseSettingsSave?.(false);
142
+ const snapshot = serializeGraphSettings(settings);
143
+ let release;
144
+ const ready = new Promise((resolve) => {
145
+ release = resolve;
146
+ });
147
+ this.releaseSettingsSave = release;
148
+ const persist = async () => {
149
+ if (await ready)
150
+ await this.saveData(snapshot);
151
+ };
152
+ this.settingsSaveTask = this.app.vault.supportsConditionalTextWrites
153
+ ? this.app.fileEditingSessions.track(persist)
154
+ : persist();
155
+ void this.settingsSaveTask.catch((error) => {
156
+ new Notice(`Graph settings could not be saved: ${error instanceof Error ? error.message : String(error)}`, undefined, this.app);
157
+ });
133
158
  this.settingsSaveTimer = setTimeout(() => {
134
159
  this.settingsSaveTimer = null;
135
- const pending = this.pendingSettingsSave;
136
- this.pendingSettingsSave = null;
137
- if (pending)
138
- void this.saveData(pending);
160
+ this.releaseSettingsSave = null;
161
+ release(true);
139
162
  }, 180);
140
163
  }
141
164
  matchSearchPaths(query) {
package/manifest.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "id": "lapis-graph",
3
3
  "name": "Graph",
4
- "version": "0.1.2",
4
+ "version": "0.1.4",
5
5
  "minAppVersion": "0.1.0",
6
6
  "description": "Global and local graph views powered by indexed metadata",
7
7
  "author": "Lapis Notes",
8
8
  "authorUrl": "https://app.lapis.md",
9
+ "authorAvatarUrl": "https://gravatar.com/avatar/f7226d5f9cf07af2a6a60d3ab11413abb9d2e2eb60f2d5cce17356845a166155?size=256&d=initials",
9
10
  "isDesktopOnly": false,
10
11
  "lapis": {
11
12
  "manifestVersion": 1,
@@ -20,7 +21,23 @@
20
21
  "sharedDependencies": [
21
22
  "@lapis-notes/api",
22
23
  "@lapis-notes/api/telemetry",
23
- "@lapis-notes/markdown/embed"
24
+ "@lapis-notes/markdown/embed",
25
+ "@codemirror/autocomplete",
26
+ "@codemirror/commands",
27
+ "@codemirror/language",
28
+ "@codemirror/lint",
29
+ "@codemirror/state",
30
+ "@codemirror/view",
31
+ "@lezer/common",
32
+ "@lezer/highlight",
33
+ "@lezer/lr",
34
+ "svelte/renderer/5.56.10",
35
+ "svelte/renderer/5.56.10/attachments",
36
+ "svelte/renderer/5.56.10/events",
37
+ "svelte/renderer/5.56.10/internal/client",
38
+ "svelte/renderer/5.56.10/internal/disclose-version",
39
+ "svelte/renderer/5.56.10/internal/flags/legacy",
40
+ "svelte/renderer/5.56.10/reactivity"
24
41
  ],
25
42
  "requiresReloadOnUpdate": false
26
43
  }
package/package.json CHANGED
@@ -1,13 +1,14 @@
1
1
  {
2
2
  "name": "@lapis-notes/graph",
3
- "version": "0.1.2",
3
+ "version": "0.1.4",
4
4
  "description": "Lapis Notes global and local graph plugin",
5
- "license": "AGPL-3.0-or-later",
5
+ "license": "Apache-2.0",
6
6
  "type": "module",
7
7
  "files": [
8
8
  "dist",
9
9
  "manifest.json",
10
10
  "registry.json",
11
+ "registry-content",
11
12
  "styles.css",
12
13
  "README.md",
13
14
  "CHANGELOG.md",
@@ -41,17 +42,26 @@
41
42
  "./registry.json": "./registry.json"
42
43
  },
43
44
  "dependencies": {
44
- "@lapismd/design-core": "^0.1.0",
45
+ "@lapismd/design-core": "^0.7.0",
45
46
  "@lucide/svelte": "^0.523.0",
46
47
  "d3-force": "^3.0.0"
47
48
  },
48
49
  "peerDependencies": {
49
- "@lapis-notes/api": "^0.1.0",
50
- "@lapis-notes/markdown": "^0.1.2",
50
+ "@codemirror/autocomplete": "^6.18.6",
51
+ "@codemirror/commands": "^6.8.1",
52
+ "@codemirror/language": "^6.11.3",
53
+ "@codemirror/lint": "^6.8.5",
54
+ "@codemirror/state": "^6.6.0",
55
+ "@codemirror/view": "^6.42.1",
56
+ "@lapis-notes/api": "^0.2.0",
57
+ "@lapis-notes/markdown": "^0.2.0",
58
+ "@lezer/common": "^1.5.2",
59
+ "@lezer/highlight": "^1.2.3",
60
+ "@lezer/lr": "^1.4.2",
51
61
  "svelte": "^5.0.0"
52
62
  },
53
63
  "devDependencies": {
54
- "@lapis-notes/markdown": "^0.1.2",
64
+ "@lapis-notes/markdown": "^0.2.0",
55
65
  "@sveltejs/package": "^2.5.0",
56
66
  "@sveltejs/vite-plugin-svelte": "^5.1.1",
57
67
  "@tsconfig/svelte": "^5.0.5",
@@ -60,8 +70,8 @@
60
70
  "svelte": "^5.38.2",
61
71
  "svelte-check": "^4.3.1",
62
72
  "typescript": "~5.8.3",
63
- "vite": "^6.4.2",
64
- "vitest": "^4.1.8"
73
+ "vite": "^6.4.4",
74
+ "vitest": "^4.1.12"
65
75
  },
66
76
  "repository": {
67
77
  "type": "git",
@@ -0,0 +1,8 @@
1
+ # Graph
2
+
3
+ Graph visualizes relationships between notes, tags, and attachments using the
4
+ vault's indexed metadata. Global Graph shows the broader network, while Local
5
+ Graph keeps one note and its nearby connections in focus.
6
+
7
+ Open connected notes directly from the canvas and tune grouping, forces, and
8
+ time-lapse controls to make larger vaults easier to explore.
package/registry.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "$schema": "https://registry.lapis.md/schemas/plugin-source.schema.json",
3
- "schemaVersion": 1,
3
+ "schemaVersion": 2,
4
4
  "categories": ["graph", "visualization"],
5
5
  "highlights": [
6
6
  "Explore global and local relationships across notes, tags, and attachments.",
@@ -8,5 +8,142 @@
8
8
  "Tune grouping, forces, and time-lapse views for large vaults."
9
9
  ],
10
10
  "documentationUrl": "https://github.com/lapismd/lapis-plugins/tree/main/packages/graph#readme",
11
- "content": { "overview": "README.md", "changelog": "CHANGELOG.md" }
11
+ "appearance": {
12
+ "icon": "network",
13
+ "accent": "#8B5CF6"
14
+ },
15
+ "media": {
16
+ "banner": {
17
+ "alt": "Lapis Graph with Explorer on the left, a connected Global Graph in the main workspace, and Local Graph on the right.",
18
+ "images": {
19
+ "preview": {
20
+ "path": "registry-assets/banner.preview.webp"
21
+ },
22
+ "full": {
23
+ "path": "registry-assets/banner.full.webp"
24
+ },
25
+ "light": {
26
+ "path": "registry-assets/banner.light.webp"
27
+ },
28
+ "dark": {
29
+ "path": "registry-assets/banner.dark.webp"
30
+ }
31
+ },
32
+ "capture": {
33
+ "storyId": "plugins-graph-registry-screenshots--overview",
34
+ "focus": "full-shell"
35
+ }
36
+ },
37
+ "overview": {
38
+ "alt": "Focused Lapis Global Graph showing connected notes, tags, attachments, and unresolved links.",
39
+ "images": {
40
+ "preview": {
41
+ "path": "registry-assets/overview.preview.webp"
42
+ },
43
+ "full": {
44
+ "path": "registry-assets/overview.full.webp"
45
+ },
46
+ "light": {
47
+ "path": "registry-assets/overview.light.webp"
48
+ },
49
+ "dark": {
50
+ "path": "registry-assets/overview.dark.webp"
51
+ }
52
+ },
53
+ "capture": {
54
+ "storyId": "plugins-graph-registry-screenshots--global-graph",
55
+ "focus": "full-shell"
56
+ }
57
+ }
58
+ },
59
+ "gallery": [
60
+ {
61
+ "id": "global-graph",
62
+ "alt": "Focused global graph showing a richly connected project network with notes, tags, attachments, and unresolved links.",
63
+ "images": {
64
+ "preview": {
65
+ "path": "registry-assets/gallery/global-graph.preview.webp"
66
+ },
67
+ "full": {
68
+ "path": "registry-assets/gallery/global-graph.full.webp"
69
+ },
70
+ "light": {
71
+ "path": "registry-assets/gallery/global-graph.light.webp"
72
+ },
73
+ "dark": {
74
+ "path": "registry-assets/gallery/global-graph.dark.webp"
75
+ }
76
+ },
77
+ "capture": {
78
+ "storyId": "plugins-graph-registry-screenshots--global-graph",
79
+ "focus": "full-shell"
80
+ },
81
+ "card": {
82
+ "headline": [
83
+ {
84
+ "text": "See how your vault",
85
+ "tone": "neutral"
86
+ },
87
+ {
88
+ "text": "connects",
89
+ "tone": "violet"
90
+ }
91
+ ],
92
+ "description": [
93
+ {
94
+ "text": "Explore notes, tags, attachments, and",
95
+ "tone": "neutral"
96
+ },
97
+ {
98
+ "text": "unresolved links",
99
+ "tone": "rose"
100
+ },
101
+ {
102
+ "text": "in a live global map.",
103
+ "tone": "cyan"
104
+ }
105
+ ]
106
+ }
107
+ },
108
+ {
109
+ "id": "local-graph",
110
+ "alt": "Local graph sidebar focused on the active Welcome note and its connected project notes and tags.",
111
+ "images": {
112
+ "preview": {
113
+ "path": "registry-assets/gallery/local-graph.preview.webp"
114
+ },
115
+ "full": {
116
+ "path": "registry-assets/gallery/local-graph.full.webp"
117
+ },
118
+ "light": {
119
+ "path": "registry-assets/gallery/local-graph.light.webp"
120
+ },
121
+ "dark": {
122
+ "path": "registry-assets/gallery/local-graph.dark.webp"
123
+ }
124
+ },
125
+ "capture": {
126
+ "storyId": "plugins-graph-registry-screenshots--local-graph",
127
+ "focus": "right-sidebar"
128
+ },
129
+ "card": {
130
+ "headline": [
131
+ {
132
+ "text": "Focus on what is",
133
+ "tone": "neutral"
134
+ },
135
+ {
136
+ "text": "nearby",
137
+ "tone": "cyan"
138
+ }
139
+ ],
140
+ "description": [
141
+ {
142
+ "text": "Follow the active note and its closest relationships without losing your writing context.",
143
+ "tone": "neutral"
144
+ }
145
+ ]
146
+ }
147
+ }
148
+ ]
12
149
  }