noteconnection 1.1.2 → 1.3.0

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.
@@ -0,0 +1,240 @@
1
+ /* Path Mode Styles */
2
+
3
+ .path-container {
4
+ position: absolute;
5
+ top: 0;
6
+ left: 0;
7
+ width: 100vw;
8
+ height: 100vh;
9
+ background-color: #1e1e1e; /* Dark theme default */
10
+ z-index: 2000; /* Above main graph */
11
+ display: none; /* Hidden by default */
12
+ overflow: hidden;
13
+ font-family: "Segoe UI", Tahoma, Geneva, Verdana, sans-serif;
14
+ }
15
+
16
+ .path-toolbar {
17
+ position: absolute;
18
+ top: 10px;
19
+ left: 50%;
20
+ transform: translateX(-50%);
21
+ background: rgba(30, 30, 30, 0.9);
22
+ backdrop-filter: blur(10px);
23
+ padding: 8px 16px;
24
+ border-radius: 8px;
25
+ border: 1px solid rgba(255, 255, 255, 0.1);
26
+ display: flex;
27
+ gap: 20px;
28
+ align-items: center;
29
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.3);
30
+ z-index: 2005;
31
+ }
32
+
33
+ .toolbar-group {
34
+ display: flex;
35
+ align-items: center;
36
+ gap: 8px;
37
+ color: #e0e0e0;
38
+ font-size: 0.9rem;
39
+ }
40
+
41
+ .toolbar-group select {
42
+ background: #333;
43
+ color: white;
44
+ border: 1px solid #555;
45
+ padding: 4px 8px;
46
+ border-radius: 4px;
47
+ outline: none;
48
+ }
49
+
50
+ .toolbar-group select:hover {
51
+ border-color: #777;
52
+ }
53
+
54
+ .toolbar-group.right {
55
+ margin-left: 20px;
56
+ border-left: 1px solid #555;
57
+ padding-left: 20px;
58
+ }
59
+
60
+ .icon-btn {
61
+ background: none;
62
+ border: none;
63
+ color: #ff6b6b;
64
+ cursor: pointer;
65
+ font-size: 1rem;
66
+ padding: 4px 8px;
67
+ border-radius: 4px;
68
+ transition: background 0.2s;
69
+ }
70
+
71
+ .icon-btn:hover {
72
+ background: rgba(255, 107, 107, 0.1);
73
+ }
74
+
75
+ #path-canvas {
76
+ position: absolute;
77
+ top: 0;
78
+ left: 0;
79
+ width: 100%;
80
+ height: 100%;
81
+ }
82
+
83
+ #path-status {
84
+ position: absolute;
85
+ bottom: 20px;
86
+ left: 20px;
87
+ color: #888;
88
+ font-size: 0.9rem;
89
+ pointer-events: none;
90
+ }
91
+
92
+ /* Node Cards (if we use DOM overlays) */
93
+ .path-node-card {
94
+ position: absolute;
95
+ background: #2d2d2d;
96
+ border: 1px solid #444;
97
+ border-radius: 6px;
98
+ padding: 10px;
99
+ width: 200px;
100
+ box-shadow: 0 4px 12px rgba(0, 0, 0, 0.5);
101
+ pointer-events: auto;
102
+ transition:
103
+ transform 0.2s,
104
+ box-shadow 0.2s;
105
+ }
106
+
107
+ .path-node-card:hover {
108
+ transform: translateY(-2px);
109
+ box-shadow: 0 6px 16px rgba(0, 0, 0, 0.6);
110
+ border-color: #666;
111
+ }
112
+
113
+ .path-node-title {
114
+ color: #fff;
115
+ font-weight: bold;
116
+ margin-bottom: 5px;
117
+ font-size: 1rem;
118
+ }
119
+
120
+ .path-node-meta {
121
+ color: #aaa;
122
+ font-size: 0.8rem;
123
+ }
124
+
125
+ .step-badge {
126
+ display: inline-block;
127
+ background: #4a9eff;
128
+ color: white;
129
+ padding: 2px 6px;
130
+ border-radius: 10px;
131
+ font-size: 0.7rem;
132
+ margin-right: 5px;
133
+ }
134
+
135
+ /* v1.3 Path Mode Extensions */
136
+
137
+ /* Action Buttons */
138
+ #btn-mark-complete {
139
+ background: linear-gradient(135deg, #ffd700 0%, #ffa500 100%);
140
+ color: #000;
141
+ font-weight: bold;
142
+ border: none;
143
+ box-shadow: 0 0 10px rgba(255, 215, 0, 0.4);
144
+ }
145
+
146
+ #btn-mark-complete:hover {
147
+ box-shadow: 0 0 15px rgba(255, 215, 0, 0.6);
148
+ transform: scale(1.05);
149
+ }
150
+
151
+ #btn-toggle-history {
152
+ color: #4a9eff;
153
+ border-color: #4a9eff;
154
+ }
155
+
156
+ /* Sidebar */
157
+ .path-sidebar {
158
+ position: absolute;
159
+ top: 60px; /* Below toolbar */
160
+ right: 0;
161
+ width: 300px;
162
+ height: calc(100% - 60px);
163
+ background: rgba(30, 30, 30, 0.95);
164
+ border-left: 1px solid #444;
165
+ transition: transform 0.3s ease-in-out;
166
+ transform: translateX(
167
+ 100%
168
+ ); /* Hidden state logic handled by display: none for now, but transform is smoother */
169
+ display: flex; /* Overridden by inline style */
170
+ flex-direction: column;
171
+ z-index: 1000;
172
+ }
173
+
174
+ .sidebar-header {
175
+ padding: 15px;
176
+ background: #252525;
177
+ border-bottom: 1px solid #444;
178
+ display: flex;
179
+ justify-content: space-between;
180
+ align-items: center;
181
+ }
182
+
183
+ .sidebar-header h3 {
184
+ margin: 0;
185
+ font-size: 1rem;
186
+ color: #ffd700;
187
+ }
188
+
189
+ .close-btn {
190
+ background: none;
191
+ border: none;
192
+ color: #aaa;
193
+ font-size: 1.2rem;
194
+ cursor: pointer;
195
+ }
196
+
197
+ .sidebar-content {
198
+ flex: 1;
199
+ overflow-y: auto;
200
+ padding: 10px;
201
+ }
202
+
203
+ .history-item {
204
+ padding: 8px;
205
+ border-bottom: 1px solid #333;
206
+ cursor: pointer;
207
+ display: flex;
208
+ align-items: center;
209
+ gap: 10px;
210
+ transition: background 0.2s;
211
+ }
212
+
213
+ .history-item:hover {
214
+ background: #333;
215
+ }
216
+
217
+ .history-dot {
218
+ width: 10px;
219
+ height: 10px;
220
+ background: #ffd700;
221
+ border-radius: 50%;
222
+ box-shadow: 0 0 5px #ffd700;
223
+ }
224
+
225
+ .history-label {
226
+ color: #ccc;
227
+ font-size: 0.9rem;
228
+ }
229
+
230
+ /* Modal tweaks specific to Path Mode */
231
+ #node-select-list li {
232
+ padding: 8px;
233
+ border-bottom: 1px solid #333;
234
+ cursor: pointer;
235
+ color: #ccc;
236
+ }
237
+ #node-select-list li:hover {
238
+ background: #444;
239
+ color: #fff;
240
+ }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Path Mode Worker
3
+ * Bundles Core Algorithms and Layout Logic
4
+ */
5
+
6
+ importScripts("libs/d3.v7.min.js");
7
+ // We will rely on a bundled version of the core being importable
8
+ // The build script will generate 'libs/path_core.js' which defines 'Graph' and 'PathEngine' classes globally or via a shim
9
+ importScripts("libs/path_core.js");
10
+
11
+ let graph = null;
12
+ let engine = null;
13
+ let rawNodes = [];
14
+ let rawLinks = [];
15
+
16
+ onmessage = function(e) {
17
+ const { type, payload } = e.data;
18
+
19
+ try {
20
+ switch (type) {
21
+ case 'initData':
22
+ initData(payload);
23
+ break;
24
+ case 'computePath':
25
+ computePath(payload);
26
+ break;
27
+ }
28
+ } catch (err) {
29
+ console.error('Worker Error:', err);
30
+ }
31
+ };
32
+
33
+ function initData(data) {
34
+ // Reconstruct Graph object
35
+ // Assuming Graph class is globally available from path_core.js
36
+ graph = new Graph();
37
+ data.nodes.forEach(n => graph.addNode(n));
38
+ data.links.forEach(l => graph.addEdge(l.source, l.target, l.type, l.weight));
39
+
40
+ engine = new PathEngine(graph);
41
+ postMessage({ type: 'log', payload: `Graph Initialized: ${data.nodes.length} nodes` });
42
+ }
43
+
44
+ function computePath(config) {
45
+ if (!engine) return;
46
+
47
+ const { mode, strategy, layout, targetId } = config;
48
+ let result;
49
+
50
+ if (mode === 'domain') {
51
+ result = engine.domainLearning(null, strategy);
52
+ } else {
53
+ // Validation for Diffusion Mode
54
+ if (!targetId || targetId === 'null' || !graph.hasNode(targetId)) {
55
+ console.warn(`[PathWorker] Invalid target '${targetId}' for Diffusion. Fallback to Domain.`);
56
+ result = engine.domainLearning(null, 'foundational'); // Fallback
57
+ } else {
58
+ result = engine.diffusionLearning(targetId, strategy);
59
+ }
60
+ }
61
+
62
+ // Layout Calculation
63
+ // We need to assign x,y coordinates to the result nodes
64
+ // Structure: result.nodes is a linear sequence or a set.
65
+ // For Tree layout, we need to reconstruct the hierarchy passed in result.edges (which are relevant dependencies)
66
+
67
+ const layoutData = runLayout(result.nodes, result.edges, layout);
68
+
69
+ postMessage({
70
+ type: 'pathResult',
71
+ payload: {
72
+ nodes: layoutData.nodes,
73
+ edges: layoutData.edges
74
+ }
75
+ });
76
+ }
77
+
78
+ function runLayout(nodes, edges, type) {
79
+ // Convert to D3 Stratify structure if possible, or use d3-dag
80
+ // Simple approach: Build a hierarchy from stepOrder or dependencies
81
+
82
+ // Create a hierarchy object for D3
83
+ // Root is a virtual node connecting to all step 1 nodes?
84
+ // Or finds roots (in-degree 0) in the subgraph
85
+
86
+ // 1. Map nodes for quick access
87
+ const nodeMap = new Map();
88
+ nodes.forEach(n => {
89
+ // Clone to avoid mutating original logic objects if needed
90
+ nodeMap.set(n.id, { ...n, children: [] });
91
+ });
92
+
93
+ // 2. Build Tree Structure
94
+ // Note: Graph might be DAG, D3 Tree requires strict Tree.
95
+ // We break cycles/multi-parents by just taking the first parent found in this path?
96
+ // Or use graph layout. For MVP, we use a simple Level-based layout based on 'stepOrder'.
97
+
98
+ if (type === 'horizontal' || type === 'vertical') {
99
+ const levelHeight = 100;
100
+ const levelWidth = 80;
101
+
102
+ // Group by stepOrder
103
+ const levels = [];
104
+ nodes.forEach(node => {
105
+ if (!levels[node.stepOrder]) levels[node.stepOrder] = [];
106
+ levels[node.stepOrder].push(nodeMap.get(node.id));
107
+ });
108
+
109
+ // Assign coordinates
110
+ levels.forEach((level, i) => {
111
+ const y = i * levelHeight;
112
+ const xStart = -(level.length * levelWidth) / 2;
113
+ level.forEach((node, j) => {
114
+ if (type === 'vertical') {
115
+ node.x = xStart + j * levelWidth;
116
+ node.y = y;
117
+ } else {
118
+ node.x = y;
119
+ node.y = xStart + j * levelWidth;
120
+ }
121
+ });
122
+ });
123
+ } else if (type === 'radial') {
124
+ // Radial: Angle based on index, Radius based on step
125
+ const radiusStep = 120;
126
+
127
+ // Group by step for better radial distribution
128
+ const levels = [];
129
+ nodes.forEach(node => {
130
+ const step = node.stepOrder || 1;
131
+ if (!levels[step]) levels[step] = [];
132
+ levels[step].push(nodeMap.get(node.id));
133
+ });
134
+
135
+ levels.forEach((level, stepIndex) => {
136
+ if (!level) return;
137
+ const r = stepIndex * radiusStep;
138
+ level.forEach((node, i) => {
139
+ // Distribute nodes in this level around the circle
140
+ const angle = (i / level.length) * 2 * Math.PI;
141
+ // Rotate slightly per level to avoid overlap
142
+ const offset = stepIndex * 0.2;
143
+
144
+ node.x = r * Math.cos(angle + offset);
145
+ node.y = r * Math.sin(angle + offset);
146
+ });
147
+ });
148
+ } else if (type === 'orbital') {
149
+ // Orbital: Central node at 0,0. Neighbors in orbit.
150
+ // We need to identify the "Central" node.
151
+ // Strategy: First node in the list is assumed central/focus for now,
152
+ // OR the app should pass a 'focusId'.
153
+ // For Path Mode, usually the first node (step 1) or the "current" node is central.
154
+ // Let's assume nodes[0] is the center if not specified.
155
+
156
+ const centerNode = nodes[0];
157
+ if (centerNode) {
158
+ nodeMap.get(centerNode.id).x = 0;
159
+ nodeMap.get(centerNode.id).y = 0;
160
+
161
+ const radius = 200;
162
+ const peripherals = nodes.slice(1);
163
+ peripherals.forEach((n, i) => {
164
+ const node = nodeMap.get(n.id);
165
+ const angle = (i / peripherals.length) * 2 * Math.PI;
166
+ node.x = radius * Math.cos(angle);
167
+ node.y = radius * Math.sin(angle);
168
+ });
169
+ }
170
+ }
171
+
172
+ return {
173
+ nodes: Array.from(nodeMap.values()),
174
+ edges: edges
175
+ };
176
+ }
@@ -658,7 +658,7 @@ div.tooltip {
658
658
  width: 100%;
659
659
  height: 100%;
660
660
  background: rgba(0, 0, 0, 0.6);
661
- z-index: 1500;
661
+ z-index: 2500; /* Must be higher than path-container (2000) */
662
662
  display: flex;
663
663
  justify-content: center;
664
664
  align-items: center;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noteconnection",
3
- "version": "1.1.2",
3
+ "version": "1.3.0",
4
4
  "description": "Hierarchical Knowledge Graph Visualization System",
5
5
  "main": "dist/src/electron/main.js",
6
6
  "bin": {
@@ -13,8 +13,10 @@
13
13
  "electron:dev:mini": "npm run build:mini && electron .",
14
14
  "electron:build": "npm run build && electron-builder",
15
15
  "electron:build:mini": "npm run build:mini && electron-builder",
16
- "build": "tsc && node scripts/copy-assets.js",
16
+ "build": "tsc && node scripts/copy-assets.js && node scripts/bundle_path_core.js",
17
17
  "build:mini": "tsc && node scripts/copy-assets.js --mini",
18
+ "pathmode:dev": "node -r ts-node/register src/server.ts --pathmode",
19
+ "pathmode:test": "jest --testPathPatterns=Path",
18
20
  "prepublishOnly": "npm run build",
19
21
  "test": "jest"
20
22
  },
@@ -60,8 +62,10 @@
60
62
  "@capacitor/cli": "^8.0.0",
61
63
  "@capacitor/core": "^8.0.0",
62
64
  "@types/d3-force": "^3.0.10",
65
+ "@types/ws": "^8.18.1",
63
66
  "d3-force": "^3.0.0",
64
67
  "electron-squirrel-startup": "^1.0.1",
65
- "tslib": "^2.8.1"
68
+ "tslib": "^2.8.1",
69
+ "ws": "^8.19.0"
66
70
  }
67
71
  }