@nwire/scan 0.13.2 → 0.13.3
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 +3 -2
- package/dist/ast-extract.js +32 -0
- package/dist/graph.js +12 -0
- package/dist/manifest.d.ts +1 -1
- package/dist/manifest.js +1 -1
- package/dist/registry-codegen.d.ts +45 -0
- package/dist/registry-codegen.js +62 -0
- package/dist/scan.d.ts +16 -0
- package/dist/scan.js +1 -0
- package/dist/vite-plugin.d.ts +24 -5
- package/dist/vite-plugin.js +41 -5
- package/package.json +7 -6
package/dist/ast-extract.d.ts
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* workflows (including the workflow closure edge-walk and the projection /
|
|
13
13
|
* workflow event-graph edges).
|
|
14
14
|
*/
|
|
15
|
-
import type { ActionEntry, ActorEntry, CommandEntry, CronEntry, ErrorEntry, EventEntry, EventGraphEdge, ExternalCallEntry, InboundWebhookEntry, InboxEntry, OutboxEntry, ProjectionEntry, QueryEntry, ResourceEntry, SourceLocationEntry, WorkflowEntry } from "./scan.js";
|
|
15
|
+
import type { ActionEntry, ActorEntry, CommandEntry, CronEntry, ErrorEntry, EventEntry, EventGraphEdge, ExternalCallEntry, HandlerEntry, InboundWebhookEntry, InboxEntry, OutboxEntry, ProjectionEntry, QueryEntry, ResourceEntry, SourceLocationEntry, WorkflowEntry } from "./scan.js";
|
|
16
16
|
/** A `config/*.ts` module — its file and the top-level config field names it exposes. */
|
|
17
17
|
export interface ConfigModuleEntry {
|
|
18
18
|
readonly file: string;
|
|
@@ -27,13 +27,14 @@ export interface SchemaEntry {
|
|
|
27
27
|
readonly source?: SourceLocationEntry;
|
|
28
28
|
}
|
|
29
29
|
export interface UnanalyzableEntry {
|
|
30
|
-
readonly kind: "event" | "action" | "actor" | "projection" | "query" | "workflow" | "command" | "cron" | "externalCall" | "inboundWebhook" | "outbox" | "inbox" | "resource" | "error" | "schema";
|
|
30
|
+
readonly kind: "event" | "action" | "handler" | "actor" | "projection" | "query" | "workflow" | "command" | "cron" | "externalCall" | "inboundWebhook" | "outbox" | "inbox" | "resource" | "error" | "schema";
|
|
31
31
|
readonly reason: string;
|
|
32
32
|
readonly source: SourceLocationEntry;
|
|
33
33
|
}
|
|
34
34
|
export interface AstExtract {
|
|
35
35
|
readonly events: EventEntry[];
|
|
36
36
|
readonly actions: ActionEntry[];
|
|
37
|
+
readonly handlers: HandlerEntry[];
|
|
37
38
|
readonly actors: ActorEntry[];
|
|
38
39
|
readonly projections: ProjectionEntry[];
|
|
39
40
|
readonly queries: QueryEntry[];
|
package/dist/ast-extract.js
CHANGED
|
@@ -427,6 +427,7 @@ export function extractFromFiles(files, app = "") {
|
|
|
427
427
|
const parsed = parse(files);
|
|
428
428
|
const events = [];
|
|
429
429
|
const actions = [];
|
|
430
|
+
const handlers = [];
|
|
430
431
|
const actors = [];
|
|
431
432
|
const projections = [];
|
|
432
433
|
const queries = [];
|
|
@@ -659,6 +660,36 @@ export function extractFromFiles(files, app = "") {
|
|
|
659
660
|
});
|
|
660
661
|
});
|
|
661
662
|
}
|
|
663
|
+
// ── Pass 2b: handlers ──
|
|
664
|
+
// The transport-core primitive. Same name shape as actions (positional or
|
|
665
|
+
// `{ name }`); no emits/projection contract — just the request→response unit.
|
|
666
|
+
for (const { file, sf } of parsed) {
|
|
667
|
+
walk(sf, (node) => {
|
|
668
|
+
if (!isDefineCall(node, "defineHandler"))
|
|
669
|
+
return;
|
|
670
|
+
const src = sourceOf(node, sf, file);
|
|
671
|
+
const cfg = configObject(node);
|
|
672
|
+
const name = actionName(node, cfg);
|
|
673
|
+
if (!name) {
|
|
674
|
+
unanalyzable.push({
|
|
675
|
+
kind: "handler",
|
|
676
|
+
reason: "non-literal or missing handler name",
|
|
677
|
+
source: src,
|
|
678
|
+
});
|
|
679
|
+
return;
|
|
680
|
+
}
|
|
681
|
+
const handlerExpr = cfg ? prop(cfg, "handler") : undefined;
|
|
682
|
+
const calls = handlerExpr ? extractCalls(handlerExpr, externalCallNameByBinding) : [];
|
|
683
|
+
handlers.push({
|
|
684
|
+
name,
|
|
685
|
+
app,
|
|
686
|
+
public: isPublic(node),
|
|
687
|
+
description: cfg ? stringLiteral(prop(cfg, "description")) : undefined,
|
|
688
|
+
calls: calls.length ? calls : undefined,
|
|
689
|
+
source: src,
|
|
690
|
+
});
|
|
691
|
+
});
|
|
692
|
+
}
|
|
662
693
|
// ── Pass 3: projections ──
|
|
663
694
|
// After events so `listens`/`on` refs resolve. Records the projection
|
|
664
695
|
// binding so queries (pass 5) can map a projection ref → its name.
|
|
@@ -982,6 +1013,7 @@ export function extractFromFiles(files, app = "") {
|
|
|
982
1013
|
return {
|
|
983
1014
|
events,
|
|
984
1015
|
actions,
|
|
1016
|
+
handlers,
|
|
985
1017
|
actors,
|
|
986
1018
|
projections,
|
|
987
1019
|
queries,
|
package/dist/graph.js
CHANGED
|
@@ -82,6 +82,15 @@ export function buildGraph(ast, topology) {
|
|
|
82
82
|
intent: { public: q.public },
|
|
83
83
|
data: { projection: q.projection },
|
|
84
84
|
});
|
|
85
|
+
for (const h of ast.handlers ?? [])
|
|
86
|
+
add({
|
|
87
|
+
id: nid("handler", h.name),
|
|
88
|
+
kind: "handler",
|
|
89
|
+
name: h.name,
|
|
90
|
+
source: h.source,
|
|
91
|
+
intent: { description: h.description, public: h.public },
|
|
92
|
+
data: { calls: h.calls },
|
|
93
|
+
});
|
|
85
94
|
// Shared state-machine emit: state nodes + `transitions` edges (on event).
|
|
86
95
|
// `from: "*"` (always-active) is rooted at the machine node itself.
|
|
87
96
|
const emitStates = (machineKind, machineName, declaredStates, transitions) => {
|
|
@@ -180,6 +189,9 @@ export function buildGraph(ast, topology) {
|
|
|
180
189
|
for (const c of a.calls ?? [])
|
|
181
190
|
edge(nid("action", a.name), nid("externalCall", c), "calls");
|
|
182
191
|
}
|
|
192
|
+
for (const h of ast.handlers ?? [])
|
|
193
|
+
for (const c of h.calls ?? [])
|
|
194
|
+
edge(nid("handler", h.name), nid("externalCall", c), "calls");
|
|
183
195
|
for (const ed of ast.graph.events) {
|
|
184
196
|
switch (ed.via) {
|
|
185
197
|
case "emits":
|
package/dist/manifest.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ import { type AstExtract } from "./ast-extract.js";
|
|
|
16
16
|
import { type Topology } from "./topology.js";
|
|
17
17
|
import { type ManifestModel } from "./graph.js";
|
|
18
18
|
/** Bumped when the manifest shape changes, so readers can detect a stale file. */
|
|
19
|
-
export declare const MANIFEST_VERSION:
|
|
19
|
+
export declare const MANIFEST_VERSION: 4;
|
|
20
20
|
/**
|
|
21
21
|
* The project manifest — the static AST graph (events/actions/queries/actors/
|
|
22
22
|
* workflows/projections + positions + event-causation edges) plus, when built
|
package/dist/manifest.js
CHANGED
|
@@ -19,7 +19,7 @@ import { extractFromFiles } from "./ast-extract.js";
|
|
|
19
19
|
import { captureTopology } from "./topology.js";
|
|
20
20
|
import { buildGraph } from "./graph.js";
|
|
21
21
|
/** Bumped when the manifest shape changes, so readers can detect a stale file. */
|
|
22
|
-
export const MANIFEST_VERSION =
|
|
22
|
+
export const MANIFEST_VERSION = 4;
|
|
23
23
|
const SKIP_DIRS = new Set(["node_modules", "dist", ".nwire", ".git", ".vitepress", "__tests__"]);
|
|
24
24
|
/**
|
|
25
25
|
* Recursively collect non-test `.ts` source files under `root` — the input to
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time registry codegen — the production half of auto-discovery.
|
|
3
|
+
*
|
|
4
|
+
* At runtime, `@nwire/app`'s `discoverPrimitives` walks `app/` with `node:fs`
|
|
5
|
+
* and dynamic `import()`. That's perfect for dev/test and Node production, but
|
|
6
|
+
* it costs a filesystem scan at every boot and doesn't work in a bundle (no
|
|
7
|
+
* `node:fs`, no dynamic dir import) — edge targets and single-file builds.
|
|
8
|
+
*
|
|
9
|
+
* This module generates a *static* registry: a tiny ESM source that imports
|
|
10
|
+
* every app primitive with plain `import * as` statements and classifies the
|
|
11
|
+
* real exported values via `@nwire/app`'s `classifyModules`. A bundler folds
|
|
12
|
+
* those static imports into the output, so production boots with zero fs scan
|
|
13
|
+
* and zero dynamic import — and it works anywhere ESM does.
|
|
14
|
+
*
|
|
15
|
+
* Equivalence is structural, not asserted: the codegen reuses the same
|
|
16
|
+
* `collectFiles` (which files count) and the generated module calls the same
|
|
17
|
+
* `classifyModules` (how exports map to kinds) that the runtime scan uses.
|
|
18
|
+
* There is no second copy of the rules to drift.
|
|
19
|
+
*
|
|
20
|
+
* buildStart / load("virtual:nwire-registry")
|
|
21
|
+
* → generateRegistryModule(appDir)
|
|
22
|
+
* → import { classifyModules } from "@nwire/app"
|
|
23
|
+
* import * as _m0 from "/abs/app/create-item.action.ts"
|
|
24
|
+
* ...
|
|
25
|
+
* export const registry = classifyModules([_m0, ...])
|
|
26
|
+
*/
|
|
27
|
+
/** The virtual module specifier the runtime imports and the plugin resolves. */
|
|
28
|
+
export declare const REGISTRY_MODULE_ID = "virtual:nwire-registry";
|
|
29
|
+
export interface RegistryCodegenOptions {
|
|
30
|
+
/**
|
|
31
|
+
* Absolute path to the app source root to scan. Defaults to `<cwd>/app`.
|
|
32
|
+
* The same directory `createApp({ discover })` walks at runtime.
|
|
33
|
+
*/
|
|
34
|
+
readonly root?: string;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Generate the ESM source for the static registry module. Walks `root` for
|
|
38
|
+
* primitive files (using the runtime's own `collectFiles` rules) and emits a
|
|
39
|
+
* module that statically imports each and classifies them with the runtime's
|
|
40
|
+
* `classifyModules`.
|
|
41
|
+
*
|
|
42
|
+
* Returns a valid module even when no files are found — the registry is just
|
|
43
|
+
* empty, so `createApp` can fall through to whatever explicit arrays it has.
|
|
44
|
+
*/
|
|
45
|
+
export declare function generateRegistryModule(options?: RegistryCodegenOptions): string;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build-time registry codegen — the production half of auto-discovery.
|
|
3
|
+
*
|
|
4
|
+
* At runtime, `@nwire/app`'s `discoverPrimitives` walks `app/` with `node:fs`
|
|
5
|
+
* and dynamic `import()`. That's perfect for dev/test and Node production, but
|
|
6
|
+
* it costs a filesystem scan at every boot and doesn't work in a bundle (no
|
|
7
|
+
* `node:fs`, no dynamic dir import) — edge targets and single-file builds.
|
|
8
|
+
*
|
|
9
|
+
* This module generates a *static* registry: a tiny ESM source that imports
|
|
10
|
+
* every app primitive with plain `import * as` statements and classifies the
|
|
11
|
+
* real exported values via `@nwire/app`'s `classifyModules`. A bundler folds
|
|
12
|
+
* those static imports into the output, so production boots with zero fs scan
|
|
13
|
+
* and zero dynamic import — and it works anywhere ESM does.
|
|
14
|
+
*
|
|
15
|
+
* Equivalence is structural, not asserted: the codegen reuses the same
|
|
16
|
+
* `collectFiles` (which files count) and the generated module calls the same
|
|
17
|
+
* `classifyModules` (how exports map to kinds) that the runtime scan uses.
|
|
18
|
+
* There is no second copy of the rules to drift.
|
|
19
|
+
*
|
|
20
|
+
* buildStart / load("virtual:nwire-registry")
|
|
21
|
+
* → generateRegistryModule(appDir)
|
|
22
|
+
* → import { classifyModules } from "@nwire/app"
|
|
23
|
+
* import * as _m0 from "/abs/app/create-item.action.ts"
|
|
24
|
+
* ...
|
|
25
|
+
* export const registry = classifyModules([_m0, ...])
|
|
26
|
+
*/
|
|
27
|
+
import { collectFiles } from "@nwire/app";
|
|
28
|
+
/** The virtual module specifier the runtime imports and the plugin resolves. */
|
|
29
|
+
export const REGISTRY_MODULE_ID = "virtual:nwire-registry";
|
|
30
|
+
/** Normalize a filesystem path to a forward-slash import specifier. */
|
|
31
|
+
function toImportSpecifier(file) {
|
|
32
|
+
return file.replace(/\\/g, "/");
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Generate the ESM source for the static registry module. Walks `root` for
|
|
36
|
+
* primitive files (using the runtime's own `collectFiles` rules) and emits a
|
|
37
|
+
* module that statically imports each and classifies them with the runtime's
|
|
38
|
+
* `classifyModules`.
|
|
39
|
+
*
|
|
40
|
+
* Returns a valid module even when no files are found — the registry is just
|
|
41
|
+
* empty, so `createApp` can fall through to whatever explicit arrays it has.
|
|
42
|
+
*/
|
|
43
|
+
export function generateRegistryModule(options = {}) {
|
|
44
|
+
const root = options.root ?? `${process.cwd()}/app`;
|
|
45
|
+
const files = collectFiles(root).map(toImportSpecifier).sort();
|
|
46
|
+
const imports = files.map((f, i) => `import * as _m${i} from ${JSON.stringify(f)};`);
|
|
47
|
+
const list = files.map((_, i) => `_m${i}`).join(", ");
|
|
48
|
+
return [
|
|
49
|
+
"// AUTO-GENERATED by @nwire/scan registry codegen — do not edit.",
|
|
50
|
+
"// Statically imports every app primitive so production registers them",
|
|
51
|
+
"// with no filesystem scan and no dynamic import (bundle/edge-safe).",
|
|
52
|
+
'import { classifyModules } from "@nwire/app";',
|
|
53
|
+
...imports,
|
|
54
|
+
"",
|
|
55
|
+
`export const registry = classifyModules([${list}]);`,
|
|
56
|
+
"export const handlers = registry.handlers;",
|
|
57
|
+
"export const actors = registry.actors;",
|
|
58
|
+
"export const projections = registry.projections;",
|
|
59
|
+
"export const workflows = registry.workflows;",
|
|
60
|
+
"",
|
|
61
|
+
].join("\n");
|
|
62
|
+
}
|
package/dist/scan.d.ts
CHANGED
|
@@ -87,6 +87,21 @@ export interface CommandEntry {
|
|
|
87
87
|
readonly app: string;
|
|
88
88
|
readonly source?: SourceLocationEntry;
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* A `defineHandler(...)` — the transport-core primitive ("one handler, every
|
|
92
|
+
* transport"). Distinct from actions/queries: a handler has no projection
|
|
93
|
+
* backing and no event emission contract; it's the plain request→response unit
|
|
94
|
+
* any transport can dispatch.
|
|
95
|
+
*/
|
|
96
|
+
export interface HandlerEntry {
|
|
97
|
+
readonly name: string;
|
|
98
|
+
readonly app: string;
|
|
99
|
+
readonly public: boolean;
|
|
100
|
+
readonly description?: string;
|
|
101
|
+
/** External-call names invoked in the handler body. */
|
|
102
|
+
readonly calls?: readonly string[];
|
|
103
|
+
readonly source?: SourceLocationEntry;
|
|
104
|
+
}
|
|
90
105
|
export interface WorkflowEntry {
|
|
91
106
|
readonly name: string;
|
|
92
107
|
readonly app: string;
|
|
@@ -230,6 +245,7 @@ export interface EventGraphEdge {
|
|
|
230
245
|
}
|
|
231
246
|
export { buildManifest, writeManifest, readManifest, collectSourceFiles, MANIFEST_VERSION, type Manifest, } from "./manifest.js";
|
|
232
247
|
export { extractFromFiles, collectConfigModules, type AstExtract, type SchemaEntry, type ConfigModuleEntry as AstConfigModuleEntry, } from "./ast-extract.js";
|
|
248
|
+
export { generateRegistryModule, REGISTRY_MODULE_ID, type RegistryCodegenOptions, } from "./registry-codegen.js";
|
|
233
249
|
export { captureTopology, type Topology, type CapabilityInfo, type StageInfo, type PluginInfo, type BindingInfo, type HandlerInfo, type HookInfo, type ContributionInfo, type TriggerInfo, } from "./topology.js";
|
|
234
250
|
export { buildGraph, type ManifestModel, type GraphNode, type GraphEdge, type GraphIntent, type EdgeType, } from "./graph.js";
|
|
235
251
|
export { listTelemetryRuns, readTelemetryRun, type TelemetryRunMeta } from "./telemetry-runs.js";
|
package/dist/scan.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
// equivalence harness proves they match.
|
|
11
11
|
export { buildManifest, writeManifest, readManifest, collectSourceFiles, MANIFEST_VERSION, } from "./manifest.js";
|
|
12
12
|
export { extractFromFiles, collectConfigModules, } from "./ast-extract.js";
|
|
13
|
+
export { generateRegistryModule, REGISTRY_MODULE_ID, } from "./registry-codegen.js";
|
|
13
14
|
export { captureTopology, } from "./topology.js";
|
|
14
15
|
export { buildGraph, } from "./graph.js";
|
|
15
16
|
export { listTelemetryRuns, readTelemetryRun } from "./telemetry-runs.js";
|
package/dist/vite-plugin.d.ts
CHANGED
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vite/unplugin form —
|
|
2
|
+
* Vite/unplugin form — the build-side of nwire discovery. Two jobs:
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* 1. **Descriptive manifest** — on build/dev start (and on `.ts` change),
|
|
5
|
+
* walk the source tree with the AST extractor and write
|
|
6
|
+
* `.nwire/manifest.json` for Studio. No app boot — "scan the graph, not
|
|
7
|
+
* the runtime." Also served live at `/__nwire/manifest` in dev.
|
|
8
|
+
*
|
|
9
|
+
* 2. **Registry codegen** — resolve the `virtual:nwire-registry` module to a
|
|
10
|
+
* static-import registry of every `app/` primitive. `createApp({ discover })`
|
|
11
|
+
* imports this first, so a production bundle registers handlers/actors/etc.
|
|
12
|
+
* with zero filesystem scan and zero dynamic import (edge-safe). In dev/test
|
|
13
|
+
* without this plugin the import simply fails and `createApp` falls back to
|
|
14
|
+
* the runtime fs-scan — same result, slower path.
|
|
8
15
|
*/
|
|
9
16
|
import type { Plugin } from "vite";
|
|
10
17
|
export interface NwireManifestPluginOptions {
|
|
@@ -14,6 +21,18 @@ export interface NwireManifestPluginOptions {
|
|
|
14
21
|
readonly app?: string;
|
|
15
22
|
/** Output directory for `manifest.json`. Default `.nwire`. */
|
|
16
23
|
readonly outDir?: string;
|
|
24
|
+
/**
|
|
25
|
+
* App primitive root for registry codegen. Defaults to `<root>/app`. Set to
|
|
26
|
+
* `false` to disable codegen and only emit the descriptive manifest.
|
|
27
|
+
*/
|
|
28
|
+
readonly appDir?: string | false;
|
|
29
|
+
/**
|
|
30
|
+
* Emit + serve the descriptive `.nwire/manifest.json`. Default `true`. Set to
|
|
31
|
+
* `false` when a host already owns that pipeline (the `nwire dev` host runs
|
|
32
|
+
* its own richer scan with runtime fold) — the plugin then only resolves the
|
|
33
|
+
* `virtual:nwire-registry` module.
|
|
34
|
+
*/
|
|
35
|
+
readonly manifest?: boolean;
|
|
17
36
|
}
|
|
18
37
|
export declare function nwireManifestPlugin(options?: NwireManifestPluginOptions): Plugin;
|
|
19
38
|
/** @deprecated Use {@link nwireManifestPlugin}. Kept so existing imports resolve. */
|
package/dist/vite-plugin.js
CHANGED
|
@@ -1,25 +1,61 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Vite/unplugin form —
|
|
2
|
+
* Vite/unplugin form — the build-side of nwire discovery. Two jobs:
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
4
|
+
* 1. **Descriptive manifest** — on build/dev start (and on `.ts` change),
|
|
5
|
+
* walk the source tree with the AST extractor and write
|
|
6
|
+
* `.nwire/manifest.json` for Studio. No app boot — "scan the graph, not
|
|
7
|
+
* the runtime." Also served live at `/__nwire/manifest` in dev.
|
|
8
|
+
*
|
|
9
|
+
* 2. **Registry codegen** — resolve the `virtual:nwire-registry` module to a
|
|
10
|
+
* static-import registry of every `app/` primitive. `createApp({ discover })`
|
|
11
|
+
* imports this first, so a production bundle registers handlers/actors/etc.
|
|
12
|
+
* with zero filesystem scan and zero dynamic import (edge-safe). In dev/test
|
|
13
|
+
* without this plugin the import simply fails and `createApp` falls back to
|
|
14
|
+
* the runtime fs-scan — same result, slower path.
|
|
8
15
|
*/
|
|
9
16
|
import { buildManifest, writeManifest } from "./manifest.js";
|
|
17
|
+
import { generateRegistryModule, REGISTRY_MODULE_ID } from "./registry-codegen.js";
|
|
10
18
|
export function nwireManifestPlugin(options = {}) {
|
|
11
19
|
const outDir = options.outDir ?? ".nwire";
|
|
12
20
|
let root = options.root ?? process.cwd();
|
|
21
|
+
let isBuild = false;
|
|
22
|
+
// Rollup convention: prefix a resolved virtual id with `\0` so other plugins
|
|
23
|
+
// leave it alone and it never hits the filesystem resolver.
|
|
24
|
+
const resolvedRegistryId = `\0${REGISTRY_MODULE_ID}`;
|
|
25
|
+
const appDirFor = () => options.appDir || `${root}/app`;
|
|
13
26
|
return {
|
|
14
27
|
name: "nwire:manifest",
|
|
15
28
|
configResolved(config) {
|
|
16
29
|
if (!options.root && config.root)
|
|
17
30
|
root = config.root;
|
|
31
|
+
isBuild = config.command === "build";
|
|
32
|
+
},
|
|
33
|
+
// Always resolve the virtual id so the literal `import("virtual:nwire-registry")`
|
|
34
|
+
// in `@nwire/app` never hard-fails a Vite build or dev server.
|
|
35
|
+
resolveId(id) {
|
|
36
|
+
if (id === REGISTRY_MODULE_ID)
|
|
37
|
+
return resolvedRegistryId;
|
|
38
|
+
return null;
|
|
39
|
+
},
|
|
40
|
+
// Bake the static registry into production builds. In dev (serve) or when
|
|
41
|
+
// codegen is off, emit a null registry so `createApp` falls back to the
|
|
42
|
+
// runtime fs-scan — fresh on every change, HMR-friendly.
|
|
43
|
+
load(id) {
|
|
44
|
+
if (id !== resolvedRegistryId)
|
|
45
|
+
return null;
|
|
46
|
+
if (isBuild && options.appDir !== false) {
|
|
47
|
+
return generateRegistryModule({ root: appDirFor() });
|
|
48
|
+
}
|
|
49
|
+
return "export const registry = null;\n";
|
|
18
50
|
},
|
|
19
51
|
async buildStart() {
|
|
52
|
+
if (options.manifest === false)
|
|
53
|
+
return;
|
|
20
54
|
await writeManifest(buildManifest(root, options.app), outDir);
|
|
21
55
|
},
|
|
22
56
|
async configureServer(server) {
|
|
57
|
+
if (options.manifest === false)
|
|
58
|
+
return;
|
|
23
59
|
const emit = () => writeManifest(buildManifest(root, options.app), outDir);
|
|
24
60
|
await emit();
|
|
25
61
|
const onChange = (file) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nwire/scan",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.3",
|
|
4
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",
|
|
@@ -34,17 +34,18 @@
|
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"typescript": "^5.9.3",
|
|
36
36
|
"zod": "^4.4.3",
|
|
37
|
-
"@nwire/
|
|
38
|
-
"@nwire/
|
|
39
|
-
"@nwire/
|
|
40
|
-
"@nwire/
|
|
37
|
+
"@nwire/app": "0.13.3",
|
|
38
|
+
"@nwire/forge": "0.13.3",
|
|
39
|
+
"@nwire/messages": "0.13.3",
|
|
40
|
+
"@nwire/telemetry": "0.13.3",
|
|
41
|
+
"@nwire/hooks": "0.13.3"
|
|
41
42
|
},
|
|
42
43
|
"devDependencies": {
|
|
43
44
|
"@types/node": "^22.19.9",
|
|
44
45
|
"typescript": "^5.9.3",
|
|
45
46
|
"vite": "npm:rolldown-vite@latest",
|
|
46
47
|
"vitest": "^4.0.18",
|
|
47
|
-
"@nwire/container": "0.13.
|
|
48
|
+
"@nwire/container": "0.13.3"
|
|
48
49
|
},
|
|
49
50
|
"scripts": {
|
|
50
51
|
"build": "tsc && node ../../scripts/fix-dist-extensions.mjs dist",
|