@sigloch/graph-view-edit 0.2.0 → 0.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.
package/dist/index.html CHANGED
@@ -4,7 +4,7 @@
4
4
  <meta charset="UTF-8" />
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <title>graph-view-edit</title>
7
- <script type="module" crossorigin src="/assets/index-2y8UZ103.js"></script>
7
+ <script type="module" crossorigin src="/assets/index-BCyeajKa.js"></script>
8
8
  <link rel="stylesheet" crossorigin href="/assets/index-P7N8B6D1.css">
9
9
  </head>
10
10
  <body>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sigloch/graph-view-edit",
3
- "version": "0.2.0",
3
+ "version": "0.3.0",
4
4
  "description": "React/Vite viewer+editor over @sigloch/graphcode — 12 graph-views + 16 doc-views via a declarative View-Registry, plus an SE-Dashboard sibling route. Reads docs/graph/<member>.graph.json client-side (no 2nd Kuzu handle).",
5
5
  "type": "module",
6
6
  "bin": {
package/src/config.mjs CHANGED
@@ -16,10 +16,46 @@
16
16
  *
17
17
  * @author andreas@siglochconsulting
18
18
  */
19
- import { existsSync, readFileSync } from 'node:fs';
19
+ import { existsSync, readFileSync, realpathSync } from 'node:fs';
20
20
  import { resolve } from 'node:path';
21
21
  import { z } from 'zod';
22
22
 
23
+ /** Fenster für abgeleitete Ports — registrierfrei und außerhalb der üblichen Dev-Ports. */
24
+ const PORT_BASE = 43000;
25
+ const PORT_SPAN = 1000;
26
+
27
+ /**
28
+ * Der stabile Port dieses Repos (CR-GVE-238).
29
+ *
30
+ * Vorher lag der Default bei 4317 — für JEDES Repo. Vite bumpt bei Belegung, also
31
+ * entschied die Startreihenfolge über die Adresse: derselbe Graph mal auf 4317, mal auf
32
+ * 4320, ein Lesezeichen also wertlos und eine geerbte Adresse im Zweifel die eines
33
+ * fremden Repos. Aus dem physischen Pfad abgeleitet ist die Adresse dagegen über
34
+ * Neustarts, Editor-Sessions und Reboots hinweg dieselbe.
35
+ *
36
+ * FNV-1a, weil hier nichts kryptografisch sein muss: gefordert ist Determinismus über
37
+ * Prozessgrenzen (`hashCode`-Streuung wäre genauso gut, aber node hat keine). realpath,
38
+ * damit ein Symlink-Start (/var vs. /private/var, ein Worktree über einen Link) nicht als
39
+ * anderes Repo zählt — dieselbe Regel wie bei der Identitätsprobe.
40
+ *
41
+ * Kollisionen sind möglich (1000 Fächer) und harmlos: Vite bumpt, die Identitätsprobe
42
+ * erkennt den fremden Viewer. Sie sind der Ausnahmefall, nicht mehr der Normalfall.
43
+ */
44
+ export function derivePort(repoRoot) {
45
+ let physical = repoRoot;
46
+ try {
47
+ physical = realpathSync(repoRoot);
48
+ } catch {
49
+ // Nicht auflösbar (Repo existiert nicht mehr) — der gegebene Pfad tut es auch.
50
+ }
51
+ let hash = 0x811c9dc5;
52
+ for (let i = 0; i < physical.length; i++) {
53
+ hash ^= physical.charCodeAt(i);
54
+ hash = Math.imul(hash, 0x01000193) >>> 0;
55
+ }
56
+ return PORT_BASE + (hash % PORT_SPAN);
57
+ }
58
+
23
59
  export const ConfigSchema = z.object({
24
60
  graph: z
25
61
  .object({
@@ -27,7 +63,10 @@ export const ConfigSchema = z.object({
27
63
  host: z.string().nullable().default(null),
28
64
  })
29
65
  .prefault({}),
30
- port: z.number().int().positive().default(4317),
66
+ // Kein fester Default mehr: fehlt das Feld, setzt loadConfig den aus dem Repo-Pfad
67
+ // abgeleiteten Port ein (CR-GVE-238). Der Schema-Wert greift nur, wenn jemand das
68
+ // Schema direkt parst — dort ist ein Repo-Bezug nicht bekannt.
69
+ port: z.number().int().positive().default(PORT_BASE),
31
70
  ontologyDescriptor: z.string().default('se'),
32
71
  tokenTheme: z.string().default('default'),
33
72
  viewRegistryDefaults: z
@@ -45,5 +84,11 @@ export const ConfigSchema = z.object({
45
84
 
46
85
  export function loadConfig(path = process.env.GVE_CONFIG_PATH || resolve(process.cwd(), 'config.json')) {
47
86
  const raw = existsSync(path) ? JSON.parse(readFileSync(path, 'utf8')) : {};
48
- return ConfigSchema.parse(raw);
87
+ const config = ConfigSchema.parse(raw);
88
+ // Explizit gesetzt gewinnt — sonst der stabile Port des bedienten Repos. `--port` auf
89
+ // der CLI schlägt beides, das regelt Vites eigene Präzedenz.
90
+ if (raw.port === undefined) {
91
+ config.port = derivePort(process.env.GVE_REPO_ROOT || process.cwd());
92
+ }
93
+ return config;
49
94
  }