npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@jskit-ai/architecture-inspector

v0.1.13

Published

Static Vue architecture inspector for the portable architecture-inspection command contract.

Readme

Architecture Inspector

@jskit-ai/architecture-inspector/vue exports inspectVueArchitecture({ projectRoot, input, aliases, httpScope, apiBasePath, calls, apiPrefixAliases }) for finite static architecture inspection, and ships the jskit-inspect-vue command and the Vue Preview locator src/previewLocator.js. It is a plain tool package, not a JSKIT framework runtime package.

Architecture inspection

Imported assets remain file-import evidence. The Vue adapter parses only its supported JavaScript, TypeScript and Vue modules; binary images do not block route discovery. Asset-to-component transformations require their own adapter and remain explicitly unsupported here.

Run jskit-inspect-vue in the project directory. It reads one bounded JSON document from stdin and writes one genesis.architecture-observations.v1 JSON document to stdout. Errors use stderr and a failing exit status. It does not import application code, start a server, generate router declarations or retain a watcher. The package imports no consumer's code: the input contract is its own, and it writes the observation format its consumer defines, which it names only by schema id. The command runs the inspection in a child Node process whose old generation is bounded by the size of the declared scripts (192 MB plus 56 MB per MiB), so memory stays near what the inspection holds; a caller that starts Node with its own --max-old-space-size keeps that bound and runs in place.

Input supplies schema: "jskit.architecture-inspection-input.v1", indexed files: [{ path, hash }] and uiDiscovery.discoveries. Optional packages carry id, name, manifest, declarations, root, opaque and public entryPoints: [{ importPath, file }]; packageIdentity binds observations to the same inspected public boundaries. A package resolves for the files under each manifest that declares it (declarations: [{ manifest }], or its manifest when it has none), whatever the dependency kind, so the packages of a workspace resolve one another when each workspace manifest is declared. Paths are project-relative and hashes use sha256:<hex>. Only declared, hash-matching UTF-8 files are read; symlinks and files over 4 MiB are rejected. Optional stackHash and cacheDirectory serve the call cache below; other unknown fields are ignored.

Each discovery supplies id, adapter, surface, mode, registrations, pageRoots and componentRoots. Supported adapters are jskit, vue-registered-router and vue-filesystem-router.

  • Registered mode reads literal Vue Router createRouter({ routes }) declarations from the registration files. Static local arrays and literal child routes work.

  • Filesystem mode reads literal VueRouter(...) options from the registration files and uses Vue Router's own scanner with declarations and watchers disabled. Its actual routesFolder determines pages; a directory alone is not proof. Sibling routes are visited in fullPath order, so registration ids do not depend on filesystem scan order.

  • Template component uses come from actual referenced imports. Shared definitions retain their source identity. Unused imports create no composition relationship.

  • Imported external elements retain the declared package/import-path/symbol owner. Their implementation files are not read. Project-owned workspace exports can resolve to indexed source files.

  • Static imports from indexed JavaScript, TypeScript and Vue files also provide optional imports observations. The framework resolver owns declared aliases, root-relative paths and file resolution. Each record retains the source range, current input hashes, target file and imported names, including aliases, default, namespace * and type-only classification. These are import facts, not evidence of runtime calls. Coverage remains partial; namespace use does not establish which individual exports are consumed.

  • An HTTP scope names the application's operations and enables scoped literal fetch uses and the routes a defineFeature setup registers on its HTTP router. It is the root package.json name, or --http-scope shop when the operations should carry another name; without either, HTTP observations stay unconfigured. Use --alias @=src for declared project aliases.

  • router.register(method, path, options, handler) becomes an entry operation whose controller is the handler, when the router is http.router of the setup's destructured http dependency (or dependencies.http.router), used in the setup or passed to a project function that registers on the parameter receiving it. Such functions may be local or imported through named imports and re-exports, at most four calls deep. The method and path must be literals, local constants or template literals of them; a call of the kernel's resolveScopedApiBasePath with literal options stands for the path it returns. Anything else is reported as CONTROLLER_UNRESOLVED. --api-base-path /api prefixes these paths.

  • Actual CrudListScreen / CrudAddEditScreen uses whose bound screen comes from the matching JSKIT composable can connect to exported defineCrudFeature controller declarations. The resource must resolve through indexed imports and named re-exports to a literal defineCrudContract declaration with literal enabled operations, and a literal namespace or, without one, a table resource whose defineTableResource name is literal. Scope includes the explicit HTTP application identity, declared surface and API suffix; the key uses jskit.crud resource operations rather than claiming a fully expanded runtime URL. Custom clients, transport/resource overrides, dynamic operations and disabled routes do not create guessed links. This shows declared entry points; runtime provider activation is not proven. Each such entry operation carries the actionId its route runs, crud.<namespace>.<operation>. The declaration's custom actions (a literal object, bound locally or imported through named re-exports) that declare a literal route become http entry operations at the declaration's API base path (scope.routeBase and relativePath) plus the route's path, with the action's id, or crud.<namespace>.<name> without one. Other forms are reported as CRUD_ACTION_ROUTE_UNRESOLVED.

  • Routes registered through the kernel's createActionRouteScope become entry operations with their full path and, for actionRoute, their actionId. The scope options must be string literals or imported constant strings; each route's method, suffix and actionId must be literals, template literals or elements of an enclosing literal array's .map or for...of (at most 64). Anything else is reported as ACTION_ROUTE_UNRESOLVED or ACTION_ROUTE_SCOPE_UNBOUND, never guessed.

