@@ -6,7 +6,7 @@ import * as path from 'path';
66import { existsSync } from 'fs' ;
77import * as PAT from './constants.js' ;
88import { getProjectRootPath } from '../../helpers/project.js' ;
9- import { isLikelyNativeScriptRuntimePluginSpecifier , isNativeScriptCoreModule , isNativeScriptPluginModule , normalizeNativeScriptCoreSpecifier , normalizeNodeModulesSpecifier , resolveNodeModulesPackageBoundary , resolveVendorFromCandidate , viteDepsPathToBareSpecifier } from './websocket-module-specifiers.js' ;
9+ import { decodeFlattenedId , isLikelyNativeScriptRuntimePluginSpecifier , isNativeScriptCoreModule , isNativeScriptPluginModule , normalizeNativeScriptCoreSpecifier , normalizeNodeModulesSpecifier , resolveNodeModulesPackageBoundary , resolveVendorFromCandidate , viteDepsPathToBareSpecifier } from './websocket-module-specifiers.js' ;
1010import { collectTopLevelImportRecords } from './websocket-served-module-helpers.js' ;
1111
1212// Bare specifiers and special skip patterns (virtual, data:, etc.)
@@ -17,6 +17,15 @@ const SKIP_PATTERNS = /^(?:data:|blob:|node:|virtual:|vite:|\0|\/@@?id|\/__vite|
1717// the console on every served module.
1818const warnedVendorMisses = new Set < string > ( ) ;
1919
20+ function packageIsInstalled ( packageName : string ) : boolean {
21+ if ( ! packageName ) return false ;
22+ try {
23+ return existsSync ( path . join ( getProjectRootPath ( ) , 'node_modules' , ...packageName . split ( '/' ) , 'package.json' ) ) ;
24+ } catch {
25+ return false ;
26+ }
27+ }
28+
2029/**
2130 * Vendor-manifest miss fallback — e.g. `emoji-regex`, a transitive dep of
2231 * @nativescript /core that is never part of the vendor bundle. Dropping the
@@ -32,26 +41,6 @@ const warnedVendorMisses = new Set<string>();
3241 * being committed; if nothing resolves, the first candidate is used anyway —
3342 * a loud 404 on device beats a silent undefined binding.
3443 */
35- function decodeFlattenedDepId ( flat : string ) : string {
36- // Reverse Vite's flattenId, which encodes '.' as '__' and '/' (and ':') as
37- // '_'. Split on the '__' (dot) boundaries first so a single '_' inside each
38- // segment becomes a '/', then rejoin the segments with '.'. This avoids any
39- // placeholder sentinel (a literal NUL would corrupt the served module).
40- return flat
41- . split ( '__' )
42- . map ( ( segment ) => segment . replace ( / _ / g, '/' ) )
43- . join ( '.' ) ;
44- }
45-
46- function packageIsInstalled ( packageName : string ) : boolean {
47- if ( ! packageName ) return false ;
48- try {
49- return existsSync ( path . join ( getProjectRootPath ( ) , 'node_modules' , ...packageName . split ( '/' ) , 'package.json' ) ) ;
50- } catch {
51- return false ;
52- }
53- }
54-
5544function bareSpecifierFromFlatDepPath ( depPath : string ) : string {
5645 const flat = depPath . split ( '?' ) [ 0 ] . replace ( / \. m ? j s $ / , '' ) ;
5746 // flattenId is lossy (names may contain '_'), so build candidates from the
@@ -64,7 +53,7 @@ function bareSpecifierFromFlatDepPath(depPath: string): string {
6453 const pushCandidate = ( c : string ) => {
6554 if ( c && ! candidates . includes ( c ) ) candidates . push ( c ) ;
6655 } ;
67- pushCandidate ( decodeFlattenedDepId ( flat ) ) ;
56+ pushCandidate ( decodeFlattenedId ( flat ) ) ;
6857 if ( flat . startsWith ( '@' ) ) {
6958 // Scope-only decode: just the first '_' is the scope separator.
7059 pushCandidate ( flat . replace ( '_' , '/' ) ) ;
0 commit comments