(spec: string)
| 163 | } |
| 164 | |
| 165 | export async function requestModuleFromServer(spec: string): Promise<string> { |
| 166 | const isSfcArtifact = (s: string) => /(?:^|\/)sfc-[a-f0-9]{8}\.mjs$/i.test(s) || /\/_ns_hmr\/src\/sfc\//.test(s) || /__NSDOC__\/_ns_hmr\/src\/sfc\//.test(s); |
| 167 | // Ignore Vite/virtual helper or empty specs |
| 168 | if (/^\/?\0/.test(spec) || /plugin-vue:export-helper/.test(spec)) { |
| 169 | if (__NS_ENV_VERBOSE__) console.log('[hmr-fetch] skipping virtual helper', spec); |
| 170 | return Promise.reject(new Error('virtual-helper-skip')); |
| 171 | } |
| 172 | // Short-circuit device artifact paths (SFC compiled files) – never ask the server for these |
| 173 | try { |
| 174 | if (isSfcArtifact(spec)) { |
| 175 | return Promise.reject(new Error('artifact-path-disallowed')); |
| 176 | } |
| 177 | } catch {} |
| 178 | // Special-case JSON package metadata requests at project root ONLY: some modules reference '/package.json' during dev. |
| 179 | // Intentionally narrow match to '/package.json' to avoid intercepting relative imports that should be inlined. |
| 180 | if (/^\/?package\.json(?:\/index)?$/.test(spec)) { |
| 181 | // Let the server send the JSON-wrapped ESM code; we will write it as-is. |
| 182 | // We still go through the normal request flow below, but short-circuit index heuristics. |
| 183 | } |
| 184 | // Cache hit: return immediately |
| 185 | if (moduleFetchCache.has(spec)) { |
| 186 | if (__NS_ENV_VERBOSE__) console.log('[hmr-fetch] cache hit', spec); |
| 187 | return Promise.resolve(moduleFetchCache.get(spec)!); |
| 188 | } |
| 189 | // Construct HTTP ESM URL for this spec and cache it |
| 190 | const origin = httpOriginForVite || deriveHttpOrigin(hmrWsUrl); |
| 191 | if (!origin) return Promise.reject(new Error('no-http-origin')); |
| 192 | const url = origin + '/ns/m' + (spec.startsWith('/') ? spec : '/' + spec); |
| 193 | if (__NS_ENV_VERBOSE__) console.log('[hmr-fetch] resolved', spec, '→', url); |
| 194 | moduleFetchCache.set(spec, url); |
| 195 | return Promise.resolve(url); |
| 196 | } |
| 197 | |
| 198 | // Centralized safe dynamic import wrapper to guard anomalous specifiers |
| 199 | export async function safeDynImport(spec: string): Promise<any> { |
no test coverage detected