Function calls (--calls)

--calls (library option calls: true) adds functions, calls and entryPoints and their capabilities. Without it the output is unchanged.

  • Functions. Every function-like with a body, plus each file's top-level code as fn:<path>#module. Other ids are fn:<path>#<line>:<column> at the syntax node's start after decorators, export and comments, the same position Genesis's syntax sites use. exported: true marks exported top-level functions; container names an enclosing class or object.
  • Calls. One TypeScript program over the declared scripts and Vue script blocks only, plus TypeScript's own libraries; nothing under node_modules is loaded. Each call is exact (checker, di-binding, self, route-action or single-valued argument-flow), probable (other argument-flow, receiver-name, or several candidates) or unresolved.
    • defineFeature injection binds requires tokens to the setup outputs that provides them: one provider is exact, several are ambiguous.
    • Argument flow follows the caller. A function passed to a parameter that the callee calls while it runs (in its own body, in callbacks it passes on, or by forwarding it to a function that does) is an argument-flow call of the function that passes it, recorded at that call. The callee's own call of the parameter is unresolved, so one caller's callback is never reached through another caller. A parameter called only from a closure the callee stores or returns keeps every value its callers pass. Argument flow is exact when it names one function for certain: a passed inline function or a name bound to one function, or a parameter (also a destructured factory parameter such as createActions({ sessions })) that receives one value across all the project's calls, when that value resolves exactly. Several values stay probable.
    • JSDoc types are declared types: @param, @type, @typedef and import("...") types, including a package's ./server/types reached through its declared entry points. A call through a parameter or binding typed that way is a checker call. A member a type declares as typeof a function ({ run: typeof run }, @property {typeof run} run) is that function.
    • Action definitions ({ id, execute } in a feature's actions, also through create*Actions factories, pass-through wrappers and literal-array .map, with ids that are literals or module constants) and the custom actions of a CRUD declaration become action entry points; request.executeAction({ actionId: "..." }) reaches their execute function, and the controllerFunctionId of each entry operation that names an action is that function.
    • Calls that are provably external are left out: package imports, builtins, values produced by them (including let assignments, for...of, destructuring and callbacks they call), Vue's <script setup> macros and emit.
    • A method call on an untyped receiver (receiver-name) reaches a project function only when exactly one function on that side declares the name (or exactly one in a file the receiver names) and no builtin member has it: the members of TypeScript's libraries and of Node's EventEmitter, fs.Stats and streams. Otherwise it is unresolved, and a builtin name no project function declares is left out.
    • At most 2,000 call records per file; beyond that CALLS_TRUNCATED and a partial calls capability.
  • Transports. With an HTTP scope, useEndpointResource, useCommand, getHttpWebClient().request and client fetch become operation uses that carry fromFunctionId; parentId is set only in page and component files. Paths are partially evaluated (template literals, constants, imports, parameter defaults, usePaths().api, resolveScopedApiBasePath). A key is keyCertainty: "exact" when every route literal is matched; two or three candidate routes give one probable use each, with ids suffixed per candidate. --api-prefix-alias /api/x=/api/app/:slug/x (repeatable) rewrites client prefixes before matching.
  • Cache. With an absolute, existing cacheDirectory outside the project, the command keeps jskit-calls.json there. An unchanged rerun reuses the whole result. Otherwise a file keeps its calls when its own and its directly imported sources are unchanged and every target still exists. Calls that injection or argument flow resolve depend on other files' arguments, so they are resolved again on every run; a file whose such calls now reach other functions is resolved again, with every reused file whose calls reach it. Any change to a manifest, lockfile, tsconfig/jsconfig, the inspector's own manifest or source (even without a version bump), packages, UI discovery, options or stackHash rebuilds everything. An absent, unusable or corrupt cache means a cold run.

Preview locator

src/previewLocator.js is a classic script a Preview can inline. It defines globalThis.__jskitLocateElement(element), which returns { file, name? } for the nearest component with a source file (Vue development builds record it as __file) that rendered the element, or null for plain DOM. It reads only Vue's component bookkeeping, never text content or values.

Dynamic routing, template component tokens, runtime placement predicates, application request wrappers and dispatcher conventions require more evidence or an application-owned inspector. They remain partial or unsupported, never guessed. This command does not claim complete runtime call analysis. Protocols other than HTTP can use the same observation contract through their own inspector.

Example consumer-owned Stack operation:


### Inspector `vue`: Inspect Vue pages and function calls

- Runtime: `nodejs`
- Directory: `.`
- Command: `node` `node_modules/@jskit-ai/architecture-inspector/src/cli.js` `--alias` `@=src` `--calls`
- Timeout seconds: `90`
- Max output bytes: `67108864`
- Preview locator: `node_modules/@jskit-ai/architecture-inspector/src/previewLocator.js`

The consumer owns command admission, runtime selection, cancellation, publication and validation against the indexed snapshot. It must retain the last valid snapshot when an inspector fails or source changes.