@nwire/scan 0.12.0 → 0.13.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/ast-extract.d.ts +71 -0
- package/dist/ast-extract.js +1024 -0
- package/dist/graph.d.ts +56 -0
- package/dist/graph.js +325 -0
- package/dist/manifest.d.ts +67 -0
- package/dist/manifest.js +103 -0
- package/dist/scan.d.ts +46 -108
- package/dist/scan.js +13 -381
- package/dist/telemetry-runs.d.ts +37 -0
- package/dist/telemetry-runs.js +87 -0
- package/dist/topology.d.ts +10 -0
- package/dist/topology.js +10 -0
- package/dist/vite-plugin.d.ts +14 -6
- package/dist/vite-plugin.js +27 -12
- package/package.json +8 -6
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Disk readers for past telemetry runs — the `.nwire/telemetry/*.jsonl` files
|
|
3
|
+
* the telemetry reporter writes per run.
|
|
4
|
+
*
|
|
5
|
+
* These live in `@nwire/scan` because both Studio (the standalone Vite
|
|
6
|
+
* middleware) and the `nwire` CLI's one-Vite dev host need to serve telemetry
|
|
7
|
+
* history off disk, and both already depend on `@nwire/scan`. Keeping the reader
|
|
8
|
+
* here avoids a UI-package → CLI import edge (the CLI must never depend on
|
|
9
|
+
* `@nwire/studio`) and avoids duplicating the parse/guard logic in two places.
|
|
10
|
+
*
|
|
11
|
+
* All functions are synchronous, side-effect-free beyond filesystem reads, and
|
|
12
|
+
* take an explicit project `cwd` so callers can target any root without touching
|
|
13
|
+
* process state.
|
|
14
|
+
*/
|
|
15
|
+
import { existsSync, readdirSync, readFileSync, statSync } from "node:fs";
|
|
16
|
+
import { resolve } from "node:path";
|
|
17
|
+
/**
|
|
18
|
+
* List `.nwire/telemetry/*.jsonl` files for a project, newest first.
|
|
19
|
+
*
|
|
20
|
+
* Entry ids are the bare filename minus the `.jsonl` extension. Run ids are
|
|
21
|
+
* ISO-timestamp-prefixed by the telemetry reporter, so lexical descending order
|
|
22
|
+
* is chronological descending order. Missing dir or unreadable entries degrade
|
|
23
|
+
* to an empty list rather than throwing.
|
|
24
|
+
*/
|
|
25
|
+
export function listTelemetryRuns(cwd) {
|
|
26
|
+
const dir = resolve(cwd, ".nwire", "telemetry");
|
|
27
|
+
if (!existsSync(dir))
|
|
28
|
+
return [];
|
|
29
|
+
let names;
|
|
30
|
+
try {
|
|
31
|
+
names = readdirSync(dir);
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return [];
|
|
35
|
+
}
|
|
36
|
+
const runs = [];
|
|
37
|
+
for (const name of names) {
|
|
38
|
+
if (!name.endsWith(".jsonl"))
|
|
39
|
+
continue;
|
|
40
|
+
const file = resolve(dir, name);
|
|
41
|
+
try {
|
|
42
|
+
const st = statSync(file);
|
|
43
|
+
runs.push({ id: name.slice(0, -6), size: st.size, mtime: st.mtime.toISOString() });
|
|
44
|
+
}
|
|
45
|
+
catch {
|
|
46
|
+
// race: file vanished between readdir and stat — skip
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// Lexical descending = newest first (id starts with ISO timestamp).
|
|
50
|
+
runs.sort((a, b) => b.id.localeCompare(a.id));
|
|
51
|
+
return runs;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Read `.nwire/telemetry/<runId>.jsonl` and return each line parsed as JSON.
|
|
55
|
+
*
|
|
56
|
+
* Security: `runId` must not contain path separators or `..` — the function
|
|
57
|
+
* returns an empty array for any id that fails this check. Blank lines and lines
|
|
58
|
+
* that are not valid JSON are silently skipped.
|
|
59
|
+
*/
|
|
60
|
+
export function readTelemetryRun(cwd, runId) {
|
|
61
|
+
// Guard: never let runId escape the telemetry dir.
|
|
62
|
+
if (runId.includes("/") || runId.includes("\\") || runId.includes(".."))
|
|
63
|
+
return [];
|
|
64
|
+
const file = resolve(cwd, ".nwire", "telemetry", `${runId}.jsonl`);
|
|
65
|
+
if (!existsSync(file))
|
|
66
|
+
return [];
|
|
67
|
+
let text;
|
|
68
|
+
try {
|
|
69
|
+
text = readFileSync(file, "utf8");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return [];
|
|
73
|
+
}
|
|
74
|
+
const out = [];
|
|
75
|
+
for (const line of text.split(/\r?\n/)) {
|
|
76
|
+
const trimmed = line.trim();
|
|
77
|
+
if (!trimmed)
|
|
78
|
+
continue;
|
|
79
|
+
try {
|
|
80
|
+
out.push(JSON.parse(trimmed));
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
// unparseable line — skip
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
return out;
|
|
87
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Topology — re-exported from `@nwire/telemetry`.
|
|
3
|
+
*
|
|
4
|
+
* The live-runtime capture (`captureTopology`) and the `Topology` shape moved to
|
|
5
|
+
* `@nwire/telemetry` (a runtime lib) so a running app can self-emit its topology
|
|
6
|
+
* to `.nwire/topology.json` without the scanner. The scanner keeps this barrel
|
|
7
|
+
* so its instance-based manifest path and existing imports resolve unchanged;
|
|
8
|
+
* `buildManifest` folds the emitted file when no live instance is given.
|
|
9
|
+
*/
|
|
10
|
+
export { captureTopology, type Topology, type CapabilityInfo, type StageInfo, type PluginInfo, type BindingInfo, type HandlerInfo, type HookInfo, type ContributionInfo, type TriggerInfo, type AppInfo, type RouteInfo, } from "@nwire/telemetry";
|
package/dist/topology.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Topology — re-exported from `@nwire/telemetry`.
|
|
3
|
+
*
|
|
4
|
+
* The live-runtime capture (`captureTopology`) and the `Topology` shape moved to
|
|
5
|
+
* `@nwire/telemetry` (a runtime lib) so a running app can self-emit its topology
|
|
6
|
+
* to `.nwire/topology.json` without the scanner. The scanner keeps this barrel
|
|
7
|
+
* so its instance-based manifest path and existing imports resolve unchanged;
|
|
8
|
+
* `buildManifest` folds the emitted file when no live instance is given.
|
|
9
|
+
*/
|
|
10
|
+
export { captureTopology, } from "@nwire/telemetry";
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vite
|
|
2
|
+
* Vite/unplugin form — emit the build-time manifest.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* the
|
|
4
|
+
* On build start and on dev-server start (re-emitted as `.ts` source changes),
|
|
5
|
+
* walks the project's source tree with the AST extractor and writes
|
|
6
|
+
* `.nwire/manifest.json`. No app boot — "scan the graph, not the runtime."
|
|
7
|
+
* Serves the live manifest at `/__nwire/manifest` in dev.
|
|
6
8
|
*/
|
|
7
9
|
import type { Plugin } from "vite";
|
|
8
|
-
export interface
|
|
9
|
-
|
|
10
|
+
export interface NwireManifestPluginOptions {
|
|
11
|
+
/** Source root to scan. Defaults to the resolved Vite `config.root`. */
|
|
12
|
+
readonly root?: string;
|
|
13
|
+
/** App-name stamp on every manifest entry. */
|
|
14
|
+
readonly app?: string;
|
|
15
|
+
/** Output directory for `manifest.json`. Default `.nwire`. */
|
|
10
16
|
readonly outDir?: string;
|
|
11
17
|
}
|
|
12
|
-
export declare function
|
|
18
|
+
export declare function nwireManifestPlugin(options?: NwireManifestPluginOptions): Plugin;
|
|
19
|
+
/** @deprecated Use {@link nwireManifestPlugin}. Kept so existing imports resolve. */
|
|
20
|
+
export declare const nwireCachePlugin: typeof nwireManifestPlugin;
|
package/dist/vite-plugin.js
CHANGED
|
@@ -1,25 +1,40 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vite
|
|
2
|
+
* Vite/unplugin form — emit the build-time manifest.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
* the
|
|
4
|
+
* On build start and on dev-server start (re-emitted as `.ts` source changes),
|
|
5
|
+
* walks the project's source tree with the AST extractor and writes
|
|
6
|
+
* `.nwire/manifest.json`. No app boot — "scan the graph, not the runtime."
|
|
7
|
+
* Serves the live manifest at `/__nwire/manifest` in dev.
|
|
6
8
|
*/
|
|
7
|
-
import {
|
|
8
|
-
export function
|
|
9
|
+
import { buildManifest, writeManifest } from "./manifest.js";
|
|
10
|
+
export function nwireManifestPlugin(options = {}) {
|
|
9
11
|
const outDir = options.outDir ?? ".nwire";
|
|
12
|
+
let root = options.root ?? process.cwd();
|
|
10
13
|
return {
|
|
11
|
-
name: "nwire:
|
|
14
|
+
name: "nwire:manifest",
|
|
15
|
+
configResolved(config) {
|
|
16
|
+
if (!options.root && config.root)
|
|
17
|
+
root = config.root;
|
|
18
|
+
},
|
|
12
19
|
async buildStart() {
|
|
13
|
-
|
|
14
|
-
await writeCache(cache, outDir);
|
|
20
|
+
await writeManifest(buildManifest(root, options.app), outDir);
|
|
15
21
|
},
|
|
16
22
|
async configureServer(server) {
|
|
17
|
-
const
|
|
18
|
-
await
|
|
19
|
-
|
|
23
|
+
const emit = () => writeManifest(buildManifest(root, options.app), outDir);
|
|
24
|
+
await emit();
|
|
25
|
+
const onChange = (file) => {
|
|
26
|
+
if (file.endsWith(".ts") && !file.endsWith(".d.ts"))
|
|
27
|
+
void emit();
|
|
28
|
+
};
|
|
29
|
+
server.watcher.on("add", onChange);
|
|
30
|
+
server.watcher.on("change", onChange);
|
|
31
|
+
server.watcher.on("unlink", onChange);
|
|
32
|
+
server.middlewares.use("/__nwire/manifest", (_req, res) => {
|
|
20
33
|
res.setHeader("Content-Type", "application/json");
|
|
21
|
-
res.end(JSON.stringify(
|
|
34
|
+
res.end(JSON.stringify(buildManifest(root, options.app), null, 2));
|
|
22
35
|
});
|
|
23
36
|
},
|
|
24
37
|
};
|
|
25
38
|
}
|
|
39
|
+
/** @deprecated Use {@link nwireManifestPlugin}. Kept so existing imports resolve. */
|
|
40
|
+
export const nwireCachePlugin = nwireManifestPlugin;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nwire/scan",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Nwire — system registry scanner. Walks AppDefinition[] manifests and writes the .nwire/ cache (actions, events, actors, projections, queries,
|
|
3
|
+
"version": "0.13.0",
|
|
4
|
+
"description": "Nwire — system registry scanner. Walks AppDefinition[] manifests and writes the .nwire/ cache (actions, events, actors, projections, queries, routes, event graph). Vite plugin + standalone function.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cache",
|
|
7
7
|
"nwire",
|
|
@@ -32,17 +32,19 @@
|
|
|
32
32
|
"access": "public"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
+
"typescript": "^5.9.3",
|
|
35
36
|
"zod": "^4.4.3",
|
|
36
|
-
"@nwire/forge": "0.
|
|
37
|
-
"@nwire/messages": "0.
|
|
38
|
-
"@nwire/
|
|
37
|
+
"@nwire/forge": "0.13.0",
|
|
38
|
+
"@nwire/messages": "0.13.0",
|
|
39
|
+
"@nwire/telemetry": "0.13.0",
|
|
40
|
+
"@nwire/hooks": "0.13.0"
|
|
39
41
|
},
|
|
40
42
|
"devDependencies": {
|
|
41
43
|
"@types/node": "^22.19.9",
|
|
42
44
|
"typescript": "^5.9.3",
|
|
43
45
|
"vite": "npm:rolldown-vite@latest",
|
|
44
46
|
"vitest": "^4.0.18",
|
|
45
|
-
"@nwire/container": "0.
|
|
47
|
+
"@nwire/container": "0.13.0"
|
|
46
48
|
},
|
|
47
49
|
"scripts": {
|
|
48
50
|
"build": "tsc && node ../../scripts/fix-dist-extensions.mjs dist",
|