Updated constitution.md to reflect the new loading pattern for global variables:
Version: 1.19.0 → 1.20.0 (MINOR)
Changes documented:
1. Section I.II: Updated googleDriveAdapterHelper.js pattern
- Files contain LITERAL BODY of a function
- Use bare 'return {...}' statement (NOT valid standalone JS)
- server.js wraps code in IIFE: (function() { <code> })()
- Clear separation: file = content, server = wrapper
2. Section I.V: Updated loadGlobalVariables() pattern
- Shows wrapping logic with code examples
- Explains IIFE creation and execution
- Documents context creation and object capture
3. Added comprehensive examples:
- Example file structure showing literal function body
- Example server.js wrapping logic with vm.Script
- Shows how return statement exports object
4. Version history updated:
- Documented architecture changes
- Explained rationale for pattern
- Listed benefits of approach
Key pattern documented:
✅ .js files in globalVariables/ contain function bodies with return
✅ Files are NOT valid standalone JavaScript (intentional)
✅ server.js wraps them: '(function() { <code> })()'
✅ Wrapping creates IIFE that executes and returns object
✅ Pattern applies to ALL .js files in globalVariables/
Benefits explained:
- Clear separation of content vs execution wrapper
- Explicit return statement documents exports
- Wrapping logic centralized in server.js
- Consistent pattern across all global variable functions
- Files clearly show their purpose (function bodies)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changed architecture so .js files contain literal function bodies
Changes to googleDriveAdapterHelper.js:
1. Changed from object literal (\({...}\)) to return statement (return {...})
2. File now contains LITERAL BODY of a function
3. Updated header comment to explain this pattern
4. File is NO LONGER valid standalone JavaScript (has bare return)
Changes to server.js loadGlobalVariables():
1. Wrap loaded code in function: `(function() { ${code} })()`
2. Creates IIFE that executes the function body
3. Captures returned object from the function
4. Pattern applies to ALL .js files in globalVariables/
Pattern:
```javascript
// File: googleDriveAdapterHelper.js (literal function body)
class DocumentCountExceededError extends Error {...}
function generateRequestId() {...}
return {
DocumentCountExceededError,
generateRequestId,
// ... all exports
};
```
```javascript
// server.js wraps it:
const wrappedCode = `(function() {
${code}
})()`;
const script = new vm.Script(wrappedCode, { filename: file });
const returnedObject = script.runInContext(context);
```
Benefits:
✅ Files represent pure function bodies
✅ Wrapping logic centralized in server.js
✅ Clear separation: content vs. execution wrapper
✅ Explicit return statement in function body
✅ Consistent pattern for all global variable functions
✅ Easy to understand: file = function body, server = wrapper
Testing:
✓ Server starts successfully
✓ Module loads: 'Loaded global functions: googleDriveAdapterHelper'
✓ Object captured: type=object, keys=11
✓ All functions accessible in VM context
✓ proxy.js can call googleDriveAdapterHelper.* functions
Note: googleDriveAdapterHelper.js will show syntax error if run standalone
(has bare return statement) - this is intentional, it's a function body!
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Enhanced logging to verify object capture from globalVariables/*.js files
Changes to server.js loadGlobalVariables():
1. Extract returnedObject explicitly before assignment
2. Add detailed logging showing:
- type: typeof the returned value
- isObject: boolean check if it's an object
- keys: number of properties in the object
Benefits:
✅ Verifies that vm.Script returns the object correctly
✅ Shows object has expected number of keys (11 functions)
✅ Confirms globalVariableContext[varName] receives the object
✅ Helpful for debugging module loading issues
✅ Makes the capture step more explicit and clear
Logging output shows:
"Loaded global functions: googleDriveAdapterHelper",
"type":"object",
"isObject":true,
"keys":11
This confirms the return object from googleDriveAdapterHelper.js
IS being added to globalVariableContext correctly!
Pattern verification:
- Line 60: const returnedObject = script.runInContext(context);
- Line 61: globalVariableContext[varName] = returnedObject;
- Result: globalVariableContext.googleDriveAdapterHelper = {11 functions}
Testing:
✓ Server starts successfully
✓ Module loads with correct object type
✓ All 11 functions captured
✓ Object available in VM context
✓ proxy.js can call googleDriveAdapterHelper.generateRequestId() etc.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Simplified to pure object literal expression
Rationale:
- User requested to forget about IIFE wrapper
- Simpler pattern: file evaluates directly to an object
- No function wrapper needed
- No return statement needed
- server.js already handles this correctly at line 59
Pattern:
```javascript
// Define functions at top level
class DocumentCountExceededError extends Error {...}
function generateRequestId() {...}
function parseRoute() {...}
// Final expression evaluates to object
({
DocumentCountExceededError,
generateRequestId,
parseRoute,
// ... all functions
});
```
How server.js handles it (already correct):
```javascript
const script = new vm.Script(code, { filename: file });
const context = vm.createContext({ ...globalVMContext, ...globalVariableContext });
globalVariableContext[varName] = script.runInContext(context);
// script.runInContext() returns the evaluated expression (the object)
```
Changes:
- Reverted from IIFE with return: (function() { return {...}; })()
- Back to object literal: ({...})
- Removed 2-space indentation throughout
- No function wrapper
- No return statement
Benefits:
✅ Simplest possible pattern
✅ Direct object evaluation
✅ No syntax complexity
✅ Server.js already handles it correctly
✅ Clean, minimal code
Testing:
✓ Syntax validated
✓ Server starts successfully
✓ Module loads: 'Loaded global functions: googleDriveAdapterHelper'
✓ All function calls work correctly
✓ Request handling functional
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reverted from object literal to function with return statement
Rationale:
- User requested explicit 'return' statement for clarity
- Function wrapper with 'return' is more conventional and readable
- Makes it clear the code returns an object when executed
- Matches common module pattern expectations
Structure:
```javascript
(function() {
// Define all classes and functions
class DocumentCountExceededError extends Error {...}
function generateRequestId() {...}
// ... all other functions
// Return object with all exports
return {
DocumentCountExceededError,
generateRequestId,
// ... all other functions
};
})();
```
Changes:
- Wrapped entire file in IIFE: (function() { ... })()
- Changed final expression from ({ ... }) to return { ... };
- Re-added 2-space indentation for content inside function
- Updated header comment: 'Returns' → 'Function that returns'
Benefits:
✅ Explicit return statement (clearer intent)
✅ Standard IIFE module pattern
✅ More conventional JavaScript style
✅ Easier to understand for new developers
✅ Same functionality as before
Testing:
✓ Syntax validated
✓ Server starts successfully
✓ Module loads: 'Loaded global functions: googleDriveAdapterHelper'
✓ All function calls work correctly
✓ Request handling functional
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changed from IIFE pattern to direct object literal evaluation
Rationale:
- Global variable functions should evaluate to an object directly
- IIFE wrapper was unnecessary complexity
- Simpler pattern: code evaluates to object, not function that returns object
- Matches intended architecture for vm.Script module loading
Changes:
1. Removed IIFE wrapper:
- Before: (function createHelpers() { ... return {...} })()
- After: ({ ... })
2. Removed function indentation (2 spaces throughout file)
3. Updated constitution.md:
- Pattern description: 'IIFE returning object' → 'evaluates to a single object'
- Clarified: 'not wrapped in IIFE'
- Updated all pattern references
Structure:
- File defines classes and functions at top level
- Final expression is object literal referencing all functions
- When executed via vm.Script, evaluates to the object
- Object is assigned to globalVariableContext.googleDriveAdapterHelper
Benefits:
✅ Simpler pattern (no function wrapper)
✅ Clearer intent (direct object evaluation)
✅ Matches architecture description
✅ Easier to understand and maintain
✅ Same functionality, cleaner implementation
Before (IIFE):
After (Object Literal):
Testing:
✓ Syntax validated
✓ Server starts successfully
✓ Module loads: 'Loaded global functions: googleDriveAdapterHelper'
✓ All function calls work correctly
✓ Request handling works as expected
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Reduced from 298 to 246 lines (52 lines saved, 17% reduction)
Rationale:
- Proxy.js receives only 1 request at a time per execution context
- Each request runs in isolated VM context via server.js
- FIFO queue was unnecessary complexity for single-request execution
- Node.js HTTP server already handles request queueing at TCP level
Changes:
- Removed: RequestQueue class (48 lines including getters)
- Removed: requestQueue singleton instance
- Removed: Queue wrapping in main handler
- Updated: Direct call to handleSitemapRequest()
- Updated: Section numbering (2→3, 3→4 removed)
- Updated: File header structure documentation
Benefits:
✅ Simpler code (17% reduction)
✅ Less cognitive overhead (no queue state to track)
✅ Faster execution (no queue overhead)
✅ Clearer intent (direct async call)
✅ Same functionality (still sequential per VM context)
Architecture Note:
- server.js creates fresh VM context per request
- Each proxy.js execution is inherently isolated
- No concurrent access possible within same context
- HTTP server manages request ordering at network layer
Testing:
✓ Syntax validated
✓ Server starts successfully
✓ Request handling works correctly
✓ No queue-related functionality needed
Progressive Simplification:
- Start: 752 lines (monolithic with utilities)
- After helper extraction: 493 lines (-35%)
- After moderate cleanup: 298 lines (-60%)
- After queue removal: 246 lines (-67% total)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Simplification:
- Combine loadGlobalObjects() + loadGlobalVariableFunctions() → loadGlobalVariables()
- Single function handles both .json and .js files
- Reduced from 258 to 234 lines (24 lines saved, ~9% reduction)
Benefits:
- Simpler API: One function instead of two
- Clearer intent: Load all global variables regardless of type
- Less duplication: Shared error handling and logging
- Better logging: Summary shows json: N, js: M breakdown
- Same behavior: JSON loaded first, then JS (maintains order)
Implementation:
- Filter for both .json and .js files in one pass
- Separate into jsonFiles and jsFiles arrays
- Process JSON files first (data)
- Process JS files second (can reference JSON data)
- Single summary log with breakdown: {json: 1, js: 1}
Changes:
- Renamed: loadGlobalObjects() → removed
- Renamed: loadGlobalVariableFunctions() → removed
- Added: loadGlobalVariables() - unified loader
- Updated: startServer() - single loader call
- Improved: Error messages now consistent ('Failed to load {file}')
- Improved: Log messages ('Loaded global data' vs 'Loaded global functions')
Testing:
- ✓ Syntax validated
- ✓ Both JSON and JS files load correctly
- ✓ Correct load order (JSON first, JS second)
- ✓ All 2 files loaded successfully
- ✓ helpers.generateRequestId() works
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Version: 1.17.0 → 1.18.0 (MINOR: Function loading pattern documentation)
Changes:
- Document loadGlobalVariableFunctions() generic pattern
- Update VM context injection code example
- Update helpers.js loading documentation
- Document tempContext with full globalVMContext + globalVariableContext
- Fix duplicate req entry and renumber to 11 and 12
Key Documentation Updates:
1. Section I.II - helpers.js Pattern:
- Loaded by loadGlobalVariableFunctions() which scans ALL .js files
- Filename determines key: helpers.js → globalVariableContext.helpers
- Executed in tempContext with full VM globals access
2. Section I.V - VM Context Injection Pattern:
- Replaced specific helpers loading code with generic pattern
- Documents loadGlobalVariableFunctions() scanning all .js files
- Shows tempContext creation with {...globalVMContext, ...globalVariableContext}
- Documents 4-step loading process with filename-to-key mapping
3. Section I.V - Helper Functions Module:
- Added Generic Loading Pattern section
- Documents full access to VM globals (axios, jwt, crypto, etc.)
- Documents access to previously loaded JSON data and functions
- Added note about extensibility (utils.js, validators.js, etc.)
Architecture Notes:
- Generic pattern: any .js file in globalVariables/ auto-loaded
- tempContext includes all dependencies from both contexts
- Function modules can access same globals as proxy.js
- Supports multiple function modules without code changes
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changes:
- Change tempContext from minimal {crypto, console: logger}
- Now uses {...globalVMContext, ...globalVariableContext}
- Provides function modules access to all VM globals
- Matches the context pattern used for proxy.js
Benefits:
- Function modules can access all dependencies (axios, jwt, etc.)
- Consistent with per-request context pattern
- Previously loaded JSON data available to function modules
- More flexible for complex function modules
Context now includes:
- From globalVMContext: URLSearchParams, URL, console, crypto, axios, uuidv4, jwt, xmlBuilder
- From globalVariableContext: Previously loaded JSON files and function modules
- Allows function modules to depend on other globals if needed
Testing:
- ✓ Syntax validated
- ✓ helpers.js loads correctly with full context
- ✓ helpers.generateRequestId() uses crypto from context
- ✓ All 11 exports available
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changes:
- Rename loadHelpers() → loadGlobalVariableFunctions()
- Match pattern of loadGlobalObjects() for consistency
- Load ALL .js files from globalVariables/ directory (not just helpers.js)
- Use filename as key in globalVariableContext (e.g., helpers.js → 'helpers')
- Generic implementation supports multiple function modules
Pattern:
- globalVariables/filename.js → globalVariableContext['filename']
- Each .js file must return an object via IIFE
- Files filtered: *.js (excluding *.example.js)
- Executed in temp context with crypto and console
Benefits:
- Consistent with loadGlobalObjects() pattern
- Generic: can add more function modules without code changes
- Filename determines the global variable name
- Clear separation: .json for data, .js for functions
Example:
- helpers.js → globalVariableContext.helpers
- utils.js → globalVariableContext.utils (future)
- validators.js → globalVariableContext.validators (future)
Testing:
- ✓ Syntax validated
- ✓ helpers.js loads correctly with 11 exports
- ✓ Available in context as 'helpers' object
- ✓ Pattern matches loadGlobalObjects() structure
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changes:
- Store helpers object in globalVariableContext.helpers
- Remove separate 'helpers' variable and helpersContext
- Helpers now spread into context via ...globalVariableContext
- Simplifies context injection - all globals in one place
Benefits:
- More consistent with JSON data loading pattern
- Single source of truth (globalVariableContext) for all VM globals
- Cleaner context creation (no separate helpers variable)
- helpers treated same as other global objects
Implementation:
- loadHelpers() now mutates globalVariableContext instead of returning
- Use tempContext for helpers execution (discarded after use)
- helpers accessible as 'helpers' in proxy.js via spread operator
Testing:
- ✓ Syntax validated
- ✓ helpers accessible in VM context
- ✓ Spread operator includes both JSON data and helpers
- ✓ All 11 helper functions available
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Changes:
- Add loadHelpers() function to load helpers.js via vm.Script
- Load helpers module at startup using same isolation pattern as proxy.js
- Inject helpers object into VM context for proxy.js access
- Update paths: global/ → globalVariables/, proxy.js → proxyScripts/proxy.js
- Create isolated context for helpers with crypto and console
Implementation:
- helpers.js loaded via vm.Script with isolated context
- helpers context includes crypto and console (logger)
- helpers object returned by IIFE execution
- Injected into per-request VM context alongside other globals
- Follows constitution pattern for vm.Script module loading
Testing:
- ✓ All JavaScript syntax validated
- ✓ Helpers module loads successfully
- ✓ All 11 expected functions present
- ✓ generateRequestId() returns valid format
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>