Class: Mbeditor::JsGlobalsService
- Inherits:
-
Object
- Object
- Mbeditor::JsGlobalsService
- Defined in:
- app/services/mbeditor/js_globals_service.rb
Overview
Enumerates every top-level JavaScript declaration in the workspace so the
editor can declare them as ambient globals in one shot. This models the
Sprockets concatenation world: files share one global script scope, so an
unindented var/function/class (or a window.X = assignment) in any
JS-family file is visible everywhere with no import statement.
Backed by CodeSearchService (rg > git grep > grep over JS_GLOBS, which includes *.js.jsx / *.js.erb), with a short cache invalidated whenever mbeditor mutates a file.
Constant Summary collapse
- MAX_SYMBOLS =
3000- CACHE_TTL =
seconds
30- PATTERN =
Column-0 anchored so only true top-level declarations match (Sprockets globals are by definition unindented); window assignments may be indented (IIFE bodies). BSD-grep-safe ERE: no \s, no non-greedy ops.
'^((var|let|const|function|class|async[ \t]+function)[ \t]+[A-Za-z_$][A-Za-z0-9_$]*' \ '|[ \t]*window\.[A-Za-z_$][A-Za-z0-9_$]*[ \t]*=)'
- IDENTIFIER =
/[A-Za-z_$][A-Za-z0-9_$]*/- MINIFIED_NAME =
Minified bundles are the reason for both guards below.
A minified file is one enormous line, and it usually opens with a multi-declarator
var a,b,c,d,…running to thousands of names. Split on commas, that ONE line yields thousands of one-letter symbols — enough to exhaust MAX_SYMBOLS on its own, so the workspace's actual components are never reached and every reference to them shows "Cannot find name". Worse, declaringa/n/tas ambientanysilences genuine diagnostics for those names everywhere.The name check catches the conventional cases; the line-length check catches bundles that don't say "min" in the filename. Neither is a judgement about vendored code in general — a normally-formatted vendor/assets library still contributes its globals, which is correct under Sprockets.
/[.\-]min\.(js|jsx|ts|tsx)\z/i- MAX_LINE_LENGTH =
2_000
Class Method Summary collapse
Class Method Details
.call(workspace_root) ⇒ Object
47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'app/services/mbeditor/js_globals_service.rb', line 47 def call(workspace_root) root = workspace_root.to_s now = monotonic MUTEX.synchronize do entry = (@cache ||= {})[root] return entry[:data] if entry && (now - entry[:ts]) < CACHE_TTL end data = compute(root) MUTEX.synchronize { (@cache ||= {})[root] = { ts: monotonic, data: data } } data end |
.invalidate(workspace_root) ⇒ Object
60 61 62 |
# File 'app/services/mbeditor/js_globals_service.rb', line 60 def invalidate(workspace_root) MUTEX.synchronize { (@cache ||= {}).delete(workspace_root.to_s) } end |