@ng-annotate/vite-plugin 0.3.9 → 0.3.11

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.js CHANGED
@@ -1,11 +1,16 @@
1
1
  import { createWsHandler } from './ws-handler.js';
2
2
  import { createManifestPlugin } from './manifest.js';
3
+ import { setProjectRoot, getStorePath } from './store.js';
3
4
  // Default export for Angular's angular.json `plugins` option — Angular calls it as a function.
4
5
  export default ngAnnotateMcp;
5
6
  export function ngAnnotateMcp() {
6
7
  const mainPlugin = {
7
8
  name: 'ng-annotate-mcp',
8
9
  apply: 'serve',
10
+ configResolved(config) {
11
+ setProjectRoot(config.root);
12
+ config.logger.info(`[ng-annotate] store → ${getStorePath()}`);
13
+ },
9
14
  configureServer(server) {
10
15
  createWsHandler(server);
11
16
  },
package/dist/store.d.ts CHANGED
@@ -29,7 +29,9 @@ export interface Annotation {
29
29
  selectionText?: string;
30
30
  }
31
31
  export declare const STORE_DIR = ".ng-annotate";
32
- export declare const STORE_PATH: string;
32
+ /** Call from the Vite `configResolved` hook to pin the store to the Vite project root. */
33
+ export declare function setProjectRoot(root: string): void;
34
+ export declare function getStorePath(): string;
33
35
  export declare function ensureStore(): void;
34
36
  type WatcherFn = (annotation: Annotation) => void;
35
37
  export declare function addWatcher(fn: WatcherFn): () => void;
package/dist/store.js CHANGED
@@ -4,15 +4,21 @@ import { v4 as uuidv4 } from 'uuid';
4
4
  const EMPTY_STORE = { sessions: {}, annotations: {} };
5
5
  // ─── File paths ───────────────────────────────────────────────────────────────
6
6
  export const STORE_DIR = '.ng-annotate';
7
- const PROJECT_ROOT = process.env.NG_ANNOTATE_PROJECT_ROOT ?? process.cwd();
8
- export const STORE_PATH = path.join(PROJECT_ROOT, STORE_DIR, 'store.json');
7
+ let projectRoot = process.env.NG_ANNOTATE_PROJECT_ROOT ?? process.cwd();
8
+ /** Call from the Vite `configResolved` hook to pin the store to the Vite project root. */
9
+ export function setProjectRoot(root) {
10
+ projectRoot = root;
11
+ }
12
+ export function getStorePath() {
13
+ return path.join(projectRoot, STORE_DIR, 'store.json');
14
+ }
9
15
  // ─── Store init ───────────────────────────────────────────────────────────────
10
16
  export function ensureStore() {
11
- const dir = path.join(PROJECT_ROOT, STORE_DIR);
17
+ const dir = path.join(projectRoot, STORE_DIR);
12
18
  if (!fs.existsSync(dir))
13
19
  fs.mkdirSync(dir, { recursive: true });
14
- if (!fs.existsSync(STORE_PATH)) {
15
- fs.writeFileSync(STORE_PATH, JSON.stringify(EMPTY_STORE, null, 2), 'utf8');
20
+ if (!fs.existsSync(getStorePath())) {
21
+ fs.writeFileSync(getStorePath(), JSON.stringify(EMPTY_STORE, null, 2), 'utf8');
16
22
  }
17
23
  }
18
24
  // ─── File locking ─────────────────────────────────────────────────────────────
@@ -25,10 +31,10 @@ let writeQueue = Promise.resolve();
25
31
  async function withLock(fn) {
26
32
  ensureStore();
27
33
  const result = writeQueue.then(async () => {
28
- const raw = fs.readFileSync(STORE_PATH, 'utf8');
34
+ const raw = fs.readFileSync(getStorePath(), 'utf8');
29
35
  const data = JSON.parse(raw);
30
36
  const updated = await fn(data);
31
- fs.writeFileSync(STORE_PATH, JSON.stringify(updated, null, 2), 'utf8');
37
+ fs.writeFileSync(getStorePath(), JSON.stringify(updated, null, 2), 'utf8');
32
38
  return updated;
33
39
  });
34
40
  // Keep the queue alive even when this task fails
@@ -38,7 +44,7 @@ async function withLock(fn) {
38
44
  }
39
45
  function readStore() {
40
46
  ensureStore();
41
- return JSON.parse(fs.readFileSync(STORE_PATH, 'utf8'));
47
+ return JSON.parse(fs.readFileSync(getStorePath(), 'utf8'));
42
48
  }
43
49
  const watchers = new Set();
44
50
  export function addWatcher(fn) {
@@ -22,10 +22,17 @@ export function createWsHandler(server) {
22
22
  wss.on('connection', (ws, req) => {
23
23
  void (async () => {
24
24
  const referer = req.headers.referer ?? req.headers.origin ?? '';
25
- const session = await store.createSession({ active: true, url: referer });
26
- const sessionId = session.id;
27
- safeSend(ws, { type: 'session:created', session });
28
- sessionSockets.set(sessionId, ws);
25
+ let sessionId;
26
+ try {
27
+ const session = await store.createSession({ active: true, url: referer });
28
+ sessionId = session.id;
29
+ safeSend(ws, { type: 'session:created', session });
30
+ sessionSockets.set(sessionId, ws);
31
+ }
32
+ catch (err) {
33
+ server.config.logger.error(`[ng-annotate] Failed to create session: ${String(err)}`);
34
+ return;
35
+ }
29
36
  ws.on('message', (raw) => {
30
37
  void (async () => {
31
38
  let msg;
@@ -35,25 +42,28 @@ export function createWsHandler(server) {
35
42
  catch {
36
43
  return;
37
44
  }
38
- if (msg.type === 'annotation:create') {
39
- const annotation = await store.createAnnotation({
40
- ...msg.payload,
41
- sessionId,
42
- });
43
- safeSend(ws, { type: 'annotation:created', annotation });
44
- }
45
- else if (msg.type === 'annotation:reply') {
46
- const annotation = await store.addReply(msg.id, { author: 'user', message: msg.message });
47
- if (annotation) {
48
- safeSend(ws, { type: 'annotation:updated', annotation });
45
+ try {
46
+ if (msg.type === 'annotation:create') {
47
+ const annotation = await store.createAnnotation({
48
+ ...msg.payload,
49
+ sessionId,
50
+ });
51
+ safeSend(ws, { type: 'annotation:created', annotation });
49
52
  }
50
- }
51
- else {
52
- const annotation = await store.updateAnnotation(msg.id, { status: 'dismissed' });
53
- if (annotation) {
54
- safeSend(ws, { type: 'annotation:updated', annotation });
53
+ else if (msg.type === 'annotation:reply') {
54
+ const annotation = await store.addReply(msg.id, { author: 'user', message: msg.message });
55
+ if (annotation)
56
+ safeSend(ws, { type: 'annotation:updated', annotation });
57
+ }
58
+ else {
59
+ const annotation = await store.updateAnnotation(msg.id, { status: 'dismissed' });
60
+ if (annotation)
61
+ safeSend(ws, { type: 'annotation:updated', annotation });
55
62
  }
56
63
  }
64
+ catch (err) {
65
+ server.config.logger.error(`[ng-annotate] Failed to process message: ${String(err)}`);
66
+ }
57
67
  })();
58
68
  });
59
69
  ws.on('close', () => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ng-annotate/vite-plugin",
3
- "version": "0.3.9",
3
+ "version": "0.3.11",
4
4
  "type": "module",
5
5
  "description": "Vite plugin for ng-annotate-mcp — WebSocket annotation bridge and component manifest for Angular dev tooling",
6
6
  "keywords": [