Fix sudo handling for MySQL socket directory permissions in migrate commands
🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -86,7 +86,8 @@ class Migrate_Begin_Command extends Command
|
|||||||
|
|
||||||
// Step 4: Start MySQL again using supervisorctl
|
// Step 4: Start MySQL again using supervisorctl
|
||||||
$this->info('[4] Starting MySQL server...');
|
$this->info('[4] Starting MySQL server...');
|
||||||
$this->shell_exec_privileged('mkdir -p /var/run/mysqld && chmod 777 /var/run/mysqld');
|
$this->shell_exec_privileged('mkdir -p /var/run/mysqld');
|
||||||
|
$this->shell_exec_privileged('chmod 777 /var/run/mysqld');
|
||||||
$this->shell_exec_privileged('supervisorctl start mysql 2>&1');
|
$this->shell_exec_privileged('supervisorctl start mysql 2>&1');
|
||||||
|
|
||||||
// Step 5: Wait for MySQL to be ready
|
// Step 5: Wait for MySQL to be ready
|
||||||
|
|||||||
@@ -65,7 +65,8 @@ class Migrate_Rollback_Command extends Command
|
|||||||
|
|
||||||
// Step 5: Start MySQL using supervisorctl
|
// Step 5: Start MySQL using supervisorctl
|
||||||
$this->info('[5] Starting MySQL server...');
|
$this->info('[5] Starting MySQL server...');
|
||||||
$this->shell_exec_privileged('mkdir -p /var/run/mysqld && chmod 777 /var/run/mysqld');
|
$this->shell_exec_privileged('mkdir -p /var/run/mysqld');
|
||||||
|
$this->shell_exec_privileged('chmod 777 /var/run/mysqld');
|
||||||
$this->shell_exec_privileged('supervisorctl start mysql 2>&1');
|
$this->shell_exec_privileged('supervisorctl start mysql 2>&1');
|
||||||
|
|
||||||
// Step 6: Wait for MySQL to be ready
|
// Step 6: Wait for MySQL to be ready
|
||||||
|
|||||||
30
node_modules/.package-lock.json
generated
vendored
30
node_modules/.package-lock.json
generated
vendored
@@ -2211,9 +2211,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/core": {
|
"node_modules/@jqhtml/core": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/core/-/core-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/core/-/core-2.3.29.tgz",
|
||||||
"integrity": "sha512-jnm3GFudWzudwhlClcBNM2p1W74lSpnyqHp27riht+i25o5vHXEXC5/MC0RG/J7H1zcXIB67XTucC5mgfKt3TA==",
|
"integrity": "sha512-uMqxheBuB5r0nSXSFZaU4ad8z9wKDbzN4fD+FUxJPeoGAfCPdyuGWHHwlS+WyC+J7V42qhL2H28VLGmVutHi/g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||||
@@ -2237,9 +2237,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/parser": {
|
"node_modules/@jqhtml/parser": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/parser/-/parser-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/parser/-/parser-2.3.29.tgz",
|
||||||
"integrity": "sha512-Y9HyrCNJXkg3h3ILzSoWeHB53Fl8Q5hBrjdGeyg3eq4j7MFrD8iHBKChoaywzC1CuU00Ir6jsNlofXz9sOVuZQ==",
|
"integrity": "sha512-Ez0z11v8SCp6phJA2XAW+TBmGgYYDs88SeQd6YGX1ap8vCxF2MXe3A6ZlUHvOMiYNT1ONGR5zIcyIuNDJe5Mcg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/jest": "^29.5.11",
|
"@types/jest": "^29.5.11",
|
||||||
@@ -2277,9 +2277,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/ssr": {
|
"node_modules/@jqhtml/ssr": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/ssr/-/ssr-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/ssr/-/ssr-2.3.29.tgz",
|
||||||
"integrity": "sha512-MN98llN00aEgAizgMPVdCKlK964kxVig1kt5F2NTIjXH2FnsWxHQJJJyfbEAedRrvlLO1W9ciPD7mjP2iP2/og==",
|
"integrity": "sha512-IVuJNbwA9Ve/sw1KK+GBbK+4ahCkts+9ZLIdgOsYbU7owOIbxOJe1iZ2IBB4hV/I9M9c54Q8+rw4iD0E99P/nw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
@@ -2373,9 +2373,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/vscode-extension": {
|
"node_modules/@jqhtml/vscode-extension": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/vscode-extension/-/vscode-extension-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/vscode-extension/-/vscode-extension-2.3.29.tgz",
|
||||||
"integrity": "sha512-fY85EHAJclDkUX68hHd3q9hAC0Y/MwMYZgJnKOd2Js08tYD3OW7QD3zoOPR/dVhDKwEWfvXOKPDG5UO2ifTg5g==",
|
"integrity": "sha512-4ULz3axCs4ytYgtf5QpyfMBA4jLDujBibJ7mpRoyqXpuS9NsoTCsvPKdIc5F/Y3mJBFhRpsbPtiRDiiunM7XtQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.74.0"
|
"vscode": "^1.74.0"
|
||||||
@@ -12492,9 +12492,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.4",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz",
|
||||||
"integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
|
"integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
|
|||||||
41
node_modules/@jqhtml/core/dist/index.cjs
generated
vendored
41
node_modules/@jqhtml/core/dist/index.cjs
generated
vendored
@@ -4875,34 +4875,43 @@ function init_jquery_plugin(jQuery) {
|
|||||||
};
|
};
|
||||||
// Store original jQuery.fn.on
|
// Store original jQuery.fn.on
|
||||||
const originalOn = jQuery.fn.on;
|
const originalOn = jQuery.fn.on;
|
||||||
|
// Common jQuery DOM events - no warning for these
|
||||||
|
const COMMON_JQUERY_EVENTS = new Set([
|
||||||
|
'click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave',
|
||||||
|
'keydown', 'keyup', 'keypress',
|
||||||
|
'focus', 'blur', 'focusin', 'focusout',
|
||||||
|
'change', 'input', 'submit', 'reset', 'select',
|
||||||
|
'scroll', 'resize',
|
||||||
|
'load', 'unload', 'error',
|
||||||
|
'touchstart', 'touchend', 'touchmove', 'touchcancel',
|
||||||
|
'contextmenu', 'wheel',
|
||||||
|
'copy', 'cut', 'paste',
|
||||||
|
'drag', 'dragstart', 'dragend', 'dragenter', 'dragleave', 'dragover', 'drop'
|
||||||
|
]);
|
||||||
/**
|
/**
|
||||||
* Override jQuery.fn.on() to warn when attaching events to component root elements
|
* Override jQuery.fn.on() to warn when attaching non-DOM events to component root elements
|
||||||
*
|
*
|
||||||
* JQHTML components have their own .on() method for lifecycle events.
|
* JQHTML components have their own .on() method for lifecycle events (ready, create, render, etc).
|
||||||
* Attaching jQuery events to a component's root element usually indicates
|
* Attaching these via jQuery .on() to a component's root element usually indicates
|
||||||
* the developer meant to use component.on() instead.
|
* the developer meant to use component.on() instead.
|
||||||
*
|
*
|
||||||
* To suppress the warning, pass 'intentional' as any argument.
|
* Common jQuery DOM events (click, change, focus, etc.) do not trigger a warning.
|
||||||
*/
|
*/
|
||||||
jQuery.fn.on = function (...args) {
|
jQuery.fn.on = function (...args) {
|
||||||
// Check if 'intentional' flag is present in any argument
|
// Get event name (first argument)
|
||||||
const intentional = args.some(arg => arg === 'intentional');
|
const eventName = typeof args[0] === 'string' ? args[0].split('.')[0] : null; // Strip namespace
|
||||||
// Filter out 'intentional' from args before passing to original .on()
|
|
||||||
const cleanArgs = intentional ? args.filter(arg => arg !== 'intentional') : args;
|
|
||||||
// Check first element for Component class and warn if needed
|
// Check first element for Component class and warn if needed
|
||||||
if (!intentional && this.length > 0) {
|
if (eventName && !COMMON_JQUERY_EVENTS.has(eventName) && this.length > 0) {
|
||||||
const firstEl = this.first();
|
const firstEl = this.first();
|
||||||
if (firstEl.hasClass('Component')) {
|
if (firstEl.hasClass('Component')) {
|
||||||
const component = firstEl.data('_component');
|
const component = firstEl.data('_component');
|
||||||
const componentName = component?.component_name?.() || 'Component';
|
const componentName = component?.component_name?.() || 'Component';
|
||||||
console.warn(`[JQHTML] jQuery .on('${cleanArgs[0]}') called on <${componentName}> root element.\n` +
|
console.warn(`[JQHTML] jQuery .on('${args[0]}') called on <${componentName}> root element.\n` +
|
||||||
`You may have meant to use component.on() for lifecycle events, or attach to a child element.\n` +
|
`You may have meant to use component.on() for lifecycle events, or attach to a child element.`);
|
||||||
`If attaching jQuery events to the component root is intentional, pass 'intentional' as an argument:\n` +
|
|
||||||
` $(element).on('${cleanArgs[0]}', 'intentional', handler)`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call original .on() with cleaned arguments and return result
|
// Call original .on() with all arguments
|
||||||
return originalOn.apply(this, cleanArgs);
|
return originalOn.apply(this, args);
|
||||||
};
|
};
|
||||||
// Store original jQuery.fn.find
|
// Store original jQuery.fn.find
|
||||||
const originalFind = jQuery.fn.find;
|
const originalFind = jQuery.fn.find;
|
||||||
@@ -4957,7 +4966,7 @@ function init(jQuery) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Version - will be replaced during build with actual version from package.json
|
// Version - will be replaced during build with actual version from package.json
|
||||||
const version = '2.3.28';
|
const version = '2.3.29';
|
||||||
// Default export with all functionality
|
// Default export with all functionality
|
||||||
const jqhtml = {
|
const jqhtml = {
|
||||||
// Core
|
// Core
|
||||||
|
|||||||
2
node_modules/@jqhtml/core/dist/index.cjs.map
generated
vendored
2
node_modules/@jqhtml/core/dist/index.cjs.map
generated
vendored
File diff suppressed because one or more lines are too long
41
node_modules/@jqhtml/core/dist/index.js
generated
vendored
41
node_modules/@jqhtml/core/dist/index.js
generated
vendored
@@ -4871,34 +4871,43 @@ function init_jquery_plugin(jQuery) {
|
|||||||
};
|
};
|
||||||
// Store original jQuery.fn.on
|
// Store original jQuery.fn.on
|
||||||
const originalOn = jQuery.fn.on;
|
const originalOn = jQuery.fn.on;
|
||||||
|
// Common jQuery DOM events - no warning for these
|
||||||
|
const COMMON_JQUERY_EVENTS = new Set([
|
||||||
|
'click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave',
|
||||||
|
'keydown', 'keyup', 'keypress',
|
||||||
|
'focus', 'blur', 'focusin', 'focusout',
|
||||||
|
'change', 'input', 'submit', 'reset', 'select',
|
||||||
|
'scroll', 'resize',
|
||||||
|
'load', 'unload', 'error',
|
||||||
|
'touchstart', 'touchend', 'touchmove', 'touchcancel',
|
||||||
|
'contextmenu', 'wheel',
|
||||||
|
'copy', 'cut', 'paste',
|
||||||
|
'drag', 'dragstart', 'dragend', 'dragenter', 'dragleave', 'dragover', 'drop'
|
||||||
|
]);
|
||||||
/**
|
/**
|
||||||
* Override jQuery.fn.on() to warn when attaching events to component root elements
|
* Override jQuery.fn.on() to warn when attaching non-DOM events to component root elements
|
||||||
*
|
*
|
||||||
* JQHTML components have their own .on() method for lifecycle events.
|
* JQHTML components have their own .on() method for lifecycle events (ready, create, render, etc).
|
||||||
* Attaching jQuery events to a component's root element usually indicates
|
* Attaching these via jQuery .on() to a component's root element usually indicates
|
||||||
* the developer meant to use component.on() instead.
|
* the developer meant to use component.on() instead.
|
||||||
*
|
*
|
||||||
* To suppress the warning, pass 'intentional' as any argument.
|
* Common jQuery DOM events (click, change, focus, etc.) do not trigger a warning.
|
||||||
*/
|
*/
|
||||||
jQuery.fn.on = function (...args) {
|
jQuery.fn.on = function (...args) {
|
||||||
// Check if 'intentional' flag is present in any argument
|
// Get event name (first argument)
|
||||||
const intentional = args.some(arg => arg === 'intentional');
|
const eventName = typeof args[0] === 'string' ? args[0].split('.')[0] : null; // Strip namespace
|
||||||
// Filter out 'intentional' from args before passing to original .on()
|
|
||||||
const cleanArgs = intentional ? args.filter(arg => arg !== 'intentional') : args;
|
|
||||||
// Check first element for Component class and warn if needed
|
// Check first element for Component class and warn if needed
|
||||||
if (!intentional && this.length > 0) {
|
if (eventName && !COMMON_JQUERY_EVENTS.has(eventName) && this.length > 0) {
|
||||||
const firstEl = this.first();
|
const firstEl = this.first();
|
||||||
if (firstEl.hasClass('Component')) {
|
if (firstEl.hasClass('Component')) {
|
||||||
const component = firstEl.data('_component');
|
const component = firstEl.data('_component');
|
||||||
const componentName = component?.component_name?.() || 'Component';
|
const componentName = component?.component_name?.() || 'Component';
|
||||||
console.warn(`[JQHTML] jQuery .on('${cleanArgs[0]}') called on <${componentName}> root element.\n` +
|
console.warn(`[JQHTML] jQuery .on('${args[0]}') called on <${componentName}> root element.\n` +
|
||||||
`You may have meant to use component.on() for lifecycle events, or attach to a child element.\n` +
|
`You may have meant to use component.on() for lifecycle events, or attach to a child element.`);
|
||||||
`If attaching jQuery events to the component root is intentional, pass 'intentional' as an argument:\n` +
|
|
||||||
` $(element).on('${cleanArgs[0]}', 'intentional', handler)`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call original .on() with cleaned arguments and return result
|
// Call original .on() with all arguments
|
||||||
return originalOn.apply(this, cleanArgs);
|
return originalOn.apply(this, args);
|
||||||
};
|
};
|
||||||
// Store original jQuery.fn.find
|
// Store original jQuery.fn.find
|
||||||
const originalFind = jQuery.fn.find;
|
const originalFind = jQuery.fn.find;
|
||||||
@@ -4953,7 +4962,7 @@ function init(jQuery) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Version - will be replaced during build with actual version from package.json
|
// Version - will be replaced during build with actual version from package.json
|
||||||
const version = '2.3.28';
|
const version = '2.3.29';
|
||||||
// Default export with all functionality
|
// Default export with all functionality
|
||||||
const jqhtml = {
|
const jqhtml = {
|
||||||
// Core
|
// Core
|
||||||
|
|||||||
2
node_modules/@jqhtml/core/dist/index.js.map
generated
vendored
2
node_modules/@jqhtml/core/dist/index.js.map
generated
vendored
File diff suppressed because one or more lines are too long
43
node_modules/@jqhtml/core/dist/jqhtml-core.esm.js
generated
vendored
43
node_modules/@jqhtml/core/dist/jqhtml-core.esm.js
generated
vendored
@@ -1,5 +1,5 @@
|
|||||||
/**
|
/**
|
||||||
* JQHTML Core v2.3.28
|
* JQHTML Core v2.3.29
|
||||||
* (c) 2025 JQHTML Team
|
* (c) 2025 JQHTML Team
|
||||||
* Released under the MIT License
|
* Released under the MIT License
|
||||||
*/
|
*/
|
||||||
@@ -4876,34 +4876,43 @@ function init_jquery_plugin(jQuery) {
|
|||||||
};
|
};
|
||||||
// Store original jQuery.fn.on
|
// Store original jQuery.fn.on
|
||||||
const originalOn = jQuery.fn.on;
|
const originalOn = jQuery.fn.on;
|
||||||
|
// Common jQuery DOM events - no warning for these
|
||||||
|
const COMMON_JQUERY_EVENTS = new Set([
|
||||||
|
'click', 'dblclick', 'mousedown', 'mouseup', 'mousemove', 'mouseover', 'mouseout', 'mouseenter', 'mouseleave',
|
||||||
|
'keydown', 'keyup', 'keypress',
|
||||||
|
'focus', 'blur', 'focusin', 'focusout',
|
||||||
|
'change', 'input', 'submit', 'reset', 'select',
|
||||||
|
'scroll', 'resize',
|
||||||
|
'load', 'unload', 'error',
|
||||||
|
'touchstart', 'touchend', 'touchmove', 'touchcancel',
|
||||||
|
'contextmenu', 'wheel',
|
||||||
|
'copy', 'cut', 'paste',
|
||||||
|
'drag', 'dragstart', 'dragend', 'dragenter', 'dragleave', 'dragover', 'drop'
|
||||||
|
]);
|
||||||
/**
|
/**
|
||||||
* Override jQuery.fn.on() to warn when attaching events to component root elements
|
* Override jQuery.fn.on() to warn when attaching non-DOM events to component root elements
|
||||||
*
|
*
|
||||||
* JQHTML components have their own .on() method for lifecycle events.
|
* JQHTML components have their own .on() method for lifecycle events (ready, create, render, etc).
|
||||||
* Attaching jQuery events to a component's root element usually indicates
|
* Attaching these via jQuery .on() to a component's root element usually indicates
|
||||||
* the developer meant to use component.on() instead.
|
* the developer meant to use component.on() instead.
|
||||||
*
|
*
|
||||||
* To suppress the warning, pass 'intentional' as any argument.
|
* Common jQuery DOM events (click, change, focus, etc.) do not trigger a warning.
|
||||||
*/
|
*/
|
||||||
jQuery.fn.on = function (...args) {
|
jQuery.fn.on = function (...args) {
|
||||||
// Check if 'intentional' flag is present in any argument
|
// Get event name (first argument)
|
||||||
const intentional = args.some(arg => arg === 'intentional');
|
const eventName = typeof args[0] === 'string' ? args[0].split('.')[0] : null; // Strip namespace
|
||||||
// Filter out 'intentional' from args before passing to original .on()
|
|
||||||
const cleanArgs = intentional ? args.filter(arg => arg !== 'intentional') : args;
|
|
||||||
// Check first element for Component class and warn if needed
|
// Check first element for Component class and warn if needed
|
||||||
if (!intentional && this.length > 0) {
|
if (eventName && !COMMON_JQUERY_EVENTS.has(eventName) && this.length > 0) {
|
||||||
const firstEl = this.first();
|
const firstEl = this.first();
|
||||||
if (firstEl.hasClass('Component')) {
|
if (firstEl.hasClass('Component')) {
|
||||||
const component = firstEl.data('_component');
|
const component = firstEl.data('_component');
|
||||||
const componentName = component?.component_name?.() || 'Component';
|
const componentName = component?.component_name?.() || 'Component';
|
||||||
console.warn(`[JQHTML] jQuery .on('${cleanArgs[0]}') called on <${componentName}> root element.\n` +
|
console.warn(`[JQHTML] jQuery .on('${args[0]}') called on <${componentName}> root element.\n` +
|
||||||
`You may have meant to use component.on() for lifecycle events, or attach to a child element.\n` +
|
`You may have meant to use component.on() for lifecycle events, or attach to a child element.`);
|
||||||
`If attaching jQuery events to the component root is intentional, pass 'intentional' as an argument:\n` +
|
|
||||||
` $(element).on('${cleanArgs[0]}', 'intentional', handler)`);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Call original .on() with cleaned arguments and return result
|
// Call original .on() with all arguments
|
||||||
return originalOn.apply(this, cleanArgs);
|
return originalOn.apply(this, args);
|
||||||
};
|
};
|
||||||
// Store original jQuery.fn.find
|
// Store original jQuery.fn.find
|
||||||
const originalFind = jQuery.fn.find;
|
const originalFind = jQuery.fn.find;
|
||||||
@@ -4958,7 +4967,7 @@ function init(jQuery) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Version - will be replaced during build with actual version from package.json
|
// Version - will be replaced during build with actual version from package.json
|
||||||
const version = '2.3.28';
|
const version = '2.3.29';
|
||||||
// Default export with all functionality
|
// Default export with all functionality
|
||||||
const jqhtml = {
|
const jqhtml = {
|
||||||
// Core
|
// Core
|
||||||
|
|||||||
2
node_modules/@jqhtml/core/dist/jqhtml-core.esm.js.map
generated
vendored
2
node_modules/@jqhtml/core/dist/jqhtml-core.esm.js.map
generated
vendored
File diff suppressed because one or more lines are too long
2
node_modules/@jqhtml/core/dist/jquery-plugin.d.ts.map
generated
vendored
2
node_modules/@jqhtml/core/dist/jquery-plugin.d.ts.map
generated
vendored
@@ -1 +1 @@
|
|||||||
{"version":3,"file":"jquery-plugin.d.ts","sourceRoot":"","sources":["../src/jquery-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAQpE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd;;WAEG;QACH,SAAS,IAAI,gBAAgB,GAAG,IAAI,CAAC;QACrC,SAAS,CAAC,cAAc,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB,CAAC;QAC9F,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB,CAAC;QAE/E;;;;;;;WAOG;QACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;KACvC;CACF;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CA+YpD"}
|
{"version":3,"file":"jquery-plugin.d.ts","sourceRoot":"","sources":["../src/jquery-plugin.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAQpE,OAAO,CAAC,MAAM,CAAC;IACb,UAAU,MAAM;QACd;;WAEG;QACH,SAAS,IAAI,gBAAgB,GAAG,IAAI,CAAC;QACrC,SAAS,CAAC,cAAc,EAAE,oBAAoB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB,CAAC;QAC9F,SAAS,CAAC,aAAa,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,gBAAgB,CAAC;QAE/E;;;;;;;WAOG;QACH,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;KACvC;CACF;AAGD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,GAAG,GAAG,IAAI,CAwZpD"}
|
||||||
2
node_modules/@jqhtml/core/package.json
generated
vendored
2
node_modules/@jqhtml/core/package.json
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@jqhtml/core",
|
"name": "@jqhtml/core",
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"description": "Core runtime library for JQHTML",
|
"description": "Core runtime library for JQHTML",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "./dist/index.js",
|
"main": "./dist/index.js",
|
||||||
|
|||||||
2
node_modules/@jqhtml/parser/dist/codegen.js
generated
vendored
2
node_modules/@jqhtml/parser/dist/codegen.js
generated
vendored
@@ -1377,7 +1377,7 @@ export class CodeGenerator {
|
|||||||
for (const [name, component] of this.components) {
|
for (const [name, component] of this.components) {
|
||||||
code += `// Component: ${name}\n`;
|
code += `// Component: ${name}\n`;
|
||||||
code += `jqhtml_components.set('${name}', {\n`;
|
code += `jqhtml_components.set('${name}', {\n`;
|
||||||
code += ` _jqhtml_version: '2.3.28',\n`; // Version will be replaced during build
|
code += ` _jqhtml_version: '2.3.29',\n`; // Version will be replaced during build
|
||||||
code += ` name: '${name}',\n`;
|
code += ` name: '${name}',\n`;
|
||||||
code += ` tag: '${component.tagName}',\n`;
|
code += ` tag: '${component.tagName}',\n`;
|
||||||
code += ` defaultAttributes: ${this.serializeAttributeObject(component.defaultAttributes)},\n`;
|
code += ` defaultAttributes: ${this.serializeAttributeObject(component.defaultAttributes)},\n`;
|
||||||
|
|||||||
2
node_modules/@jqhtml/parser/package.json
generated
vendored
2
node_modules/@jqhtml/parser/package.json
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@jqhtml/parser",
|
"name": "@jqhtml/parser",
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"description": "JQHTML template parser - converts templates to JavaScript",
|
"description": "JQHTML template parser - converts templates to JavaScript",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"main": "dist/index.js",
|
"main": "dist/index.js",
|
||||||
|
|||||||
2
node_modules/@jqhtml/ssr/package.json
generated
vendored
2
node_modules/@jqhtml/ssr/package.json
generated
vendored
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@jqhtml/ssr",
|
"name": "@jqhtml/ssr",
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"description": "Server-Side Rendering for JQHTML components - renders components to HTML for SEO",
|
"description": "Server-Side Rendering for JQHTML components - renders components to HTML for SEO",
|
||||||
"main": "src/index.js",
|
"main": "src/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
|
|||||||
2
node_modules/@jqhtml/vscode-extension/.version
generated
vendored
2
node_modules/@jqhtml/vscode-extension/.version
generated
vendored
@@ -1 +1 @@
|
|||||||
2.3.28
|
2.3.29
|
||||||
|
|||||||
Binary file not shown.
2
node_modules/@jqhtml/vscode-extension/package.json
generated
vendored
2
node_modules/@jqhtml/vscode-extension/package.json
generated
vendored
@@ -2,7 +2,7 @@
|
|||||||
"name": "@jqhtml/vscode-extension",
|
"name": "@jqhtml/vscode-extension",
|
||||||
"displayName": "JQHTML",
|
"displayName": "JQHTML",
|
||||||
"description": "Syntax highlighting and language support for JQHTML template files",
|
"description": "Syntax highlighting and language support for JQHTML template files",
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"publisher": "jqhtml",
|
"publisher": "jqhtml",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
|
|||||||
0
node_modules/watchpack/LICENSE
generated
vendored
Executable file → Normal file
0
node_modules/watchpack/LICENSE
generated
vendored
Executable file → Normal file
18
node_modules/watchpack/README.md
generated
vendored
Executable file → Normal file
18
node_modules/watchpack/README.md
generated
vendored
Executable file → Normal file
@@ -21,9 +21,9 @@ watchpack high level API doesn't map directly to watchers. Instead a three level
|
|||||||
## API
|
## API
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
var Watchpack = require("watchpack");
|
const Watchpack = require("watchpack");
|
||||||
|
|
||||||
var wp = new Watchpack({
|
const wp = new Watchpack({
|
||||||
// options:
|
// options:
|
||||||
aggregateTimeout: 1000,
|
aggregateTimeout: 1000,
|
||||||
// fire "aggregated" event when after a change for 1000ms no additional change occurred
|
// fire "aggregated" event when after a change for 1000ms no additional change occurred
|
||||||
@@ -42,7 +42,7 @@ var wp = new Watchpack({
|
|||||||
// false (default): watches only specified item they may be real files or symlinks
|
// false (default): watches only specified item they may be real files or symlinks
|
||||||
// (This makes sense when symlinks has already been resolved)
|
// (This makes sense when symlinks has already been resolved)
|
||||||
|
|
||||||
ignored: "**/.git"
|
ignored: "**/.git",
|
||||||
// ignored: "string" - a glob pattern for files or folders that should not be watched
|
// ignored: "string" - a glob pattern for files or folders that should not be watched
|
||||||
// ignored: ["string", "string"] - multiple glob patterns that should be ignored
|
// ignored: ["string", "string"] - multiple glob patterns that should be ignored
|
||||||
// ignored: /regexp/ - a regular expression for files or folders that should not be watched
|
// ignored: /regexp/ - a regular expression for files or folders that should not be watched
|
||||||
@@ -61,7 +61,7 @@ wp.watch({
|
|||||||
files: listOfFiles,
|
files: listOfFiles,
|
||||||
directories: listOfDirectories,
|
directories: listOfDirectories,
|
||||||
missing: listOfNotExistingItems,
|
missing: listOfNotExistingItems,
|
||||||
startTime: Date.now() - 10000
|
startTime: Date.now() - 10000,
|
||||||
});
|
});
|
||||||
// starts watching these files and directories
|
// starts watching these files and directories
|
||||||
// calling this again will override the files and directories
|
// calling this again will override the files and directories
|
||||||
@@ -76,18 +76,18 @@ wp.watch({
|
|||||||
// files and directories are assumed to exist, when they are not found without further information a remove event is emitted
|
// files and directories are assumed to exist, when they are not found without further information a remove event is emitted
|
||||||
// missing is assumed to not exist and no remove event is emitted
|
// missing is assumed to not exist and no remove event is emitted
|
||||||
|
|
||||||
wp.on("change", function(filePath, mtime, explanation) {
|
wp.on("change", (filePath, mtime, explanation) => {
|
||||||
// filePath: the changed file
|
// filePath: the changed file
|
||||||
// mtime: last modified time for the changed file
|
// mtime: last modified time for the changed file
|
||||||
// explanation: textual information how this change was detected
|
// explanation: textual information how this change was detected
|
||||||
});
|
});
|
||||||
|
|
||||||
wp.on("remove", function(filePath, explanation) {
|
wp.on("remove", (filePath, explanation) => {
|
||||||
// filePath: the removed file or directory
|
// filePath: the removed file or directory
|
||||||
// explanation: textual information how this change was detected
|
// explanation: textual information how this change was detected
|
||||||
});
|
});
|
||||||
|
|
||||||
wp.on("aggregated", function(changes, removals) {
|
wp.on("aggregated", (changes, removals) => {
|
||||||
// changes: a Set of all changed files
|
// changes: a Set of all changed files
|
||||||
// removals: a Set of all removed files
|
// removals: a Set of all removed files
|
||||||
// watchpack gives up ownership on these Sets.
|
// watchpack gives up ownership on these Sets.
|
||||||
@@ -120,13 +120,13 @@ wp.collectTimeInfoEntries(fileInfoEntries, directoryInfoEntries);
|
|||||||
// timestamp: only for files, the mtime timestamp of the file
|
// timestamp: only for files, the mtime timestamp of the file
|
||||||
|
|
||||||
// Watchpack.prototype.getTimeInfoEntries()
|
// Watchpack.prototype.getTimeInfoEntries()
|
||||||
var fileTimes = wp.getTimeInfoEntries();
|
const fileTimes = wp.getTimeInfoEntries();
|
||||||
// returns a Map with all known time info objects for files and directories
|
// returns a Map with all known time info objects for files and directories
|
||||||
// similar to collectTimeInfoEntries but returns a single map with all entries
|
// similar to collectTimeInfoEntries but returns a single map with all entries
|
||||||
|
|
||||||
// (deprecated)
|
// (deprecated)
|
||||||
// Watchpack.prototype.getTimes()
|
// Watchpack.prototype.getTimes()
|
||||||
var fileTimes = wp.getTimes();
|
const fileTimesOld = wp.getTimes();
|
||||||
// returns an object with all known change times for files
|
// returns an object with all known change times for files
|
||||||
// this include timestamps from files not directly watched
|
// this include timestamps from files not directly watched
|
||||||
// key: absolute path, value: timestamp as number
|
// key: absolute path, value: timestamp as number
|
||||||
|
|||||||
454
node_modules/watchpack/lib/DirectoryWatcher.js
generated
vendored
Executable file → Normal file
454
node_modules/watchpack/lib/DirectoryWatcher.js
generated
vendored
Executable file → Normal file
@@ -4,12 +4,23 @@
|
|||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const EventEmitter = require("events").EventEmitter;
|
const { EventEmitter } = require("events");
|
||||||
const fs = require("graceful-fs");
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
|
const fs = require("graceful-fs");
|
||||||
|
|
||||||
const watchEventSource = require("./watchEventSource");
|
const watchEventSource = require("./watchEventSource");
|
||||||
|
|
||||||
|
/** @typedef {import("./index").IgnoredFunction} IgnoredFunction */
|
||||||
|
/** @typedef {import("./index").EventType} EventType */
|
||||||
|
/** @typedef {import("./index").TimeInfoEntries} TimeInfoEntries */
|
||||||
|
/** @typedef {import("./index").Entry} Entry */
|
||||||
|
/** @typedef {import("./index").ExistanceOnlyTimeEntry} ExistanceOnlyTimeEntry */
|
||||||
|
/** @typedef {import("./index").OnlySafeTimeEntry} OnlySafeTimeEntry */
|
||||||
|
/** @typedef {import("./index").EventMap} EventMap */
|
||||||
|
/** @typedef {import("./getWatcherManager").WatcherManager} WatcherManager */
|
||||||
|
/** @typedef {import("./watchEventSource").Watcher} EventSourceWatcher */
|
||||||
|
|
||||||
|
/** @type {ExistanceOnlyTimeEntry} */
|
||||||
const EXISTANCE_ONLY_TIME_ENTRY = Object.freeze({});
|
const EXISTANCE_ONLY_TIME_ENTRY = Object.freeze({});
|
||||||
|
|
||||||
let FS_ACCURACY = 2000;
|
let FS_ACCURACY = 2000;
|
||||||
@@ -17,45 +28,130 @@ let FS_ACCURACY = 2000;
|
|||||||
const IS_OSX = require("os").platform() === "darwin";
|
const IS_OSX = require("os").platform() === "darwin";
|
||||||
const IS_WIN = require("os").platform() === "win32";
|
const IS_WIN = require("os").platform() === "win32";
|
||||||
|
|
||||||
const WATCHPACK_POLLING = process.env.WATCHPACK_POLLING;
|
const { WATCHPACK_POLLING } = process.env;
|
||||||
const FORCE_POLLING =
|
const FORCE_POLLING =
|
||||||
|
// @ts-expect-error avoid additional checks
|
||||||
`${+WATCHPACK_POLLING}` === WATCHPACK_POLLING
|
`${+WATCHPACK_POLLING}` === WATCHPACK_POLLING
|
||||||
? +WATCHPACK_POLLING
|
? +WATCHPACK_POLLING
|
||||||
: !!WATCHPACK_POLLING && WATCHPACK_POLLING !== "false";
|
: Boolean(WATCHPACK_POLLING) && WATCHPACK_POLLING !== "false";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} str string
|
||||||
|
* @returns {string} lower cased string
|
||||||
|
*/
|
||||||
function withoutCase(str) {
|
function withoutCase(str) {
|
||||||
return str.toLowerCase();
|
return str.toLowerCase();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} times times
|
||||||
|
* @param {() => void} callback callback
|
||||||
|
* @returns {() => void} result
|
||||||
|
*/
|
||||||
function needCalls(times, callback) {
|
function needCalls(times, callback) {
|
||||||
return function() {
|
return function needCallsCallback() {
|
||||||
if (--times === 0) {
|
if (--times === 0) {
|
||||||
return callback();
|
return callback();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Entry} entry entry
|
||||||
|
*/
|
||||||
|
function fixupEntryAccuracy(entry) {
|
||||||
|
if (entry.accuracy > FS_ACCURACY) {
|
||||||
|
entry.safeTime = entry.safeTime - entry.accuracy + FS_ACCURACY;
|
||||||
|
entry.accuracy = FS_ACCURACY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number=} mtime mtime
|
||||||
|
*/
|
||||||
|
function ensureFsAccuracy(mtime) {
|
||||||
|
if (!mtime) return;
|
||||||
|
if (FS_ACCURACY > 1 && mtime % 1 !== 0) FS_ACCURACY = 1;
|
||||||
|
else if (FS_ACCURACY > 10 && mtime % 10 !== 0) FS_ACCURACY = 10;
|
||||||
|
else if (FS_ACCURACY > 100 && mtime % 100 !== 0) FS_ACCURACY = 100;
|
||||||
|
else if (FS_ACCURACY > 1000 && mtime % 1000 !== 0) FS_ACCURACY = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} FileWatcherEvents
|
||||||
|
* @property {(type: EventType) => void} initial-missing initial missing event
|
||||||
|
* @property {(mtime: number, type: EventType, initial: boolean) => void} change change event
|
||||||
|
* @property {(type: EventType) => void} remove remove event
|
||||||
|
* @property {() => void} closed closed event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} DirectoryWatcherEvents
|
||||||
|
* @property {(type: EventType) => void} initial-missing initial missing event
|
||||||
|
* @property {((file: string, mtime: number, type: EventType, initial: boolean) => void)} change change event
|
||||||
|
* @property {(type: EventType) => void} remove remove event
|
||||||
|
* @property {() => void} closed closed event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {EventMap} T
|
||||||
|
* @extends {EventEmitter<{ [K in keyof T]: Parameters<T[K]> }>}
|
||||||
|
*/
|
||||||
class Watcher extends EventEmitter {
|
class Watcher extends EventEmitter {
|
||||||
constructor(directoryWatcher, filePath, startTime) {
|
/**
|
||||||
|
* @param {DirectoryWatcher} directoryWatcher a directory watcher
|
||||||
|
* @param {string} target a target to watch
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
*/
|
||||||
|
constructor(directoryWatcher, target, startTime) {
|
||||||
super();
|
super();
|
||||||
this.directoryWatcher = directoryWatcher;
|
this.directoryWatcher = directoryWatcher;
|
||||||
this.path = filePath;
|
this.path = target;
|
||||||
this.startTime = startTime && +startTime;
|
this.startTime = startTime && +startTime;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {number} mtime mtime
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @returns {boolean} true of start time less than mtile, otherwise false
|
||||||
|
*/
|
||||||
checkStartTime(mtime, initial) {
|
checkStartTime(mtime, initial) {
|
||||||
const startTime = this.startTime;
|
const { startTime } = this;
|
||||||
if (typeof startTime !== "number") return !initial;
|
if (typeof startTime !== "number") return !initial;
|
||||||
return startTime <= mtime;
|
return startTime <= mtime;
|
||||||
}
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
|
// @ts-expect-error bad typing in EventEmitter
|
||||||
this.emit("closed");
|
this.emit("closed");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {Set<string>} InitialScanRemoved */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatchpackEvents
|
||||||
|
* @property {(target: string, mtime: string, type: EventType, initial: boolean) => void} change change event
|
||||||
|
* @property {() => void} closed closed event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} DirectoryWatcherOptions
|
||||||
|
* @property {boolean=} followSymlinks true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
* @property {IgnoredFunction=} ignored ignore some files from watching (glob pattern or regexp)
|
||||||
|
* @property {number | boolean=} poll true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {EventEmitter<{ [K in keyof WatchpackEvents]: Parameters<WatchpackEvents[K]> }>}
|
||||||
|
*/
|
||||||
class DirectoryWatcher extends EventEmitter {
|
class DirectoryWatcher extends EventEmitter {
|
||||||
constructor(watcherManager, directoryPath, options) {
|
/**
|
||||||
|
* @param {WatcherManager} watcherManager a watcher manager
|
||||||
|
* @param {string} directoryPath directory path
|
||||||
|
* @param {DirectoryWatcherOptions=} options options
|
||||||
|
*/
|
||||||
|
constructor(watcherManager, directoryPath, options = {}) {
|
||||||
super();
|
super();
|
||||||
if (FORCE_POLLING) {
|
if (FORCE_POLLING) {
|
||||||
options.poll = FORCE_POLLING;
|
options.poll = FORCE_POLLING;
|
||||||
@@ -65,28 +161,35 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
this.path = directoryPath;
|
this.path = directoryPath;
|
||||||
// safeTime is the point in time after which reading is safe to be unchanged
|
// safeTime is the point in time after which reading is safe to be unchanged
|
||||||
// timestamp is a value that should be compared with another timestamp (mtime)
|
// timestamp is a value that should be compared with another timestamp (mtime)
|
||||||
/** @type {Map<string, { safeTime: number, timestamp: number }} */
|
/** @type {Map<string, Entry>} */
|
||||||
this.files = new Map();
|
this.files = new Map();
|
||||||
/** @type {Map<string, number>} */
|
/** @type {Map<string, number>} */
|
||||||
this.filesWithoutCase = new Map();
|
this.filesWithoutCase = new Map();
|
||||||
|
/** @type {Map<string, Watcher<DirectoryWatcherEvents> | boolean>} */
|
||||||
this.directories = new Map();
|
this.directories = new Map();
|
||||||
this.lastWatchEvent = 0;
|
this.lastWatchEvent = 0;
|
||||||
this.initialScan = true;
|
this.initialScan = true;
|
||||||
this.ignored = options.ignored || (() => false);
|
this.ignored = options.ignored || (() => false);
|
||||||
this.nestedWatching = false;
|
this.nestedWatching = false;
|
||||||
|
/** @type {number | false} */
|
||||||
this.polledWatching =
|
this.polledWatching =
|
||||||
typeof options.poll === "number"
|
typeof options.poll === "number"
|
||||||
? options.poll
|
? options.poll
|
||||||
: options.poll
|
: options.poll
|
||||||
? 5007
|
? 5007
|
||||||
: false;
|
: false;
|
||||||
|
/** @type {undefined | NodeJS.Timeout} */
|
||||||
this.timeout = undefined;
|
this.timeout = undefined;
|
||||||
|
/** @type {null | InitialScanRemoved} */
|
||||||
this.initialScanRemoved = new Set();
|
this.initialScanRemoved = new Set();
|
||||||
|
/** @type {undefined | number} */
|
||||||
this.initialScanFinished = undefined;
|
this.initialScanFinished = undefined;
|
||||||
/** @type {Map<string, Set<Watcher>>} */
|
/** @type {Map<string, Set<Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>>>} */
|
||||||
this.watchers = new Map();
|
this.watchers = new Map();
|
||||||
|
/** @type {Watcher<FileWatcherEvents> | null} */
|
||||||
this.parentWatcher = null;
|
this.parentWatcher = null;
|
||||||
this.refs = 0;
|
this.refs = 0;
|
||||||
|
/** @type {Map<string, boolean>} */
|
||||||
this._activeEvents = new Map();
|
this._activeEvents = new Map();
|
||||||
this.closed = false;
|
this.closed = false;
|
||||||
this.scanning = false;
|
this.scanning = false;
|
||||||
@@ -100,19 +203,22 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
createWatcher() {
|
createWatcher() {
|
||||||
try {
|
try {
|
||||||
if (this.polledWatching) {
|
if (this.polledWatching) {
|
||||||
this.watcher = {
|
/** @type {EventSourceWatcher} */
|
||||||
|
(this.watcher) = /** @type {EventSourceWatcher} */ ({
|
||||||
close: () => {
|
close: () => {
|
||||||
if (this.timeout) {
|
if (this.timeout) {
|
||||||
clearTimeout(this.timeout);
|
clearTimeout(this.timeout);
|
||||||
this.timeout = undefined;
|
this.timeout = undefined;
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
};
|
});
|
||||||
} else {
|
} else {
|
||||||
if (IS_OSX) {
|
if (IS_OSX) {
|
||||||
this.watchInParentDirectory();
|
this.watchInParentDirectory();
|
||||||
}
|
}
|
||||||
this.watcher = watchEventSource.watch(this.path);
|
this.watcher =
|
||||||
|
/** @type {EventSourceWatcher} */
|
||||||
|
(watchEventSource.watch(this.path));
|
||||||
this.watcher.on("change", this.onWatchEvent.bind(this));
|
this.watcher.on("change", this.onWatchEvent.bind(this));
|
||||||
this.watcher.on("error", this.onWatcherError.bind(this));
|
this.watcher.on("error", this.onWatcherError.bind(this));
|
||||||
}
|
}
|
||||||
@@ -121,6 +227,11 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {(watcher: Watcher<EventMap>) => void} T
|
||||||
|
* @param {string} path path
|
||||||
|
* @param {T} fn function
|
||||||
|
*/
|
||||||
forEachWatcher(path, fn) {
|
forEachWatcher(path, fn) {
|
||||||
const watchers = this.watchers.get(withoutCase(path));
|
const watchers = this.watchers.get(withoutCase(path));
|
||||||
if (watchers !== undefined) {
|
if (watchers !== undefined) {
|
||||||
@@ -130,20 +241,28 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} itemPath an item path
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @param {EventType} type even type
|
||||||
|
*/
|
||||||
setMissing(itemPath, initial, type) {
|
setMissing(itemPath, initial, type) {
|
||||||
if (this.initialScan) {
|
if (this.initialScan) {
|
||||||
this.initialScanRemoved.add(itemPath);
|
/** @type {InitialScanRemoved} */
|
||||||
|
(this.initialScanRemoved).add(itemPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const oldDirectory = this.directories.get(itemPath);
|
const oldDirectory = this.directories.get(itemPath);
|
||||||
if (oldDirectory) {
|
if (oldDirectory) {
|
||||||
if (this.nestedWatching) oldDirectory.close();
|
if (this.nestedWatching) {
|
||||||
|
/** @type {Watcher<DirectoryWatcherEvents>} */
|
||||||
|
(oldDirectory).close();
|
||||||
|
}
|
||||||
this.directories.delete(itemPath);
|
this.directories.delete(itemPath);
|
||||||
|
this.forEachWatcher(itemPath, (w) => w.emit("remove", type));
|
||||||
this.forEachWatcher(itemPath, w => w.emit("remove", type));
|
|
||||||
if (!initial) {
|
if (!initial) {
|
||||||
this.forEachWatcher(this.path, w =>
|
this.forEachWatcher(this.path, (w) =>
|
||||||
w.emit("change", itemPath, null, type, initial)
|
w.emit("change", itemPath, null, type, initial),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -152,30 +271,38 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
if (oldFile) {
|
if (oldFile) {
|
||||||
this.files.delete(itemPath);
|
this.files.delete(itemPath);
|
||||||
const key = withoutCase(itemPath);
|
const key = withoutCase(itemPath);
|
||||||
const count = this.filesWithoutCase.get(key) - 1;
|
const count = /** @type {number} */ (this.filesWithoutCase.get(key)) - 1;
|
||||||
if (count <= 0) {
|
if (count <= 0) {
|
||||||
this.filesWithoutCase.delete(key);
|
this.filesWithoutCase.delete(key);
|
||||||
this.forEachWatcher(itemPath, w => w.emit("remove", type));
|
this.forEachWatcher(itemPath, (w) => w.emit("remove", type));
|
||||||
} else {
|
} else {
|
||||||
this.filesWithoutCase.set(key, count);
|
this.filesWithoutCase.set(key, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!initial) {
|
if (!initial) {
|
||||||
this.forEachWatcher(this.path, w =>
|
this.forEachWatcher(this.path, (w) =>
|
||||||
w.emit("change", itemPath, null, type, initial)
|
w.emit("change", itemPath, null, type, initial),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
setFileTime(filePath, mtime, initial, ignoreWhenEqual, type) {
|
/**
|
||||||
|
* @param {string} target a target to set file time
|
||||||
|
* @param {number} mtime mtime
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @param {boolean} ignoreWhenEqual true to ignore when equal, otherwise false
|
||||||
|
* @param {EventType} type type
|
||||||
|
*/
|
||||||
|
setFileTime(target, mtime, initial, ignoreWhenEqual, type) {
|
||||||
const now = Date.now();
|
const now = Date.now();
|
||||||
|
|
||||||
if (this.ignored(filePath)) return;
|
if (this.ignored(target)) return;
|
||||||
|
|
||||||
const old = this.files.get(filePath);
|
const old = this.files.get(target);
|
||||||
|
|
||||||
let safeTime, accuracy;
|
let safeTime;
|
||||||
|
let accuracy;
|
||||||
if (initial) {
|
if (initial) {
|
||||||
safeTime = Math.min(now, mtime) + FS_ACCURACY;
|
safeTime = Math.min(now, mtime) + FS_ACCURACY;
|
||||||
accuracy = FS_ACCURACY;
|
accuracy = FS_ACCURACY;
|
||||||
@@ -194,14 +321,14 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
|
|
||||||
if (ignoreWhenEqual && old && old.timestamp === mtime) return;
|
if (ignoreWhenEqual && old && old.timestamp === mtime) return;
|
||||||
|
|
||||||
this.files.set(filePath, {
|
this.files.set(target, {
|
||||||
safeTime,
|
safeTime,
|
||||||
accuracy,
|
accuracy,
|
||||||
timestamp: mtime
|
timestamp: mtime,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (!old) {
|
if (!old) {
|
||||||
const key = withoutCase(filePath);
|
const key = withoutCase(target);
|
||||||
const count = this.filesWithoutCase.get(key);
|
const count = this.filesWithoutCase.get(key);
|
||||||
this.filesWithoutCase.set(key, (count || 0) + 1);
|
this.filesWithoutCase.set(key, (count || 0) + 1);
|
||||||
if (count !== undefined) {
|
if (count !== undefined) {
|
||||||
@@ -213,27 +340,33 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
this.doScan(false);
|
this.doScan(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.forEachWatcher(filePath, w => {
|
this.forEachWatcher(target, (w) => {
|
||||||
if (!initial || w.checkStartTime(safeTime, initial)) {
|
if (!initial || w.checkStartTime(safeTime, initial)) {
|
||||||
w.emit("change", mtime, type);
|
w.emit("change", mtime, type);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else if (!initial) {
|
} else if (!initial) {
|
||||||
this.forEachWatcher(filePath, w => w.emit("change", mtime, type));
|
this.forEachWatcher(target, (w) => w.emit("change", mtime, type));
|
||||||
}
|
}
|
||||||
this.forEachWatcher(this.path, w => {
|
this.forEachWatcher(this.path, (w) => {
|
||||||
if (!initial || w.checkStartTime(safeTime, initial)) {
|
if (!initial || w.checkStartTime(safeTime, initial)) {
|
||||||
w.emit("change", filePath, safeTime, type, initial);
|
w.emit("change", target, safeTime, type, initial);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} directoryPath directory path
|
||||||
|
* @param {number} birthtime birthtime
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @param {EventType} type even type
|
||||||
|
*/
|
||||||
setDirectory(directoryPath, birthtime, initial, type) {
|
setDirectory(directoryPath, birthtime, initial, type) {
|
||||||
if (this.ignored(directoryPath)) return;
|
if (this.ignored(directoryPath)) return;
|
||||||
if (directoryPath === this.path) {
|
if (directoryPath === this.path) {
|
||||||
if (!initial) {
|
if (!initial) {
|
||||||
this.forEachWatcher(this.path, w =>
|
this.forEachWatcher(this.path, (w) =>
|
||||||
w.emit("change", directoryPath, birthtime, type, initial)
|
w.emit("change", directoryPath, birthtime, type, initial),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -247,19 +380,14 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
this.directories.set(directoryPath, true);
|
this.directories.set(directoryPath, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
let safeTime;
|
const safeTime = initial ? Math.min(now, birthtime) + FS_ACCURACY : now;
|
||||||
if (initial) {
|
|
||||||
safeTime = Math.min(now, birthtime) + FS_ACCURACY;
|
|
||||||
} else {
|
|
||||||
safeTime = now;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.forEachWatcher(directoryPath, w => {
|
this.forEachWatcher(directoryPath, (w) => {
|
||||||
if (!initial || w.checkStartTime(safeTime, false)) {
|
if (!initial || w.checkStartTime(safeTime, false)) {
|
||||||
w.emit("change", birthtime, type);
|
w.emit("change", birthtime, type);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.forEachWatcher(this.path, w => {
|
this.forEachWatcher(this.path, (w) => {
|
||||||
if (!initial || w.checkStartTime(safeTime, initial)) {
|
if (!initial || w.checkStartTime(safeTime, initial)) {
|
||||||
w.emit("change", directoryPath, safeTime, type, initial);
|
w.emit("change", directoryPath, safeTime, type, initial);
|
||||||
}
|
}
|
||||||
@@ -268,43 +396,57 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} directoryPath directory path
|
||||||
|
*/
|
||||||
createNestedWatcher(directoryPath) {
|
createNestedWatcher(directoryPath) {
|
||||||
const watcher = this.watcherManager.watchDirectory(directoryPath, 1);
|
const watcher = this.watcherManager.watchDirectory(directoryPath, 1);
|
||||||
watcher.on("change", (filePath, mtime, type, initial) => {
|
watcher.on("change", (target, mtime, type, initial) => {
|
||||||
this.forEachWatcher(this.path, w => {
|
this.forEachWatcher(this.path, (w) => {
|
||||||
if (!initial || w.checkStartTime(mtime, initial)) {
|
if (!initial || w.checkStartTime(mtime, initial)) {
|
||||||
w.emit("change", filePath, mtime, type, initial);
|
w.emit("change", target, mtime, type, initial);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
this.directories.set(directoryPath, watcher);
|
this.directories.set(directoryPath, watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} flag true when nested, otherwise false
|
||||||
|
*/
|
||||||
setNestedWatching(flag) {
|
setNestedWatching(flag) {
|
||||||
if (this.nestedWatching !== !!flag) {
|
if (this.nestedWatching !== Boolean(flag)) {
|
||||||
this.nestedWatching = !!flag;
|
this.nestedWatching = Boolean(flag);
|
||||||
if (this.nestedWatching) {
|
if (this.nestedWatching) {
|
||||||
for (const directory of this.directories.keys()) {
|
for (const directory of this.directories.keys()) {
|
||||||
this.createNestedWatcher(directory);
|
this.createNestedWatcher(directory);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (const [directory, watcher] of this.directories) {
|
for (const [directory, watcher] of this.directories) {
|
||||||
watcher.close();
|
/** @type {Watcher<DirectoryWatcherEvents>} */
|
||||||
|
(watcher).close();
|
||||||
this.directories.set(directory, true);
|
this.directories.set(directory, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
watch(filePath, startTime) {
|
/**
|
||||||
const key = withoutCase(filePath);
|
* @param {string} target a target to watch
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
* @returns {Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>} watcher
|
||||||
|
*/
|
||||||
|
watch(target, startTime) {
|
||||||
|
const key = withoutCase(target);
|
||||||
let watchers = this.watchers.get(key);
|
let watchers = this.watchers.get(key);
|
||||||
if (watchers === undefined) {
|
if (watchers === undefined) {
|
||||||
watchers = new Set();
|
watchers = new Set();
|
||||||
this.watchers.set(key, watchers);
|
this.watchers.set(key, watchers);
|
||||||
}
|
}
|
||||||
this.refs++;
|
this.refs++;
|
||||||
const watcher = new Watcher(this, filePath, startTime);
|
const watcher =
|
||||||
|
/** @type {Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>} */
|
||||||
|
(new Watcher(this, target, startTime));
|
||||||
watcher.on("closed", () => {
|
watcher.on("closed", () => {
|
||||||
if (--this.refs <= 0) {
|
if (--this.refs <= 0) {
|
||||||
this.close();
|
this.close();
|
||||||
@@ -313,12 +455,12 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
watchers.delete(watcher);
|
watchers.delete(watcher);
|
||||||
if (watchers.size === 0) {
|
if (watchers.size === 0) {
|
||||||
this.watchers.delete(key);
|
this.watchers.delete(key);
|
||||||
if (this.path === filePath) this.setNestedWatching(false);
|
if (this.path === target) this.setNestedWatching(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
watchers.add(watcher);
|
watchers.add(watcher);
|
||||||
let safeTime;
|
let safeTime;
|
||||||
if (filePath === this.path) {
|
if (target === this.path) {
|
||||||
this.setNestedWatching(true);
|
this.setNestedWatching(true);
|
||||||
safeTime = this.lastWatchEvent;
|
safeTime = this.lastWatchEvent;
|
||||||
for (const entry of this.files.values()) {
|
for (const entry of this.files.values()) {
|
||||||
@@ -326,7 +468,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
safeTime = Math.max(safeTime, entry.safeTime);
|
safeTime = Math.max(safeTime, entry.safeTime);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const entry = this.files.get(filePath);
|
const entry = this.files.get(target);
|
||||||
if (entry) {
|
if (entry) {
|
||||||
fixupEntryAccuracy(entry);
|
fixupEntryAccuracy(entry);
|
||||||
safeTime = entry.safeTime;
|
safeTime = entry.safeTime;
|
||||||
@@ -335,38 +477,47 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (safeTime) {
|
if (safeTime) {
|
||||||
if (safeTime >= startTime) {
|
if (startTime && safeTime >= startTime) {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
if (filePath === this.path) {
|
if (target === this.path) {
|
||||||
watcher.emit(
|
/** @type {Watcher<DirectoryWatcherEvents>} */
|
||||||
|
(watcher).emit(
|
||||||
"change",
|
"change",
|
||||||
filePath,
|
target,
|
||||||
safeTime,
|
safeTime,
|
||||||
"watch (outdated on attach)",
|
"watch (outdated on attach)",
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
watcher.emit(
|
/** @type {Watcher<FileWatcherEvents>} */
|
||||||
|
(watcher).emit(
|
||||||
"change",
|
"change",
|
||||||
safeTime,
|
safeTime,
|
||||||
"watch (outdated on attach)",
|
"watch (outdated on attach)",
|
||||||
true
|
true,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (this.initialScan) {
|
} else if (this.initialScan) {
|
||||||
if (this.initialScanRemoved.has(filePath)) {
|
if (
|
||||||
|
/** @type {InitialScanRemoved} */
|
||||||
|
(this.initialScanRemoved).has(target)
|
||||||
|
) {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
watcher.emit("remove");
|
watcher.emit("remove");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
} else if (
|
} else if (
|
||||||
filePath !== this.path &&
|
target !== this.path &&
|
||||||
!this.directories.has(filePath) &&
|
!this.directories.has(target) &&
|
||||||
watcher.checkStartTime(this.initialScanFinished, false)
|
watcher.checkStartTime(
|
||||||
|
/** @type {number} */
|
||||||
|
(this.initialScanFinished),
|
||||||
|
false,
|
||||||
|
)
|
||||||
) {
|
) {
|
||||||
process.nextTick(() => {
|
process.nextTick(() => {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
@@ -376,6 +527,10 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
return watcher;
|
return watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {EventType} eventType event type
|
||||||
|
* @param {string=} filename filename
|
||||||
|
*/
|
||||||
onWatchEvent(eventType, filename) {
|
onWatchEvent(eventType, filename) {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
@@ -387,15 +542,15 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const filePath = path.join(this.path, filename);
|
const target = path.join(this.path, filename);
|
||||||
if (this.ignored(filePath)) return;
|
if (this.ignored(target)) return;
|
||||||
|
|
||||||
if (this._activeEvents.get(filename) === undefined) {
|
if (this._activeEvents.get(filename) === undefined) {
|
||||||
this._activeEvents.set(filename, false);
|
this._activeEvents.set(filename, false);
|
||||||
const checkStats = () => {
|
const checkStats = () => {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
this._activeEvents.set(filename, false);
|
this._activeEvents.set(filename, false);
|
||||||
fs.lstat(filePath, (err, stats) => {
|
fs.lstat(target, (err, stats) => {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
if (this._activeEvents.get(filename) === true) {
|
if (this._activeEvents.get(filename) === true) {
|
||||||
process.nextTick(checkStats);
|
process.nextTick(checkStats);
|
||||||
@@ -411,35 +566,28 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
err.code !== "EBUSY"
|
err.code !== "EBUSY"
|
||||||
) {
|
) {
|
||||||
this.onStatsError(err);
|
this.onStatsError(err);
|
||||||
} else {
|
} else if (
|
||||||
if (filename === path.basename(this.path)) {
|
filename === path.basename(this.path) && // This may indicate that the directory itself was removed
|
||||||
// This may indicate that the directory itself was removed
|
!fs.existsSync(this.path)
|
||||||
if (!fs.existsSync(this.path)) {
|
) {
|
||||||
this.onDirectoryRemoved("stat failed");
|
this.onDirectoryRemoved("stat failed");
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.lastWatchEvent = Date.now();
|
this.lastWatchEvent = Date.now();
|
||||||
if (!stats) {
|
if (!stats) {
|
||||||
this.setMissing(filePath, false, eventType);
|
this.setMissing(target, false, eventType);
|
||||||
} else if (stats.isDirectory()) {
|
} else if (stats.isDirectory()) {
|
||||||
this.setDirectory(
|
this.setDirectory(target, +stats.birthtime || 1, false, eventType);
|
||||||
filePath,
|
|
||||||
+stats.birthtime || 1,
|
|
||||||
false,
|
|
||||||
eventType
|
|
||||||
);
|
|
||||||
} else if (stats.isFile() || stats.isSymbolicLink()) {
|
} else if (stats.isFile() || stats.isSymbolicLink()) {
|
||||||
if (stats.mtime) {
|
if (stats.mtime) {
|
||||||
ensureFsAccuracy(stats.mtime);
|
ensureFsAccuracy(+stats.mtime);
|
||||||
}
|
}
|
||||||
this.setFileTime(
|
this.setFileTime(
|
||||||
filePath,
|
target,
|
||||||
+stats.mtime || +stats.ctime || 1,
|
+stats.mtime || +stats.ctime || 1,
|
||||||
false,
|
false,
|
||||||
false,
|
false,
|
||||||
eventType
|
eventType,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -450,25 +598,42 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {unknown=} err error
|
||||||
|
*/
|
||||||
onWatcherError(err) {
|
onWatcherError(err) {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
if (err) {
|
if (err) {
|
||||||
if (err.code !== "EPERM" && err.code !== "ENOENT") {
|
if (
|
||||||
console.error("Watchpack Error (watcher): " + err);
|
/** @type {NodeJS.ErrnoException} */
|
||||||
|
(err).code !== "EPERM" &&
|
||||||
|
/** @type {NodeJS.ErrnoException} */
|
||||||
|
(err).code !== "ENOENT"
|
||||||
|
) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(`Watchpack Error (watcher): ${err}`);
|
||||||
}
|
}
|
||||||
this.onDirectoryRemoved("watch error");
|
this.onDirectoryRemoved("watch error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Error | NodeJS.ErrnoException=} err error
|
||||||
|
*/
|
||||||
onStatsError(err) {
|
onStatsError(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Watchpack Error (stats): " + err);
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(`Watchpack Error (stats): ${err}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Error | NodeJS.ErrnoException=} err error
|
||||||
|
*/
|
||||||
onScanError(err) {
|
onScanError(err) {
|
||||||
if (err) {
|
if (err) {
|
||||||
console.error("Watchpack Error (initial scan): " + err);
|
// eslint-disable-next-line no-console
|
||||||
|
console.error(`Watchpack Error (initial scan): ${err}`);
|
||||||
}
|
}
|
||||||
this.onScanFinished();
|
this.onScanFinished();
|
||||||
}
|
}
|
||||||
@@ -482,18 +647,21 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} reason a reason
|
||||||
|
*/
|
||||||
onDirectoryRemoved(reason) {
|
onDirectoryRemoved(reason) {
|
||||||
if (this.watcher) {
|
if (this.watcher) {
|
||||||
this.watcher.close();
|
this.watcher.close();
|
||||||
this.watcher = null;
|
this.watcher = null;
|
||||||
}
|
}
|
||||||
this.watchInParentDirectory();
|
this.watchInParentDirectory();
|
||||||
const type = `directory-removed (${reason})`;
|
const type = /** @type {EventType} */ (`directory-removed (${reason})`);
|
||||||
for (const directory of this.directories.keys()) {
|
for (const directory of this.directories.keys()) {
|
||||||
this.setMissing(directory, null, type);
|
this.setMissing(directory, false, type);
|
||||||
}
|
}
|
||||||
for (const file of this.files.keys()) {
|
for (const file of this.files.keys()) {
|
||||||
this.setMissing(file, null, type);
|
this.setMissing(file, false, type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -505,7 +673,8 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
if (path.dirname(parentDir) === parentDir) return;
|
if (path.dirname(parentDir) === parentDir) return;
|
||||||
|
|
||||||
this.parentWatcher = this.watcherManager.watchFile(this.path, 1);
|
this.parentWatcher = this.watcherManager.watchFile(this.path, 1);
|
||||||
this.parentWatcher.on("change", (mtime, type) => {
|
/** @type {Watcher<FileWatcherEvents>} */
|
||||||
|
(this.parentWatcher).on("change", (mtime, type) => {
|
||||||
if (this.closed) return;
|
if (this.closed) return;
|
||||||
|
|
||||||
// On non-osx platforms we don't need this watcher to detect
|
// On non-osx platforms we don't need this watcher to detect
|
||||||
@@ -520,17 +689,21 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
this.doScan(false);
|
this.doScan(false);
|
||||||
|
|
||||||
// directory was created so we emit an event
|
// directory was created so we emit an event
|
||||||
this.forEachWatcher(this.path, w =>
|
this.forEachWatcher(this.path, (w) =>
|
||||||
w.emit("change", this.path, mtime, type, false)
|
w.emit("change", this.path, mtime, type, false),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
this.parentWatcher.on("remove", () => {
|
/** @type {Watcher<FileWatcherEvents>} */
|
||||||
|
(this.parentWatcher).on("remove", () => {
|
||||||
this.onDirectoryRemoved("parent directory removed");
|
this.onDirectoryRemoved("parent directory removed");
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
*/
|
||||||
doScan(initial) {
|
doScan(initial) {
|
||||||
if (this.scanning) {
|
if (this.scanning) {
|
||||||
if (this.scanAgain) {
|
if (this.scanAgain) {
|
||||||
@@ -564,7 +737,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
if (watcher.checkStartTime(this.initialScanFinished, false)) {
|
if (watcher.checkStartTime(this.initialScanFinished, false)) {
|
||||||
watcher.emit(
|
watcher.emit(
|
||||||
"initial-missing",
|
"initial-missing",
|
||||||
"scan (parent directory missing in initial scan)"
|
"scan (parent directory missing in initial scan)",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,7 +752,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const itemPaths = new Set(
|
const itemPaths = new Set(
|
||||||
items.map(item => path.join(this.path, item.normalize("NFC")))
|
items.map((item) => path.join(this.path, item.normalize("NFC"))),
|
||||||
);
|
);
|
||||||
for (const file of this.files.keys()) {
|
for (const file of this.files.keys()) {
|
||||||
if (!itemPaths.has(file)) {
|
if (!itemPaths.has(file)) {
|
||||||
@@ -613,7 +786,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
if (watcher.checkStartTime(this.initialScanFinished, false)) {
|
if (watcher.checkStartTime(this.initialScanFinished, false)) {
|
||||||
watcher.emit(
|
watcher.emit(
|
||||||
"initial-missing",
|
"initial-missing",
|
||||||
"scan (missing in initial scan)"
|
"scan (missing in initial scan)",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,7 +812,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
// TODO https://github.com/libuv/libuv/pull/4566
|
// TODO https://github.com/libuv/libuv/pull/4566
|
||||||
(err2.code === "EINVAL" && IS_WIN)
|
(err2.code === "EINVAL" && IS_WIN)
|
||||||
) {
|
) {
|
||||||
this.setMissing(itemPath, initial, "scan (" + err2.code + ")");
|
this.setMissing(itemPath, initial, `scan (${err2.code})`);
|
||||||
} else {
|
} else {
|
||||||
this.onScanError(err2);
|
this.onScanError(err2);
|
||||||
}
|
}
|
||||||
@@ -648,23 +821,25 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
if (stats.isFile() || stats.isSymbolicLink()) {
|
if (stats.isFile() || stats.isSymbolicLink()) {
|
||||||
if (stats.mtime) {
|
if (stats.mtime) {
|
||||||
ensureFsAccuracy(stats.mtime);
|
ensureFsAccuracy(+stats.mtime);
|
||||||
}
|
}
|
||||||
this.setFileTime(
|
this.setFileTime(
|
||||||
itemPath,
|
itemPath,
|
||||||
+stats.mtime || +stats.ctime || 1,
|
+stats.mtime || +stats.ctime || 1,
|
||||||
initial,
|
initial,
|
||||||
true,
|
true,
|
||||||
"scan (file)"
|
"scan (file)",
|
||||||
|
);
|
||||||
|
} else if (
|
||||||
|
stats.isDirectory() &&
|
||||||
|
(!initial || !this.directories.has(itemPath))
|
||||||
|
) {
|
||||||
|
this.setDirectory(
|
||||||
|
itemPath,
|
||||||
|
+stats.birthtime || 1,
|
||||||
|
initial,
|
||||||
|
"scan (dir)",
|
||||||
);
|
);
|
||||||
} else if (stats.isDirectory()) {
|
|
||||||
if (!initial || !this.directories.has(itemPath))
|
|
||||||
this.setDirectory(
|
|
||||||
itemPath,
|
|
||||||
+stats.birthtime || 1,
|
|
||||||
initial,
|
|
||||||
"scan (dir)"
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
itemFinished();
|
itemFinished();
|
||||||
});
|
});
|
||||||
@@ -674,6 +849,9 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Record<string, number>} times
|
||||||
|
*/
|
||||||
getTimes() {
|
getTimes() {
|
||||||
const obj = Object.create(null);
|
const obj = Object.create(null);
|
||||||
let safeTime = this.lastWatchEvent;
|
let safeTime = this.lastWatchEvent;
|
||||||
@@ -684,7 +862,9 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
if (this.nestedWatching) {
|
if (this.nestedWatching) {
|
||||||
for (const w of this.directories.values()) {
|
for (const w of this.directories.values()) {
|
||||||
const times = w.directoryWatcher.getTimes();
|
const times =
|
||||||
|
/** @type {Watcher<DirectoryWatcherEvents>} */
|
||||||
|
(w).directoryWatcher.getTimes();
|
||||||
for (const file of Object.keys(times)) {
|
for (const file of Object.keys(times)) {
|
||||||
const time = times[file];
|
const time = times[file];
|
||||||
safeTime = Math.max(safeTime, time);
|
safeTime = Math.max(safeTime, time);
|
||||||
@@ -696,7 +876,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
if (!this.initialScan) {
|
if (!this.initialScan) {
|
||||||
for (const watchers of this.watchers.values()) {
|
for (const watchers of this.watchers.values()) {
|
||||||
for (const watcher of watchers) {
|
for (const watcher of watchers) {
|
||||||
const path = watcher.path;
|
const { path } = watcher;
|
||||||
if (!Object.prototype.hasOwnProperty.call(obj, path)) {
|
if (!Object.prototype.hasOwnProperty.call(obj, path)) {
|
||||||
obj[path] = null;
|
obj[path] = null;
|
||||||
}
|
}
|
||||||
@@ -706,6 +886,11 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {TimeInfoEntries} fileTimestamps file timestamps
|
||||||
|
* @param {TimeInfoEntries} directoryTimestamps directory timestamps
|
||||||
|
* @returns {number} safe time
|
||||||
|
*/
|
||||||
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
|
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
|
||||||
let safeTime = this.lastWatchEvent;
|
let safeTime = this.lastWatchEvent;
|
||||||
for (const [file, entry] of this.files) {
|
for (const [file, entry] of this.files) {
|
||||||
@@ -717,23 +902,25 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
for (const w of this.directories.values()) {
|
for (const w of this.directories.values()) {
|
||||||
safeTime = Math.max(
|
safeTime = Math.max(
|
||||||
safeTime,
|
safeTime,
|
||||||
w.directoryWatcher.collectTimeInfoEntries(
|
/** @type {Watcher<DirectoryWatcherEvents>} */
|
||||||
|
(w).directoryWatcher.collectTimeInfoEntries(
|
||||||
fileTimestamps,
|
fileTimestamps,
|
||||||
directoryTimestamps
|
directoryTimestamps,
|
||||||
)
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
|
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
|
||||||
directoryTimestamps.set(this.path, {
|
directoryTimestamps.set(this.path, {
|
||||||
safeTime
|
safeTime,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
for (const dir of this.directories.keys()) {
|
for (const dir of this.directories.keys()) {
|
||||||
// No additional info about this directory
|
// No additional info about this directory
|
||||||
// but maybe another DirectoryWatcher has info
|
// but maybe another DirectoryWatcher has info
|
||||||
fileTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
|
fileTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
|
||||||
if (!directoryTimestamps.has(dir))
|
if (!directoryTimestamps.has(dir)) {
|
||||||
directoryTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
|
directoryTimestamps.set(dir, EXISTANCE_ONLY_TIME_ENTRY);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
|
fileTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
|
||||||
directoryTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
|
directoryTimestamps.set(this.path, EXISTANCE_ONLY_TIME_ENTRY);
|
||||||
@@ -741,7 +928,7 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
if (!this.initialScan) {
|
if (!this.initialScan) {
|
||||||
for (const watchers of this.watchers.values()) {
|
for (const watchers of this.watchers.values()) {
|
||||||
for (const watcher of watchers) {
|
for (const watcher of watchers) {
|
||||||
const path = watcher.path;
|
const { path } = watcher;
|
||||||
if (!fileTimestamps.has(path)) {
|
if (!fileTimestamps.has(path)) {
|
||||||
fileTimestamps.set(path, null);
|
fileTimestamps.set(path, null);
|
||||||
}
|
}
|
||||||
@@ -760,7 +947,8 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
}
|
}
|
||||||
if (this.nestedWatching) {
|
if (this.nestedWatching) {
|
||||||
for (const w of this.directories.values()) {
|
for (const w of this.directories.values()) {
|
||||||
w.close();
|
/** @type {Watcher<DirectoryWatcherEvents>} */
|
||||||
|
(w).close();
|
||||||
}
|
}
|
||||||
this.directories.clear();
|
this.directories.clear();
|
||||||
}
|
}
|
||||||
@@ -774,18 +962,4 @@ class DirectoryWatcher extends EventEmitter {
|
|||||||
|
|
||||||
module.exports = DirectoryWatcher;
|
module.exports = DirectoryWatcher;
|
||||||
module.exports.EXISTANCE_ONLY_TIME_ENTRY = EXISTANCE_ONLY_TIME_ENTRY;
|
module.exports.EXISTANCE_ONLY_TIME_ENTRY = EXISTANCE_ONLY_TIME_ENTRY;
|
||||||
|
module.exports.Watcher = Watcher;
|
||||||
function fixupEntryAccuracy(entry) {
|
|
||||||
if (entry.accuracy > FS_ACCURACY) {
|
|
||||||
entry.safeTime = entry.safeTime - entry.accuracy + FS_ACCURACY;
|
|
||||||
entry.accuracy = FS_ACCURACY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function ensureFsAccuracy(mtime) {
|
|
||||||
if (!mtime) return;
|
|
||||||
if (FS_ACCURACY > 1 && mtime % 1 !== 0) FS_ACCURACY = 1;
|
|
||||||
else if (FS_ACCURACY > 10 && mtime % 10 !== 0) FS_ACCURACY = 10;
|
|
||||||
else if (FS_ACCURACY > 100 && mtime % 100 !== 0) FS_ACCURACY = 100;
|
|
||||||
else if (FS_ACCURACY > 1000 && mtime % 1000 !== 0) FS_ACCURACY = 1000;
|
|
||||||
}
|
|
||||||
|
|||||||
25
node_modules/watchpack/lib/LinkResolver.js
generated
vendored
Executable file → Normal file
25
node_modules/watchpack/lib/LinkResolver.js
generated
vendored
Executable file → Normal file
@@ -15,12 +15,13 @@ if (process.platform === "win32") EXPECTED_ERRORS.add("UNKNOWN");
|
|||||||
|
|
||||||
class LinkResolver {
|
class LinkResolver {
|
||||||
constructor() {
|
constructor() {
|
||||||
|
/** @type {Map<string, readonly string[]>} */
|
||||||
this.cache = new Map();
|
this.cache = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} file path to file or directory
|
* @param {string} file path to file or directory
|
||||||
* @returns {string[]} array of file and all symlinks contributed in the resolving process (first item is the resolved file)
|
* @returns {readonly string[]} array of file and all symlinks contributed in the resolving process (first item is the resolved file)
|
||||||
*/
|
*/
|
||||||
resolve(file) {
|
resolve(file) {
|
||||||
const cacheEntry = this.cache.get(file);
|
const cacheEntry = this.cache.get(file);
|
||||||
@@ -65,17 +66,18 @@ class LinkResolver {
|
|||||||
for (let i = 1; i < parentResolved.length; i++) {
|
for (let i = 1; i < parentResolved.length; i++) {
|
||||||
resultSet.add(parentResolved[i]);
|
resultSet.add(parentResolved[i]);
|
||||||
}
|
}
|
||||||
result = Object.freeze(Array.from(resultSet));
|
result = Object.freeze([...resultSet]);
|
||||||
} else if (parentResolved.length > 1) {
|
} else if (parentResolved.length > 1) {
|
||||||
// we have links in the parent but not for the link content location
|
// we have links in the parent but not for the link content location
|
||||||
result = parentResolved.slice();
|
result = [...parentResolved];
|
||||||
|
// eslint-disable-next-line prefer-destructuring
|
||||||
result[0] = linkResolved[0];
|
result[0] = linkResolved[0];
|
||||||
// add the link
|
// add the link
|
||||||
result.push(realFile);
|
result.push(realFile);
|
||||||
Object.freeze(result);
|
Object.freeze(result);
|
||||||
} else if (linkResolved.length > 1) {
|
} else if (linkResolved.length > 1) {
|
||||||
// we can return the link content location result
|
// we can return the link content location result
|
||||||
result = linkResolved.slice();
|
result = [...linkResolved];
|
||||||
// add the link
|
// add the link
|
||||||
result.push(realFile);
|
result.push(realFile);
|
||||||
Object.freeze(result);
|
Object.freeze(result);
|
||||||
@@ -86,17 +88,21 @@ class LinkResolver {
|
|||||||
// the resolve real location
|
// the resolve real location
|
||||||
linkResolved[0],
|
linkResolved[0],
|
||||||
// add the link
|
// add the link
|
||||||
realFile
|
realFile,
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
this.cache.set(file, result);
|
this.cache.set(file, result);
|
||||||
return result;
|
return result;
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
if (!EXPECTED_ERRORS.has(e.code)) {
|
if (
|
||||||
throw e;
|
/** @type {NodeJS.ErrnoException} */
|
||||||
|
(err).code &&
|
||||||
|
!EXPECTED_ERRORS.has(/** @type {NodeJS.ErrnoException} */ (err).code)
|
||||||
|
) {
|
||||||
|
throw err;
|
||||||
}
|
}
|
||||||
// no link
|
// no link
|
||||||
const result = parentResolved.slice();
|
const result = [...parentResolved];
|
||||||
result[0] = realFile;
|
result[0] = realFile;
|
||||||
Object.freeze(result);
|
Object.freeze(result);
|
||||||
this.cache.set(file, result);
|
this.cache.set(file, result);
|
||||||
@@ -104,4 +110,5 @@ class LinkResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = LinkResolver;
|
module.exports = LinkResolver;
|
||||||
|
|||||||
42
node_modules/watchpack/lib/getWatcherManager.js
generated
vendored
Executable file → Normal file
42
node_modules/watchpack/lib/getWatcherManager.js
generated
vendored
Executable file → Normal file
@@ -7,12 +7,29 @@
|
|||||||
const path = require("path");
|
const path = require("path");
|
||||||
const DirectoryWatcher = require("./DirectoryWatcher");
|
const DirectoryWatcher = require("./DirectoryWatcher");
|
||||||
|
|
||||||
|
/** @typedef {import("./index").EventMap} EventMap */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").DirectoryWatcherOptions} DirectoryWatcherOptions */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").DirectoryWatcherEvents} DirectoryWatcherEvents */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").FileWatcherEvents} FileWatcherEvents */
|
||||||
|
/**
|
||||||
|
* @template {EventMap} T
|
||||||
|
* @typedef {import("./DirectoryWatcher").Watcher<T>} Watcher
|
||||||
|
*/
|
||||||
|
|
||||||
class WatcherManager {
|
class WatcherManager {
|
||||||
constructor(options) {
|
/**
|
||||||
|
* @param {DirectoryWatcherOptions=} options options
|
||||||
|
*/
|
||||||
|
constructor(options = {}) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
/** @type {Map<string, DirectoryWatcher>} */
|
||||||
this.directoryWatchers = new Map();
|
this.directoryWatchers = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} directory a directory
|
||||||
|
* @returns {DirectoryWatcher} a directory watcher
|
||||||
|
*/
|
||||||
getDirectoryWatcher(directory) {
|
getDirectoryWatcher(directory) {
|
||||||
const watcher = this.directoryWatchers.get(directory);
|
const watcher = this.directoryWatchers.get(directory);
|
||||||
if (watcher === undefined) {
|
if (watcher === undefined) {
|
||||||
@@ -26,23 +43,34 @@ class WatcherManager {
|
|||||||
return watcher;
|
return watcher;
|
||||||
}
|
}
|
||||||
|
|
||||||
watchFile(p, startTime) {
|
/**
|
||||||
const directory = path.dirname(p);
|
* @param {string} file file
|
||||||
if (directory === p) return null;
|
* @param {number=} startTime start time
|
||||||
return this.getDirectoryWatcher(directory).watch(p, startTime);
|
* @returns {Watcher<FileWatcherEvents> | null} watcher or null if file has no directory
|
||||||
|
*/
|
||||||
|
watchFile(file, startTime) {
|
||||||
|
const directory = path.dirname(file);
|
||||||
|
if (directory === file) return null;
|
||||||
|
return this.getDirectoryWatcher(directory).watch(file, startTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} directory directory
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
* @returns {Watcher<DirectoryWatcherEvents>} watcher
|
||||||
|
*/
|
||||||
watchDirectory(directory, startTime) {
|
watchDirectory(directory, startTime) {
|
||||||
return this.getDirectoryWatcher(directory).watch(directory, startTime);
|
return this.getDirectoryWatcher(directory).watch(directory, startTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const watcherManagers = new WeakMap();
|
const watcherManagers = new WeakMap();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {object} options options
|
* @param {DirectoryWatcherOptions} options options
|
||||||
* @returns {WatcherManager} the watcher manager
|
* @returns {WatcherManager} the watcher manager
|
||||||
*/
|
*/
|
||||||
module.exports = options => {
|
module.exports = (options) => {
|
||||||
const watcherManager = watcherManagers.get(options);
|
const watcherManager = watcherManagers.get(options);
|
||||||
if (watcherManager !== undefined) return watcherManager;
|
if (watcherManager !== undefined) return watcherManager;
|
||||||
const newWatcherManager = new WatcherManager(options);
|
const newWatcherManager = new WatcherManager(options);
|
||||||
|
|||||||
554
node_modules/watchpack/lib/index.js
generated
vendored
Normal file
554
node_modules/watchpack/lib/index.js
generated
vendored
Normal file
@@ -0,0 +1,554 @@
|
|||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Tobias Koppers @sokra
|
||||||
|
*/
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { EventEmitter } = require("events");
|
||||||
|
const globToRegExp = require("glob-to-regexp");
|
||||||
|
const LinkResolver = require("./LinkResolver");
|
||||||
|
const getWatcherManager = require("./getWatcherManager");
|
||||||
|
const watchEventSource = require("./watchEventSource");
|
||||||
|
|
||||||
|
/** @typedef {import("./getWatcherManager").WatcherManager} WatcherManager */
|
||||||
|
/** @typedef {import("./DirectoryWatcher")} DirectoryWatcher */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").DirectoryWatcherEvents} DirectoryWatcherEvents */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").FileWatcherEvents} FileWatcherEvents */
|
||||||
|
|
||||||
|
// eslint-disable-next-line jsdoc/reject-any-type
|
||||||
|
/** @typedef {Record<string, (...args: any[]) => any>} EventMap */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template {EventMap} T
|
||||||
|
* @typedef {import("./DirectoryWatcher").Watcher<T>} Watcher
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @typedef {(item: string) => boolean} IgnoredFunction */
|
||||||
|
/** @typedef {string[] | RegExp | string | IgnoredFunction} Ignored */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatcherOptions
|
||||||
|
* @property {boolean=} followSymlinks true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
* @property {Ignored=} ignored ignore some files from watching (glob pattern or regexp)
|
||||||
|
* @property {number | boolean=} poll true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @typedef {WatcherOptions & { aggregateTimeout?: number }} WatchOptions */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} NormalizedWatchOptions
|
||||||
|
* @property {boolean} followSymlinks true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
* @property {IgnoredFunction} ignored ignore some files from watching (glob pattern or regexp)
|
||||||
|
* @property {number | boolean=} poll true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @typedef {`scan (${string})` | "change" | "rename" | `watch ${string}` | `directory-removed ${string}`} EventType */
|
||||||
|
/** @typedef {{ safeTime: number, timestamp: number, accuracy: number }} Entry */
|
||||||
|
/** @typedef {{ safeTime: number }} OnlySafeTimeEntry */
|
||||||
|
// eslint-disable-next-line jsdoc/ts-no-empty-object-type
|
||||||
|
/** @typedef {{}} ExistanceOnlyTimeEntry */
|
||||||
|
/** @typedef {Map<string, Entry | OnlySafeTimeEntry | ExistanceOnlyTimeEntry | null>} TimeInfoEntries */
|
||||||
|
/** @typedef {Set<string>} Changes */
|
||||||
|
/** @typedef {Set<string>} Removals */
|
||||||
|
/** @typedef {{ changes: Changes, removals: Removals }} Aggregated */
|
||||||
|
/** @typedef {{ files?: Iterable<string>, directories?: Iterable<string>, missing?: Iterable<string>, startTime?: number }} WatchMethodOptions */
|
||||||
|
/** @typedef {Record<string, number>} Times */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {MapIterator<WatchpackFileWatcher> | MapIterator<WatchpackDirectoryWatcher>} watchers watchers
|
||||||
|
* @param {Set<DirectoryWatcher>} set set
|
||||||
|
*/
|
||||||
|
function addWatchersToSet(watchers, set) {
|
||||||
|
for (const ww of watchers) {
|
||||||
|
const w = ww.watcher;
|
||||||
|
if (!set.has(w.directoryWatcher)) {
|
||||||
|
set.add(w.directoryWatcher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} ignored ignored
|
||||||
|
* @returns {string | undefined} resolved global to regexp
|
||||||
|
*/
|
||||||
|
const stringToRegexp = (ignored) => {
|
||||||
|
if (ignored.length === 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const { source } = globToRegExp(ignored, { globstar: true, extended: true });
|
||||||
|
return `${source.slice(0, -1)}(?:$|\\/)`;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Ignored=} ignored ignored
|
||||||
|
* @returns {(item: string) => boolean} ignored to function
|
||||||
|
*/
|
||||||
|
const ignoredToFunction = (ignored) => {
|
||||||
|
if (Array.isArray(ignored)) {
|
||||||
|
const stringRegexps = ignored.map((i) => stringToRegexp(i)).filter(Boolean);
|
||||||
|
if (stringRegexps.length === 0) {
|
||||||
|
return () => false;
|
||||||
|
}
|
||||||
|
const regexp = new RegExp(stringRegexps.join("|"));
|
||||||
|
return (item) => regexp.test(item.replace(/\\/g, "/"));
|
||||||
|
} else if (typeof ignored === "string") {
|
||||||
|
const stringRegexp = stringToRegexp(ignored);
|
||||||
|
if (!stringRegexp) {
|
||||||
|
return () => false;
|
||||||
|
}
|
||||||
|
const regexp = new RegExp(stringRegexp);
|
||||||
|
return (item) => regexp.test(item.replace(/\\/g, "/"));
|
||||||
|
} else if (ignored instanceof RegExp) {
|
||||||
|
return (item) => ignored.test(item.replace(/\\/g, "/"));
|
||||||
|
} else if (typeof ignored === "function") {
|
||||||
|
return ignored;
|
||||||
|
} else if (ignored) {
|
||||||
|
throw new Error(`Invalid option for 'ignored': ${ignored}`);
|
||||||
|
} else {
|
||||||
|
return () => false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {WatchOptions} options options
|
||||||
|
* @returns {NormalizedWatchOptions} normalized options
|
||||||
|
*/
|
||||||
|
const normalizeOptions = (options) => ({
|
||||||
|
followSymlinks: Boolean(options.followSymlinks),
|
||||||
|
ignored: ignoredToFunction(options.ignored),
|
||||||
|
poll: options.poll,
|
||||||
|
});
|
||||||
|
|
||||||
|
const normalizeCache = new WeakMap();
|
||||||
|
/**
|
||||||
|
* @param {WatchOptions} options options
|
||||||
|
* @returns {NormalizedWatchOptions} normalized options
|
||||||
|
*/
|
||||||
|
const cachedNormalizeOptions = (options) => {
|
||||||
|
const cacheEntry = normalizeCache.get(options);
|
||||||
|
if (cacheEntry !== undefined) return cacheEntry;
|
||||||
|
const normalized = normalizeOptions(options);
|
||||||
|
normalizeCache.set(options, normalized);
|
||||||
|
return normalized;
|
||||||
|
};
|
||||||
|
|
||||||
|
class WatchpackFileWatcher {
|
||||||
|
/**
|
||||||
|
* @param {Watchpack} watchpack watchpack
|
||||||
|
* @param {Watcher<FileWatcherEvents>} watcher watcher
|
||||||
|
* @param {string | string[]} files files
|
||||||
|
*/
|
||||||
|
constructor(watchpack, watcher, files) {
|
||||||
|
/** @type {string[]} */
|
||||||
|
this.files = Array.isArray(files) ? files : [files];
|
||||||
|
this.watcher = watcher;
|
||||||
|
watcher.on("initial-missing", (type) => {
|
||||||
|
for (const file of this.files) {
|
||||||
|
if (!watchpack._missing.has(file)) {
|
||||||
|
watchpack._onRemove(file, file, type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watcher.on("change", (mtime, type, _initial) => {
|
||||||
|
for (const file of this.files) {
|
||||||
|
watchpack._onChange(file, mtime, file, type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watcher.on("remove", (type) => {
|
||||||
|
for (const file of this.files) {
|
||||||
|
watchpack._onRemove(file, file, type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | string[]} files files
|
||||||
|
*/
|
||||||
|
update(files) {
|
||||||
|
if (!Array.isArray(files)) {
|
||||||
|
if (this.files.length !== 1) {
|
||||||
|
this.files = [files];
|
||||||
|
} else if (this.files[0] !== files) {
|
||||||
|
this.files[0] = files;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.files = files;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.watcher.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class WatchpackDirectoryWatcher {
|
||||||
|
/**
|
||||||
|
* @param {Watchpack} watchpack watchpack
|
||||||
|
* @param {Watcher<DirectoryWatcherEvents>} watcher watcher
|
||||||
|
* @param {string} directories directories
|
||||||
|
*/
|
||||||
|
constructor(watchpack, watcher, directories) {
|
||||||
|
/** @type {string[]} */
|
||||||
|
this.directories = Array.isArray(directories) ? directories : [directories];
|
||||||
|
this.watcher = watcher;
|
||||||
|
watcher.on("initial-missing", (type) => {
|
||||||
|
for (const item of this.directories) {
|
||||||
|
watchpack._onRemove(item, item, type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watcher.on("change", (file, mtime, type, _initial) => {
|
||||||
|
for (const item of this.directories) {
|
||||||
|
watchpack._onChange(item, mtime, file, type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
watcher.on("remove", (type) => {
|
||||||
|
for (const item of this.directories) {
|
||||||
|
watchpack._onRemove(item, item, type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string | string[]} directories directories
|
||||||
|
*/
|
||||||
|
update(directories) {
|
||||||
|
if (!Array.isArray(directories)) {
|
||||||
|
if (this.directories.length !== 1) {
|
||||||
|
this.directories = [directories];
|
||||||
|
} else if (this.directories[0] !== directories) {
|
||||||
|
this.directories[0] = directories;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this.directories = directories;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.watcher.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatchpackEvents
|
||||||
|
* @property {(file: string, mtime: number, type: EventType) => void} change change event
|
||||||
|
* @property {(file: string, type: EventType) => void} remove remove event
|
||||||
|
* @property {(changes: Changes, removals: Removals) => void} aggregated aggregated event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {EventEmitter<{ [K in keyof WatchpackEvents]: Parameters<WatchpackEvents[K]> }>}
|
||||||
|
*/
|
||||||
|
class Watchpack extends EventEmitter {
|
||||||
|
/**
|
||||||
|
* @param {WatchOptions=} options options
|
||||||
|
*/
|
||||||
|
constructor(options = {}) {
|
||||||
|
super();
|
||||||
|
if (!options) options = {};
|
||||||
|
/** @type {WatchOptions} */
|
||||||
|
this.options = options;
|
||||||
|
this.aggregateTimeout =
|
||||||
|
typeof options.aggregateTimeout === "number"
|
||||||
|
? options.aggregateTimeout
|
||||||
|
: 200;
|
||||||
|
/** @type {NormalizedWatchOptions} */
|
||||||
|
this.watcherOptions = cachedNormalizeOptions(options);
|
||||||
|
/** @type {WatcherManager} */
|
||||||
|
this.watcherManager = getWatcherManager(this.watcherOptions);
|
||||||
|
/** @type {Map<string, WatchpackFileWatcher>} */
|
||||||
|
this.fileWatchers = new Map();
|
||||||
|
/** @type {Map<string, WatchpackDirectoryWatcher>} */
|
||||||
|
this.directoryWatchers = new Map();
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
this._missing = new Set();
|
||||||
|
this.startTime = undefined;
|
||||||
|
this.paused = false;
|
||||||
|
/** @type {Changes} */
|
||||||
|
this.aggregatedChanges = new Set();
|
||||||
|
/** @type {Removals} */
|
||||||
|
this.aggregatedRemovals = new Set();
|
||||||
|
/** @type {undefined | NodeJS.Timeout} */
|
||||||
|
this.aggregateTimer = undefined;
|
||||||
|
this._onTimeout = this._onTimeout.bind(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
* @param {Iterable<string>} arg1 files
|
||||||
|
* @param {Iterable<string>} arg2 directories
|
||||||
|
* @param {number=} arg3 startTime
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
* @param {WatchMethodOptions} arg1 watch options
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param {Iterable<string> | WatchMethodOptions} arg1 files
|
||||||
|
* @param {Iterable<string>=} arg2 directories
|
||||||
|
* @param {number=} arg3 startTime
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
watch(arg1, arg2, arg3) {
|
||||||
|
/** @type {Iterable<string> | undefined} */
|
||||||
|
let files;
|
||||||
|
/** @type {Iterable<string> | undefined} */
|
||||||
|
let directories;
|
||||||
|
/** @type {Iterable<string> | undefined} */
|
||||||
|
let missing;
|
||||||
|
/** @type {number | undefined} */
|
||||||
|
let startTime;
|
||||||
|
if (!arg2) {
|
||||||
|
({
|
||||||
|
files = [],
|
||||||
|
directories = [],
|
||||||
|
missing = [],
|
||||||
|
startTime,
|
||||||
|
} = /** @type {WatchMethodOptions} */ (arg1));
|
||||||
|
} else {
|
||||||
|
files = /** @type {Iterable<string>} */ (arg1);
|
||||||
|
directories = /** @type {Iterable<string>} */ (arg2);
|
||||||
|
missing = [];
|
||||||
|
startTime = /** @type {number} */ (arg3);
|
||||||
|
}
|
||||||
|
this.paused = false;
|
||||||
|
const { fileWatchers, directoryWatchers } = this;
|
||||||
|
const { ignored } = this.watcherOptions;
|
||||||
|
/**
|
||||||
|
* @param {string} path path
|
||||||
|
* @returns {boolean} true when need to filter, otherwise false
|
||||||
|
*/
|
||||||
|
const filter = (path) => !ignored(path);
|
||||||
|
/**
|
||||||
|
* @template K, V
|
||||||
|
* @param {Map<K, V | V[]>} map map
|
||||||
|
* @param {K} key key
|
||||||
|
* @param {V} item item
|
||||||
|
*/
|
||||||
|
const addToMap = (map, key, item) => {
|
||||||
|
const list = map.get(key);
|
||||||
|
if (list === undefined) {
|
||||||
|
map.set(key, item);
|
||||||
|
} else if (Array.isArray(list)) {
|
||||||
|
list.push(item);
|
||||||
|
} else {
|
||||||
|
map.set(key, [list, item]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
const fileWatchersNeeded = new Map();
|
||||||
|
const directoryWatchersNeeded = new Map();
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
const missingFiles = new Set();
|
||||||
|
if (this.watcherOptions.followSymlinks) {
|
||||||
|
const resolver = new LinkResolver();
|
||||||
|
for (const file of files) {
|
||||||
|
if (filter(file)) {
|
||||||
|
for (const innerFile of resolver.resolve(file)) {
|
||||||
|
if (file === innerFile || filter(innerFile)) {
|
||||||
|
addToMap(fileWatchersNeeded, innerFile, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const file of missing) {
|
||||||
|
if (filter(file)) {
|
||||||
|
for (const innerFile of resolver.resolve(file)) {
|
||||||
|
if (file === innerFile || filter(innerFile)) {
|
||||||
|
missingFiles.add(file);
|
||||||
|
addToMap(fileWatchersNeeded, innerFile, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const dir of directories) {
|
||||||
|
if (filter(dir)) {
|
||||||
|
let first = true;
|
||||||
|
for (const innerItem of resolver.resolve(dir)) {
|
||||||
|
if (filter(innerItem)) {
|
||||||
|
addToMap(
|
||||||
|
first ? directoryWatchersNeeded : fileWatchersNeeded,
|
||||||
|
innerItem,
|
||||||
|
dir,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
first = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const file of files) {
|
||||||
|
if (filter(file)) {
|
||||||
|
addToMap(fileWatchersNeeded, file, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const file of missing) {
|
||||||
|
if (filter(file)) {
|
||||||
|
missingFiles.add(file);
|
||||||
|
addToMap(fileWatchersNeeded, file, file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const dir of directories) {
|
||||||
|
if (filter(dir)) {
|
||||||
|
addToMap(directoryWatchersNeeded, dir, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Close unneeded old watchers
|
||||||
|
// and update existing watchers
|
||||||
|
for (const [key, w] of fileWatchers) {
|
||||||
|
const needed = fileWatchersNeeded.get(key);
|
||||||
|
if (needed === undefined) {
|
||||||
|
w.close();
|
||||||
|
fileWatchers.delete(key);
|
||||||
|
} else {
|
||||||
|
w.update(needed);
|
||||||
|
fileWatchersNeeded.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [key, w] of directoryWatchers) {
|
||||||
|
const needed = directoryWatchersNeeded.get(key);
|
||||||
|
if (needed === undefined) {
|
||||||
|
w.close();
|
||||||
|
directoryWatchers.delete(key);
|
||||||
|
} else {
|
||||||
|
w.update(needed);
|
||||||
|
directoryWatchersNeeded.delete(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Create new watchers and install handlers on these watchers
|
||||||
|
watchEventSource.batch(() => {
|
||||||
|
for (const [key, files] of fileWatchersNeeded) {
|
||||||
|
const watcher = this.watcherManager.watchFile(key, startTime);
|
||||||
|
if (watcher) {
|
||||||
|
fileWatchers.set(key, new WatchpackFileWatcher(this, watcher, files));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const [key, directories] of directoryWatchersNeeded) {
|
||||||
|
const watcher = this.watcherManager.watchDirectory(key, startTime);
|
||||||
|
if (watcher) {
|
||||||
|
directoryWatchers.set(
|
||||||
|
key,
|
||||||
|
new WatchpackDirectoryWatcher(this, watcher, directories),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
this._missing = missingFiles;
|
||||||
|
this.startTime = startTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
close() {
|
||||||
|
this.paused = true;
|
||||||
|
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
||||||
|
for (const w of this.fileWatchers.values()) w.close();
|
||||||
|
for (const w of this.directoryWatchers.values()) w.close();
|
||||||
|
this.fileWatchers.clear();
|
||||||
|
this.directoryWatchers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
pause() {
|
||||||
|
this.paused = true;
|
||||||
|
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Record<string, number>} times
|
||||||
|
*/
|
||||||
|
getTimes() {
|
||||||
|
/** @type {Set<DirectoryWatcher>} */
|
||||||
|
const directoryWatchers = new Set();
|
||||||
|
addWatchersToSet(this.fileWatchers.values(), directoryWatchers);
|
||||||
|
addWatchersToSet(this.directoryWatchers.values(), directoryWatchers);
|
||||||
|
/** @type {Record<string, number>} */
|
||||||
|
const obj = Object.create(null);
|
||||||
|
for (const w of directoryWatchers) {
|
||||||
|
const times = w.getTimes();
|
||||||
|
for (const file of Object.keys(times)) obj[file] = times[file];
|
||||||
|
}
|
||||||
|
return obj;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {TimeInfoEntries} time info entries
|
||||||
|
*/
|
||||||
|
getTimeInfoEntries() {
|
||||||
|
/** @type {TimeInfoEntries} */
|
||||||
|
const map = new Map();
|
||||||
|
this.collectTimeInfoEntries(map, map);
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {TimeInfoEntries} fileTimestamps file timestamps
|
||||||
|
* @param {TimeInfoEntries} directoryTimestamps directory timestamps
|
||||||
|
*/
|
||||||
|
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
|
||||||
|
/** @type {Set<DirectoryWatcher>} */
|
||||||
|
const allWatchers = new Set();
|
||||||
|
addWatchersToSet(this.fileWatchers.values(), allWatchers);
|
||||||
|
addWatchersToSet(this.directoryWatchers.values(), allWatchers);
|
||||||
|
for (const w of allWatchers) {
|
||||||
|
w.collectTimeInfoEntries(fileTimestamps, directoryTimestamps);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Aggregated} aggregated info
|
||||||
|
*/
|
||||||
|
getAggregated() {
|
||||||
|
if (this.aggregateTimer) {
|
||||||
|
clearTimeout(this.aggregateTimer);
|
||||||
|
this.aggregateTimer = undefined;
|
||||||
|
}
|
||||||
|
const changes = this.aggregatedChanges;
|
||||||
|
const removals = this.aggregatedRemovals;
|
||||||
|
this.aggregatedChanges = new Set();
|
||||||
|
this.aggregatedRemovals = new Set();
|
||||||
|
return { changes, removals };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} item item
|
||||||
|
* @param {number} mtime mtime
|
||||||
|
* @param {string} file file
|
||||||
|
* @param {EventType} type type
|
||||||
|
*/
|
||||||
|
_onChange(item, mtime, file, type) {
|
||||||
|
file = file || item;
|
||||||
|
if (!this.paused) {
|
||||||
|
this.emit("change", file, mtime, type);
|
||||||
|
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
||||||
|
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
|
||||||
|
}
|
||||||
|
this.aggregatedRemovals.delete(item);
|
||||||
|
this.aggregatedChanges.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} item item
|
||||||
|
* @param {string} file file
|
||||||
|
* @param {EventType} type type
|
||||||
|
*/
|
||||||
|
_onRemove(item, file, type) {
|
||||||
|
file = file || item;
|
||||||
|
if (!this.paused) {
|
||||||
|
this.emit("remove", file, type);
|
||||||
|
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
||||||
|
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
|
||||||
|
}
|
||||||
|
this.aggregatedChanges.delete(item);
|
||||||
|
this.aggregatedRemovals.add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
_onTimeout() {
|
||||||
|
this.aggregateTimer = undefined;
|
||||||
|
const changes = this.aggregatedChanges;
|
||||||
|
const removals = this.aggregatedRemovals;
|
||||||
|
this.aggregatedChanges = new Set();
|
||||||
|
this.aggregatedRemovals = new Set();
|
||||||
|
this.emit("aggregated", changes, removals);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = Watchpack;
|
||||||
44
node_modules/watchpack/lib/reducePlan.js
generated
vendored
Executable file → Normal file
44
node_modules/watchpack/lib/reducePlan.js
generated
vendored
Executable file → Normal file
@@ -8,48 +8,48 @@ const path = require("path");
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @template T
|
* @template T
|
||||||
* @typedef {Object} TreeNode
|
* @typedef {object} TreeNode
|
||||||
* @property {string} filePath
|
* @property {string} target target
|
||||||
* @property {TreeNode} parent
|
* @property {TreeNode<T>} parent parent
|
||||||
* @property {TreeNode[]} children
|
* @property {TreeNode<T>[]} children children
|
||||||
* @property {number} entries
|
* @property {number} entries number of entries
|
||||||
* @property {boolean} active
|
* @property {boolean} active true when active, otherwise false
|
||||||
* @property {T[] | T | undefined} value
|
* @property {T[] | T | undefined} value value
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @template T
|
* @template T
|
||||||
* @param {Map<string, T[] | T} plan
|
* @param {Map<string, T[] | T>} plan plan
|
||||||
* @param {number} limit
|
* @param {number} limit limit
|
||||||
* @returns {Map<string, Map<T, string>>} the new plan
|
* @returns {Map<string, Map<T, string>>} the new plan
|
||||||
*/
|
*/
|
||||||
module.exports = (plan, limit) => {
|
module.exports = (plan, limit) => {
|
||||||
const treeMap = new Map();
|
const treeMap = new Map();
|
||||||
// Convert to tree
|
// Convert to tree
|
||||||
for (const [filePath, value] of plan) {
|
for (const [target, value] of plan) {
|
||||||
treeMap.set(filePath, {
|
treeMap.set(target, {
|
||||||
filePath,
|
target,
|
||||||
parent: undefined,
|
parent: undefined,
|
||||||
children: undefined,
|
children: undefined,
|
||||||
entries: 1,
|
entries: 1,
|
||||||
active: true,
|
active: true,
|
||||||
value
|
value,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
let currentCount = treeMap.size;
|
let currentCount = treeMap.size;
|
||||||
// Create parents and calculate sum of entries
|
// Create parents and calculate sum of entries
|
||||||
for (const node of treeMap.values()) {
|
for (const node of treeMap.values()) {
|
||||||
const parentPath = path.dirname(node.filePath);
|
const parentPath = path.dirname(node.target);
|
||||||
if (parentPath !== node.filePath) {
|
if (parentPath !== node.target) {
|
||||||
let parent = treeMap.get(parentPath);
|
let parent = treeMap.get(parentPath);
|
||||||
if (parent === undefined) {
|
if (parent === undefined) {
|
||||||
parent = {
|
parent = {
|
||||||
filePath: parentPath,
|
target: parentPath,
|
||||||
parent: undefined,
|
parent: undefined,
|
||||||
children: [node],
|
children: [node],
|
||||||
entries: node.entries,
|
entries: node.entries,
|
||||||
active: false,
|
active: false,
|
||||||
value: undefined
|
value: undefined,
|
||||||
};
|
};
|
||||||
treeMap.set(parentPath, parent);
|
treeMap.set(parentPath, parent);
|
||||||
node.parent = parent;
|
node.parent = parent;
|
||||||
@@ -71,7 +71,7 @@ module.exports = (plan, limit) => {
|
|||||||
while (currentCount > limit) {
|
while (currentCount > limit) {
|
||||||
// Select node that helps reaching the limit most effectively without overmerging
|
// Select node that helps reaching the limit most effectively without overmerging
|
||||||
const overLimit = currentCount - limit;
|
const overLimit = currentCount - limit;
|
||||||
let bestNode = undefined;
|
let bestNode;
|
||||||
let bestCost = Infinity;
|
let bestCost = Infinity;
|
||||||
for (const node of treeMap.values()) {
|
for (const node of treeMap.values()) {
|
||||||
if (node.entries <= 1 || !node.children || !node.parent) continue;
|
if (node.entries <= 1 || !node.children || !node.parent) continue;
|
||||||
@@ -95,7 +95,7 @@ module.exports = (plan, limit) => {
|
|||||||
bestNode.active = true;
|
bestNode.active = true;
|
||||||
bestNode.entries = 1;
|
bestNode.entries = 1;
|
||||||
currentCount -= reduction;
|
currentCount -= reduction;
|
||||||
let parent = bestNode.parent;
|
let { parent } = bestNode;
|
||||||
while (parent) {
|
while (parent) {
|
||||||
parent.entries -= reduction;
|
parent.entries -= reduction;
|
||||||
parent = parent.parent;
|
parent = parent.parent;
|
||||||
@@ -120,10 +120,10 @@ module.exports = (plan, limit) => {
|
|||||||
if (node.value) {
|
if (node.value) {
|
||||||
if (Array.isArray(node.value)) {
|
if (Array.isArray(node.value)) {
|
||||||
for (const item of node.value) {
|
for (const item of node.value) {
|
||||||
map.set(item, node.filePath);
|
map.set(item, node.target);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
map.set(node.value, node.filePath);
|
map.set(node.value, node.target);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node.children) {
|
if (node.children) {
|
||||||
@@ -132,7 +132,7 @@ module.exports = (plan, limit) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
newPlan.set(rootNode.filePath, map);
|
newPlan.set(rootNode.target, map);
|
||||||
}
|
}
|
||||||
return newPlan;
|
return newPlan;
|
||||||
};
|
};
|
||||||
|
|||||||
152
node_modules/watchpack/lib/watchEventSource.js
generated
vendored
Executable file → Normal file
152
node_modules/watchpack/lib/watchEventSource.js
generated
vendored
Executable file → Normal file
@@ -4,22 +4,28 @@
|
|||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
|
const { EventEmitter } = require("events");
|
||||||
const fs = require("fs");
|
const fs = require("fs");
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { EventEmitter } = require("events");
|
|
||||||
const reducePlan = require("./reducePlan");
|
const reducePlan = require("./reducePlan");
|
||||||
|
|
||||||
|
/** @typedef {import("fs").FSWatcher} FSWatcher */
|
||||||
|
/** @typedef {import("./index").EventType} EventType */
|
||||||
|
|
||||||
const IS_OSX = require("os").platform() === "darwin";
|
const IS_OSX = require("os").platform() === "darwin";
|
||||||
const IS_WIN = require("os").platform() === "win32";
|
const IS_WIN = require("os").platform() === "win32";
|
||||||
|
|
||||||
const SUPPORTS_RECURSIVE_WATCHING = IS_OSX || IS_WIN;
|
const SUPPORTS_RECURSIVE_WATCHING = IS_OSX || IS_WIN;
|
||||||
|
|
||||||
// Use 20 for OSX to make `FSWatcher.close` faster
|
// Use 20 for OSX to make `FSWatcher.close` faster
|
||||||
// https://github.com/nodejs/node/issues/29949
|
// https://github.com/nodejs/node/issues/29949
|
||||||
const watcherLimit =
|
const watcherLimit =
|
||||||
|
// @ts-expect-error avoid additional checks
|
||||||
+process.env.WATCHPACK_WATCHER_LIMIT || (IS_OSX ? 20 : 10000);
|
+process.env.WATCHPACK_WATCHER_LIMIT || (IS_OSX ? 20 : 10000);
|
||||||
|
|
||||||
const recursiveWatcherLogging = !!process.env
|
const recursiveWatcherLogging = Boolean(
|
||||||
.WATCHPACK_RECURSIVE_WATCHER_LOGGING;
|
process.env.WATCHPACK_RECURSIVE_WATCHER_LOGGING,
|
||||||
|
);
|
||||||
|
|
||||||
let isBatch = false;
|
let isBatch = false;
|
||||||
let watcherCount = 0;
|
let watcherCount = 0;
|
||||||
@@ -36,12 +42,24 @@ const directWatchers = new Map();
|
|||||||
/** @type {Map<Watcher, RecursiveWatcher | DirectWatcher>} */
|
/** @type {Map<Watcher, RecursiveWatcher | DirectWatcher>} */
|
||||||
const underlyingWatcher = new Map();
|
const underlyingWatcher = new Map();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filePath file path
|
||||||
|
* @returns {NodeJS.ErrnoException} new error with file path in the message
|
||||||
|
*/
|
||||||
function createEPERMError(filePath) {
|
function createEPERMError(filePath) {
|
||||||
const error = new Error(`Operation not permitted: ${filePath}`);
|
const error =
|
||||||
|
/** @type {NodeJS.ErrnoException} */
|
||||||
|
(new Error(`Operation not permitted: ${filePath}`));
|
||||||
error.code = "EPERM";
|
error.code = "EPERM";
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {FSWatcher} watcher watcher
|
||||||
|
* @param {string} filePath a file path
|
||||||
|
* @param {(type: "rename" | "change", filename: string) => void} handleChangeEvent function to handle change
|
||||||
|
* @returns {(type: "rename" | "change", filename: string) => void} handler of change event
|
||||||
|
*/
|
||||||
function createHandleChangeEvent(watcher, filePath, handleChangeEvent) {
|
function createHandleChangeEvent(watcher, filePath, handleChangeEvent) {
|
||||||
return (type, filename) => {
|
return (type, filename) => {
|
||||||
// TODO: After Node.js v22, fs.watch(dir) and deleting a dir will trigger the rename change event.
|
// TODO: After Node.js v22, fs.watch(dir) and deleting a dir will trigger the rename change event.
|
||||||
@@ -64,9 +82,13 @@ function createHandleChangeEvent(watcher, filePath, handleChangeEvent) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class DirectWatcher {
|
class DirectWatcher {
|
||||||
|
/**
|
||||||
|
* @param {string} filePath file path
|
||||||
|
*/
|
||||||
constructor(filePath) {
|
constructor(filePath) {
|
||||||
this.filePath = filePath;
|
this.filePath = filePath;
|
||||||
this.watchers = new Set();
|
this.watchers = new Set();
|
||||||
|
/** @type {FSWatcher | undefined} */
|
||||||
this.watcher = undefined;
|
this.watcher = undefined;
|
||||||
try {
|
try {
|
||||||
const watcher = fs.watch(filePath);
|
const watcher = fs.watch(filePath);
|
||||||
@@ -79,10 +101,10 @@ class DirectWatcher {
|
|||||||
for (const w of this.watchers) {
|
for (const w of this.watchers) {
|
||||||
w.emit("change", type, filename);
|
w.emit("change", type, filename);
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
);
|
);
|
||||||
watcher.on("change", handleChangeEvent);
|
watcher.on("change", handleChangeEvent);
|
||||||
watcher.on("error", error => {
|
watcher.on("error", (error) => {
|
||||||
for (const w of this.watchers) {
|
for (const w of this.watchers) {
|
||||||
w.emit("error", error);
|
w.emit("error", error);
|
||||||
}
|
}
|
||||||
@@ -97,11 +119,17 @@ class DirectWatcher {
|
|||||||
watcherCount++;
|
watcherCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Watcher} watcher a watcher
|
||||||
|
*/
|
||||||
add(watcher) {
|
add(watcher) {
|
||||||
underlyingWatcher.set(watcher, this);
|
underlyingWatcher.set(watcher, this);
|
||||||
this.watchers.add(watcher);
|
this.watchers.add(watcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Watcher} watcher a watcher
|
||||||
|
*/
|
||||||
remove(watcher) {
|
remove(watcher) {
|
||||||
this.watchers.delete(watcher);
|
this.watchers.delete(watcher);
|
||||||
if (this.watchers.size === 0) {
|
if (this.watchers.size === 0) {
|
||||||
@@ -116,31 +144,36 @@ class DirectWatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @typedef {Set<Watcher>} WatcherSet */
|
||||||
|
|
||||||
class RecursiveWatcher {
|
class RecursiveWatcher {
|
||||||
|
/**
|
||||||
|
* @param {string} rootPath a root path
|
||||||
|
*/
|
||||||
constructor(rootPath) {
|
constructor(rootPath) {
|
||||||
this.rootPath = rootPath;
|
this.rootPath = rootPath;
|
||||||
/** @type {Map<Watcher, string>} */
|
/** @type {Map<Watcher, string>} */
|
||||||
this.mapWatcherToPath = new Map();
|
this.mapWatcherToPath = new Map();
|
||||||
/** @type {Map<string, Set<Watcher>>} */
|
/** @type {Map<string, WatcherSet>} */
|
||||||
this.mapPathToWatchers = new Map();
|
this.mapPathToWatchers = new Map();
|
||||||
this.watcher = undefined;
|
this.watcher = undefined;
|
||||||
try {
|
try {
|
||||||
const watcher = fs.watch(rootPath, {
|
const watcher = fs.watch(rootPath, {
|
||||||
recursive: true
|
recursive: true,
|
||||||
});
|
});
|
||||||
this.watcher = watcher;
|
this.watcher = watcher;
|
||||||
watcher.on("change", (type, filename) => {
|
watcher.on("change", (type, filename) => {
|
||||||
if (!filename) {
|
if (!filename) {
|
||||||
if (recursiveWatcherLogging) {
|
if (recursiveWatcherLogging) {
|
||||||
process.stderr.write(
|
process.stderr.write(
|
||||||
`[watchpack] dispatch ${type} event in recursive watcher (${this.rootPath}) to all watchers\n`
|
`[watchpack] dispatch ${type} event in recursive watcher (${this.rootPath}) to all watchers\n`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
for (const w of this.mapWatcherToPath.keys()) {
|
for (const w of this.mapWatcherToPath.keys()) {
|
||||||
w.emit("change", type);
|
w.emit("change", /** @type {EventType} */ (type));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
const dir = path.dirname(filename);
|
const dir = path.dirname(/** @type {string} */ (filename));
|
||||||
const watchers = this.mapPathToWatchers.get(dir);
|
const watchers = this.mapPathToWatchers.get(dir);
|
||||||
if (recursiveWatcherLogging) {
|
if (recursiveWatcherLogging) {
|
||||||
process.stderr.write(
|
process.stderr.write(
|
||||||
@@ -148,16 +181,20 @@ class RecursiveWatcher {
|
|||||||
this.rootPath
|
this.rootPath
|
||||||
}) for '${filename}' to ${
|
}) for '${filename}' to ${
|
||||||
watchers ? watchers.size : 0
|
watchers ? watchers.size : 0
|
||||||
} watchers\n`
|
} watchers\n`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (watchers === undefined) return;
|
if (watchers === undefined) return;
|
||||||
for (const w of watchers) {
|
for (const w of watchers) {
|
||||||
w.emit("change", type, path.basename(filename));
|
w.emit(
|
||||||
|
"change",
|
||||||
|
/** @type {EventType} */ (type),
|
||||||
|
path.basename(/** @type {string} */ (filename)),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
watcher.on("error", error => {
|
watcher.on("error", (error) => {
|
||||||
for (const w of this.mapWatcherToPath.keys()) {
|
for (const w of this.mapWatcherToPath.keys()) {
|
||||||
w.emit("error", error);
|
w.emit("error", error);
|
||||||
}
|
}
|
||||||
@@ -172,11 +209,15 @@ class RecursiveWatcher {
|
|||||||
watcherCount++;
|
watcherCount++;
|
||||||
if (recursiveWatcherLogging) {
|
if (recursiveWatcherLogging) {
|
||||||
process.stderr.write(
|
process.stderr.write(
|
||||||
`[watchpack] created recursive watcher at ${rootPath}\n`
|
`[watchpack] created recursive watcher at ${rootPath}\n`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filePath a file path
|
||||||
|
* @param {Watcher} watcher a watcher
|
||||||
|
*/
|
||||||
add(filePath, watcher) {
|
add(filePath, watcher) {
|
||||||
underlyingWatcher.set(watcher, this);
|
underlyingWatcher.set(watcher, this);
|
||||||
const subpath = filePath.slice(this.rootPath.length + 1) || ".";
|
const subpath = filePath.slice(this.rootPath.length + 1) || ".";
|
||||||
@@ -191,11 +232,14 @@ class RecursiveWatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {Watcher} watcher a watcher
|
||||||
|
*/
|
||||||
remove(watcher) {
|
remove(watcher) {
|
||||||
const subpath = this.mapWatcherToPath.get(watcher);
|
const subpath = this.mapWatcherToPath.get(watcher);
|
||||||
if (!subpath) return;
|
if (!subpath) return;
|
||||||
this.mapWatcherToPath.delete(watcher);
|
this.mapWatcherToPath.delete(watcher);
|
||||||
const set = this.mapPathToWatchers.get(subpath);
|
const set = /** @type {WatcherSet} */ (this.mapPathToWatchers.get(subpath));
|
||||||
set.delete(watcher);
|
set.delete(watcher);
|
||||||
if (set.size === 0) {
|
if (set.size === 0) {
|
||||||
this.mapPathToWatchers.delete(subpath);
|
this.mapPathToWatchers.delete(subpath);
|
||||||
@@ -206,7 +250,7 @@ class RecursiveWatcher {
|
|||||||
if (this.watcher) this.watcher.close();
|
if (this.watcher) this.watcher.close();
|
||||||
if (recursiveWatcherLogging) {
|
if (recursiveWatcherLogging) {
|
||||||
process.stderr.write(
|
process.stderr.write(
|
||||||
`[watchpack] closed recursive watcher at ${this.rootPath}\n`
|
`[watchpack] closed recursive watcher at ${this.rootPath}\n`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -217,19 +261,37 @@ class RecursiveWatcher {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatcherEvents
|
||||||
|
* @property {(eventType: EventType, filename?: string) => void} change change event
|
||||||
|
* @property {(err: unknown) => void} error error event
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends {EventEmitter<{ [K in keyof WatcherEvents]: Parameters<WatcherEvents[K]> }>}
|
||||||
|
*/
|
||||||
class Watcher extends EventEmitter {
|
class Watcher extends EventEmitter {
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
|
||||||
close() {
|
close() {
|
||||||
if (pendingWatchers.has(this)) {
|
if (pendingWatchers.has(this)) {
|
||||||
pendingWatchers.delete(this);
|
pendingWatchers.delete(this);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const watcher = underlyingWatcher.get(this);
|
const watcher = underlyingWatcher.get(this);
|
||||||
watcher.remove(this);
|
/** @type {RecursiveWatcher | DirectWatcher} */
|
||||||
|
(watcher).remove(this);
|
||||||
underlyingWatcher.delete(this);
|
underlyingWatcher.delete(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createDirectWatcher = filePath => {
|
/**
|
||||||
|
* @param {string} filePath a file path
|
||||||
|
* @returns {DirectWatcher} a directory watcher
|
||||||
|
*/
|
||||||
|
const createDirectWatcher = (filePath) => {
|
||||||
const existing = directWatchers.get(filePath);
|
const existing = directWatchers.get(filePath);
|
||||||
if (existing !== undefined) return existing;
|
if (existing !== undefined) return existing;
|
||||||
const w = new DirectWatcher(filePath);
|
const w = new DirectWatcher(filePath);
|
||||||
@@ -237,7 +299,11 @@ const createDirectWatcher = filePath => {
|
|||||||
return w;
|
return w;
|
||||||
};
|
};
|
||||||
|
|
||||||
const createRecursiveWatcher = rootPath => {
|
/**
|
||||||
|
* @param {string} rootPath a root path
|
||||||
|
* @returns {RecursiveWatcher} a recursive watcher
|
||||||
|
*/
|
||||||
|
const createRecursiveWatcher = (rootPath) => {
|
||||||
const existing = recursiveWatchers.get(rootPath);
|
const existing = recursiveWatchers.get(rootPath);
|
||||||
if (existing !== undefined) return existing;
|
if (existing !== undefined) return existing;
|
||||||
const w = new RecursiveWatcher(rootPath);
|
const w = new RecursiveWatcher(rootPath);
|
||||||
@@ -248,6 +314,10 @@ const createRecursiveWatcher = rootPath => {
|
|||||||
const execute = () => {
|
const execute = () => {
|
||||||
/** @type {Map<string, Watcher[] | Watcher>} */
|
/** @type {Map<string, Watcher[] | Watcher>} */
|
||||||
const map = new Map();
|
const map = new Map();
|
||||||
|
/**
|
||||||
|
* @param {Watcher} watcher a watcher
|
||||||
|
* @param {string} filePath a file path
|
||||||
|
*/
|
||||||
const addWatcher = (watcher, filePath) => {
|
const addWatcher = (watcher, filePath) => {
|
||||||
const entry = map.get(filePath);
|
const entry = map.get(filePath);
|
||||||
if (entry === undefined) {
|
if (entry === undefined) {
|
||||||
@@ -328,7 +398,30 @@ const execute = () => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.watch = filePath => {
|
module.exports.Watcher = Watcher;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {() => void} fn a function
|
||||||
|
*/
|
||||||
|
module.exports.batch = (fn) => {
|
||||||
|
isBatch = true;
|
||||||
|
try {
|
||||||
|
fn();
|
||||||
|
} finally {
|
||||||
|
isBatch = false;
|
||||||
|
execute();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
module.exports.createHandleChangeEvent = createHandleChangeEvent;
|
||||||
|
|
||||||
|
module.exports.getNumberOfWatchers = () => watcherCount;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filePath a file path
|
||||||
|
* @returns {Watcher} watcher
|
||||||
|
*/
|
||||||
|
module.exports.watch = (filePath) => {
|
||||||
const watcher = new Watcher();
|
const watcher = new Watcher();
|
||||||
// Find an existing watcher
|
// Find an existing watcher
|
||||||
const directWatcher = directWatchers.get(filePath);
|
const directWatcher = directWatchers.get(filePath);
|
||||||
@@ -353,19 +446,4 @@ exports.watch = filePath => {
|
|||||||
return watcher;
|
return watcher;
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.batch = fn => {
|
module.exports.watcherLimit = watcherLimit;
|
||||||
isBatch = true;
|
|
||||||
try {
|
|
||||||
fn();
|
|
||||||
} finally {
|
|
||||||
isBatch = false;
|
|
||||||
execute();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.getNumberOfWatchers = () => {
|
|
||||||
return watcherCount;
|
|
||||||
};
|
|
||||||
|
|
||||||
exports.createHandleChangeEvent = createHandleChangeEvent;
|
|
||||||
exports.watcherLimit = watcherLimit;
|
|
||||||
|
|||||||
391
node_modules/watchpack/lib/watchpack.js
generated
vendored
Executable file → Normal file
391
node_modules/watchpack/lib/watchpack.js
generated
vendored
Executable file → Normal file
@@ -1,393 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
Author Tobias Koppers @sokra
|
Author Alexander Akait @akexander-akait
|
||||||
*/
|
*/
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
const getWatcherManager = require("./getWatcherManager");
|
// TODO remove this file in the next major release
|
||||||
const LinkResolver = require("./LinkResolver");
|
module.exports = require("./index");
|
||||||
const EventEmitter = require("events").EventEmitter;
|
|
||||||
const globToRegExp = require("glob-to-regexp");
|
|
||||||
const watchEventSource = require("./watchEventSource");
|
|
||||||
|
|
||||||
const EMPTY_ARRAY = [];
|
|
||||||
const EMPTY_OPTIONS = {};
|
|
||||||
|
|
||||||
function addWatchersToSet(watchers, set) {
|
|
||||||
for (const ww of watchers) {
|
|
||||||
const w = ww.watcher;
|
|
||||||
if (!set.has(w.directoryWatcher)) {
|
|
||||||
set.add(w.directoryWatcher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const stringToRegexp = ignored => {
|
|
||||||
if (ignored.length === 0) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const source = globToRegExp(ignored, { globstar: true, extended: true })
|
|
||||||
.source;
|
|
||||||
return source.slice(0, source.length - 1) + "(?:$|\\/)";
|
|
||||||
};
|
|
||||||
|
|
||||||
const ignoredToFunction = ignored => {
|
|
||||||
if (Array.isArray(ignored)) {
|
|
||||||
const stringRegexps = ignored.map(i => stringToRegexp(i)).filter(Boolean);
|
|
||||||
if (stringRegexps.length === 0) {
|
|
||||||
return () => false;
|
|
||||||
}
|
|
||||||
const regexp = new RegExp(stringRegexps.join("|"));
|
|
||||||
return x => regexp.test(x.replace(/\\/g, "/"));
|
|
||||||
} else if (typeof ignored === "string") {
|
|
||||||
const stringRegexp = stringToRegexp(ignored);
|
|
||||||
if (!stringRegexp) {
|
|
||||||
return () => false;
|
|
||||||
}
|
|
||||||
const regexp = new RegExp(stringRegexp);
|
|
||||||
return x => regexp.test(x.replace(/\\/g, "/"));
|
|
||||||
} else if (ignored instanceof RegExp) {
|
|
||||||
return x => ignored.test(x.replace(/\\/g, "/"));
|
|
||||||
} else if (ignored instanceof Function) {
|
|
||||||
return ignored;
|
|
||||||
} else if (ignored) {
|
|
||||||
throw new Error(`Invalid option for 'ignored': ${ignored}`);
|
|
||||||
} else {
|
|
||||||
return () => false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const normalizeOptions = options => {
|
|
||||||
return {
|
|
||||||
followSymlinks: !!options.followSymlinks,
|
|
||||||
ignored: ignoredToFunction(options.ignored),
|
|
||||||
poll: options.poll
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
const normalizeCache = new WeakMap();
|
|
||||||
const cachedNormalizeOptions = options => {
|
|
||||||
const cacheEntry = normalizeCache.get(options);
|
|
||||||
if (cacheEntry !== undefined) return cacheEntry;
|
|
||||||
const normalized = normalizeOptions(options);
|
|
||||||
normalizeCache.set(options, normalized);
|
|
||||||
return normalized;
|
|
||||||
};
|
|
||||||
|
|
||||||
class WatchpackFileWatcher {
|
|
||||||
constructor(watchpack, watcher, files) {
|
|
||||||
this.files = Array.isArray(files) ? files : [files];
|
|
||||||
this.watcher = watcher;
|
|
||||||
watcher.on("initial-missing", type => {
|
|
||||||
for (const file of this.files) {
|
|
||||||
if (!watchpack._missing.has(file))
|
|
||||||
watchpack._onRemove(file, file, type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
watcher.on("change", (mtime, type) => {
|
|
||||||
for (const file of this.files) {
|
|
||||||
watchpack._onChange(file, mtime, file, type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
watcher.on("remove", type => {
|
|
||||||
for (const file of this.files) {
|
|
||||||
watchpack._onRemove(file, file, type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update(files) {
|
|
||||||
if (!Array.isArray(files)) {
|
|
||||||
if (this.files.length !== 1) {
|
|
||||||
this.files = [files];
|
|
||||||
} else if (this.files[0] !== files) {
|
|
||||||
this.files[0] = files;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.files = files;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this.watcher.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WatchpackDirectoryWatcher {
|
|
||||||
constructor(watchpack, watcher, directories) {
|
|
||||||
this.directories = Array.isArray(directories) ? directories : [directories];
|
|
||||||
this.watcher = watcher;
|
|
||||||
watcher.on("initial-missing", type => {
|
|
||||||
for (const item of this.directories) {
|
|
||||||
watchpack._onRemove(item, item, type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
watcher.on("change", (file, mtime, type) => {
|
|
||||||
for (const item of this.directories) {
|
|
||||||
watchpack._onChange(item, mtime, file, type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
watcher.on("remove", type => {
|
|
||||||
for (const item of this.directories) {
|
|
||||||
watchpack._onRemove(item, item, type);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
update(directories) {
|
|
||||||
if (!Array.isArray(directories)) {
|
|
||||||
if (this.directories.length !== 1) {
|
|
||||||
this.directories = [directories];
|
|
||||||
} else if (this.directories[0] !== directories) {
|
|
||||||
this.directories[0] = directories;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
this.directories = directories;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this.watcher.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class Watchpack extends EventEmitter {
|
|
||||||
constructor(options) {
|
|
||||||
super();
|
|
||||||
if (!options) options = EMPTY_OPTIONS;
|
|
||||||
this.options = options;
|
|
||||||
this.aggregateTimeout =
|
|
||||||
typeof options.aggregateTimeout === "number"
|
|
||||||
? options.aggregateTimeout
|
|
||||||
: 200;
|
|
||||||
this.watcherOptions = cachedNormalizeOptions(options);
|
|
||||||
this.watcherManager = getWatcherManager(this.watcherOptions);
|
|
||||||
this.fileWatchers = new Map();
|
|
||||||
this.directoryWatchers = new Map();
|
|
||||||
this._missing = new Set();
|
|
||||||
this.startTime = undefined;
|
|
||||||
this.paused = false;
|
|
||||||
this.aggregatedChanges = new Set();
|
|
||||||
this.aggregatedRemovals = new Set();
|
|
||||||
this.aggregateTimer = undefined;
|
|
||||||
this._onTimeout = this._onTimeout.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(arg1, arg2, arg3) {
|
|
||||||
let files, directories, missing, startTime;
|
|
||||||
if (!arg2) {
|
|
||||||
({
|
|
||||||
files = EMPTY_ARRAY,
|
|
||||||
directories = EMPTY_ARRAY,
|
|
||||||
missing = EMPTY_ARRAY,
|
|
||||||
startTime
|
|
||||||
} = arg1);
|
|
||||||
} else {
|
|
||||||
files = arg1;
|
|
||||||
directories = arg2;
|
|
||||||
missing = EMPTY_ARRAY;
|
|
||||||
startTime = arg3;
|
|
||||||
}
|
|
||||||
this.paused = false;
|
|
||||||
const fileWatchers = this.fileWatchers;
|
|
||||||
const directoryWatchers = this.directoryWatchers;
|
|
||||||
const ignored = this.watcherOptions.ignored;
|
|
||||||
const filter = path => !ignored(path);
|
|
||||||
const addToMap = (map, key, item) => {
|
|
||||||
const list = map.get(key);
|
|
||||||
if (list === undefined) {
|
|
||||||
map.set(key, item);
|
|
||||||
} else if (Array.isArray(list)) {
|
|
||||||
list.push(item);
|
|
||||||
} else {
|
|
||||||
map.set(key, [list, item]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
const fileWatchersNeeded = new Map();
|
|
||||||
const directoryWatchersNeeded = new Map();
|
|
||||||
const missingFiles = new Set();
|
|
||||||
if (this.watcherOptions.followSymlinks) {
|
|
||||||
const resolver = new LinkResolver();
|
|
||||||
for (const file of files) {
|
|
||||||
if (filter(file)) {
|
|
||||||
for (const innerFile of resolver.resolve(file)) {
|
|
||||||
if (file === innerFile || filter(innerFile)) {
|
|
||||||
addToMap(fileWatchersNeeded, innerFile, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const file of missing) {
|
|
||||||
if (filter(file)) {
|
|
||||||
for (const innerFile of resolver.resolve(file)) {
|
|
||||||
if (file === innerFile || filter(innerFile)) {
|
|
||||||
missingFiles.add(file);
|
|
||||||
addToMap(fileWatchersNeeded, innerFile, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const dir of directories) {
|
|
||||||
if (filter(dir)) {
|
|
||||||
let first = true;
|
|
||||||
for (const innerItem of resolver.resolve(dir)) {
|
|
||||||
if (filter(innerItem)) {
|
|
||||||
addToMap(
|
|
||||||
first ? directoryWatchersNeeded : fileWatchersNeeded,
|
|
||||||
innerItem,
|
|
||||||
dir
|
|
||||||
);
|
|
||||||
}
|
|
||||||
first = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (const file of files) {
|
|
||||||
if (filter(file)) {
|
|
||||||
addToMap(fileWatchersNeeded, file, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const file of missing) {
|
|
||||||
if (filter(file)) {
|
|
||||||
missingFiles.add(file);
|
|
||||||
addToMap(fileWatchersNeeded, file, file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const dir of directories) {
|
|
||||||
if (filter(dir)) {
|
|
||||||
addToMap(directoryWatchersNeeded, dir, dir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Close unneeded old watchers
|
|
||||||
// and update existing watchers
|
|
||||||
for (const [key, w] of fileWatchers) {
|
|
||||||
const needed = fileWatchersNeeded.get(key);
|
|
||||||
if (needed === undefined) {
|
|
||||||
w.close();
|
|
||||||
fileWatchers.delete(key);
|
|
||||||
} else {
|
|
||||||
w.update(needed);
|
|
||||||
fileWatchersNeeded.delete(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const [key, w] of directoryWatchers) {
|
|
||||||
const needed = directoryWatchersNeeded.get(key);
|
|
||||||
if (needed === undefined) {
|
|
||||||
w.close();
|
|
||||||
directoryWatchers.delete(key);
|
|
||||||
} else {
|
|
||||||
w.update(needed);
|
|
||||||
directoryWatchersNeeded.delete(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Create new watchers and install handlers on these watchers
|
|
||||||
watchEventSource.batch(() => {
|
|
||||||
for (const [key, files] of fileWatchersNeeded) {
|
|
||||||
const watcher = this.watcherManager.watchFile(key, startTime);
|
|
||||||
if (watcher) {
|
|
||||||
fileWatchers.set(key, new WatchpackFileWatcher(this, watcher, files));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (const [key, directories] of directoryWatchersNeeded) {
|
|
||||||
const watcher = this.watcherManager.watchDirectory(key, startTime);
|
|
||||||
if (watcher) {
|
|
||||||
directoryWatchers.set(
|
|
||||||
key,
|
|
||||||
new WatchpackDirectoryWatcher(this, watcher, directories)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this._missing = missingFiles;
|
|
||||||
this.startTime = startTime;
|
|
||||||
}
|
|
||||||
|
|
||||||
close() {
|
|
||||||
this.paused = true;
|
|
||||||
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
|
||||||
for (const w of this.fileWatchers.values()) w.close();
|
|
||||||
for (const w of this.directoryWatchers.values()) w.close();
|
|
||||||
this.fileWatchers.clear();
|
|
||||||
this.directoryWatchers.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
pause() {
|
|
||||||
this.paused = true;
|
|
||||||
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
|
||||||
}
|
|
||||||
|
|
||||||
getTimes() {
|
|
||||||
const directoryWatchers = new Set();
|
|
||||||
addWatchersToSet(this.fileWatchers.values(), directoryWatchers);
|
|
||||||
addWatchersToSet(this.directoryWatchers.values(), directoryWatchers);
|
|
||||||
const obj = Object.create(null);
|
|
||||||
for (const w of directoryWatchers) {
|
|
||||||
const times = w.getTimes();
|
|
||||||
for (const file of Object.keys(times)) obj[file] = times[file];
|
|
||||||
}
|
|
||||||
return obj;
|
|
||||||
}
|
|
||||||
|
|
||||||
getTimeInfoEntries() {
|
|
||||||
const map = new Map();
|
|
||||||
this.collectTimeInfoEntries(map, map);
|
|
||||||
return map;
|
|
||||||
}
|
|
||||||
|
|
||||||
collectTimeInfoEntries(fileTimestamps, directoryTimestamps) {
|
|
||||||
const allWatchers = new Set();
|
|
||||||
addWatchersToSet(this.fileWatchers.values(), allWatchers);
|
|
||||||
addWatchersToSet(this.directoryWatchers.values(), allWatchers);
|
|
||||||
const safeTime = { value: 0 };
|
|
||||||
for (const w of allWatchers) {
|
|
||||||
w.collectTimeInfoEntries(fileTimestamps, directoryTimestamps, safeTime);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getAggregated() {
|
|
||||||
if (this.aggregateTimer) {
|
|
||||||
clearTimeout(this.aggregateTimer);
|
|
||||||
this.aggregateTimer = undefined;
|
|
||||||
}
|
|
||||||
const changes = this.aggregatedChanges;
|
|
||||||
const removals = this.aggregatedRemovals;
|
|
||||||
this.aggregatedChanges = new Set();
|
|
||||||
this.aggregatedRemovals = new Set();
|
|
||||||
return { changes, removals };
|
|
||||||
}
|
|
||||||
|
|
||||||
_onChange(item, mtime, file, type) {
|
|
||||||
file = file || item;
|
|
||||||
if (!this.paused) {
|
|
||||||
this.emit("change", file, mtime, type);
|
|
||||||
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
|
||||||
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
|
|
||||||
}
|
|
||||||
this.aggregatedRemovals.delete(item);
|
|
||||||
this.aggregatedChanges.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onRemove(item, file, type) {
|
|
||||||
file = file || item;
|
|
||||||
if (!this.paused) {
|
|
||||||
this.emit("remove", file, type);
|
|
||||||
if (this.aggregateTimer) clearTimeout(this.aggregateTimer);
|
|
||||||
this.aggregateTimer = setTimeout(this._onTimeout, this.aggregateTimeout);
|
|
||||||
}
|
|
||||||
this.aggregatedChanges.delete(item);
|
|
||||||
this.aggregatedRemovals.add(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
_onTimeout() {
|
|
||||||
this.aggregateTimer = undefined;
|
|
||||||
const changes = this.aggregatedChanges;
|
|
||||||
const removals = this.aggregatedRemovals;
|
|
||||||
this.aggregatedChanges = new Set();
|
|
||||||
this.aggregatedRemovals = new Set();
|
|
||||||
this.emit("aggregated", changes, removals);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = Watchpack;
|
|
||||||
|
|||||||
85
node_modules/watchpack/package.json
generated
vendored
Executable file → Normal file
85
node_modules/watchpack/package.json
generated
vendored
Executable file → Normal file
@@ -1,48 +1,73 @@
|
|||||||
{
|
{
|
||||||
"name": "watchpack",
|
"name": "watchpack",
|
||||||
"version": "2.4.4",
|
"version": "2.5.0",
|
||||||
"description": "",
|
"description": "",
|
||||||
"main": "./lib/watchpack.js",
|
"homepage": "https://github.com/webpack/watchpack",
|
||||||
"directories": {
|
"bugs": {
|
||||||
"test": "test"
|
"url": "https://github.com/webpack/watchpack/issues"
|
||||||
},
|
|
||||||
"files": [
|
|
||||||
"lib/"
|
|
||||||
],
|
|
||||||
"scripts": {
|
|
||||||
"pretty-files": "prettier \"lib/**.*\" \"test/**/*.js\" --write",
|
|
||||||
"lint": "eslint lib",
|
|
||||||
"test:only": "mocha",
|
|
||||||
"test:coverage": "istanbul cover node_modules/mocha/bin/_mocha",
|
|
||||||
"pretest": "yarn lint",
|
|
||||||
"test": "mocha"
|
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "https://github.com/webpack/watchpack.git"
|
"url": "https://github.com/webpack/watchpack.git"
|
||||||
},
|
},
|
||||||
"author": "Tobias Koppers @sokra",
|
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"bugs": {
|
"author": "Tobias Koppers @sokra",
|
||||||
"url": "https://github.com/webpack/watchpack/issues"
|
"main": "lib/index.js",
|
||||||
|
"types": "types/index.js",
|
||||||
|
"directories": {
|
||||||
|
"test": "test"
|
||||||
},
|
},
|
||||||
"homepage": "https://github.com/webpack/watchpack",
|
"files": [
|
||||||
"devDependencies": {
|
"lib/",
|
||||||
"coveralls": "^3.0.0",
|
"types/"
|
||||||
"eslint": "^5.11.1",
|
],
|
||||||
"eslint-config-prettier": "^4.3.0",
|
"scripts": {
|
||||||
"eslint-plugin-prettier": "^3.1.0",
|
"lint": "npm run lint:code && npm run lint:types && npm run lint:types-test && npm run lint:declarations && npm run fmt:check",
|
||||||
"istanbul": "^0.4.3",
|
"lint:code": "eslint --cache .",
|
||||||
"mocha": "^5.0.1",
|
"lint:types": "tsc",
|
||||||
"prettier": "^1.11.0",
|
"lint:types-test": "tsc -p tsconfig.types.test.json",
|
||||||
"rimraf": "^2.6.2",
|
"lint:declarations": "npm run fix:declarations && git diff --exit-code ./types",
|
||||||
"should": "^8.3.1",
|
"fix": "npm run fix:code && npm run fix:declarations",
|
||||||
"write-file-atomic": "^3.0.1"
|
"fix:code": "npm run lint:code -- --fix",
|
||||||
|
"fix:declarations": "tsc --noEmit false --declaration --emitDeclarationOnly --outDir types && npm run fmt -- ./types",
|
||||||
|
"fmt": "npm run fmt:base -- --log-level warn --write",
|
||||||
|
"fmt:check": "npm run fmt:base -- --check",
|
||||||
|
"fmt:base": "prettier --cache --ignore-unknown .",
|
||||||
|
"pretest": "npm run lint",
|
||||||
|
"test": "npm run test:coverage",
|
||||||
|
"test:base": "jest --runInBand",
|
||||||
|
"test:only": "npm run test:base",
|
||||||
|
"test:watch": "npm run test:base -- --watch",
|
||||||
|
"test:coverage": "npm run test:base -- --collectCoverageFrom=\"lib/**/*.js\" --coverage"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
"graceful-fs": "^4.1.2"
|
"graceful-fs": "^4.1.2"
|
||||||
},
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@eslint/js": "^9.28.0",
|
||||||
|
"@eslint/markdown": "^7.5.1",
|
||||||
|
"@stylistic/eslint-plugin": "^5.6.1",
|
||||||
|
"@types/glob-to-regexp": "^0.4.4",
|
||||||
|
"@types/graceful-fs": "^4.1.9",
|
||||||
|
"@types/jest": "^27.5.1",
|
||||||
|
"@types/node": "^24.10.4",
|
||||||
|
"eslint": "^9.39.2",
|
||||||
|
"eslint-config-prettier": "^10.1.8",
|
||||||
|
"eslint-config-webpack": "^4.7.3",
|
||||||
|
"eslint-plugin-import": "^2.32.0",
|
||||||
|
"eslint-plugin-jest": "^29.5.0",
|
||||||
|
"eslint-plugin-jsdoc": "^61.5.0",
|
||||||
|
"eslint-plugin-n": "^17.23.1",
|
||||||
|
"eslint-plugin-prettier": "^5.5.4",
|
||||||
|
"eslint-plugin-unicorn": "^62.0.0",
|
||||||
|
"globals": "^16.5.0",
|
||||||
|
"jest": "^27.5.1",
|
||||||
|
"prettier": "^3.7.4",
|
||||||
|
"rimraf": "^2.6.2",
|
||||||
|
"typescript": "^5.9.3",
|
||||||
|
"write-file-atomic": "^3.0.1"
|
||||||
|
},
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=10.13.0"
|
"node": ">=10.13.0"
|
||||||
}
|
}
|
||||||
|
|||||||
333
node_modules/watchpack/types/DirectoryWatcher.d.ts
generated
vendored
Normal file
333
node_modules/watchpack/types/DirectoryWatcher.d.ts
generated
vendored
Normal file
@@ -0,0 +1,333 @@
|
|||||||
|
export = DirectoryWatcher;
|
||||||
|
/** @typedef {Set<string>} InitialScanRemoved */
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatchpackEvents
|
||||||
|
* @property {(target: string, mtime: string, type: EventType, initial: boolean) => void} change change event
|
||||||
|
* @property {() => void} closed closed event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @typedef {object} DirectoryWatcherOptions
|
||||||
|
* @property {boolean=} followSymlinks true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
* @property {IgnoredFunction=} ignored ignore some files from watching (glob pattern or regexp)
|
||||||
|
* @property {number | boolean=} poll true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @extends {EventEmitter<{ [K in keyof WatchpackEvents]: Parameters<WatchpackEvents[K]> }>}
|
||||||
|
*/
|
||||||
|
declare class DirectoryWatcher extends EventEmitter<{
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: [
|
||||||
|
target: string,
|
||||||
|
mtime: string,
|
||||||
|
type: import("./index").EventType,
|
||||||
|
initial: boolean,
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* closed event
|
||||||
|
*/
|
||||||
|
closed: [];
|
||||||
|
}> {
|
||||||
|
/**
|
||||||
|
* @param {WatcherManager} watcherManager a watcher manager
|
||||||
|
* @param {string} directoryPath directory path
|
||||||
|
* @param {DirectoryWatcherOptions=} options options
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
watcherManager: WatcherManager,
|
||||||
|
directoryPath: string,
|
||||||
|
options?: DirectoryWatcherOptions | undefined,
|
||||||
|
);
|
||||||
|
watcherManager: import("./getWatcherManager").WatcherManager;
|
||||||
|
options: DirectoryWatcherOptions;
|
||||||
|
path: string;
|
||||||
|
/** @type {Map<string, Entry>} */
|
||||||
|
files: Map<string, Entry>;
|
||||||
|
/** @type {Map<string, number>} */
|
||||||
|
filesWithoutCase: Map<string, number>;
|
||||||
|
/** @type {Map<string, Watcher<DirectoryWatcherEvents> | boolean>} */
|
||||||
|
directories: Map<string, Watcher<DirectoryWatcherEvents> | boolean>;
|
||||||
|
lastWatchEvent: number;
|
||||||
|
initialScan: boolean;
|
||||||
|
ignored: import("./index").IgnoredFunction;
|
||||||
|
nestedWatching: boolean;
|
||||||
|
/** @type {number | false} */
|
||||||
|
polledWatching: number | false;
|
||||||
|
/** @type {undefined | NodeJS.Timeout} */
|
||||||
|
timeout: undefined | NodeJS.Timeout;
|
||||||
|
/** @type {null | InitialScanRemoved} */
|
||||||
|
initialScanRemoved: null | InitialScanRemoved;
|
||||||
|
/** @type {undefined | number} */
|
||||||
|
initialScanFinished: undefined | number;
|
||||||
|
/** @type {Map<string, Set<Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>>>} */
|
||||||
|
watchers: Map<
|
||||||
|
string,
|
||||||
|
Set<Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>>
|
||||||
|
>;
|
||||||
|
/** @type {Watcher<FileWatcherEvents> | null} */
|
||||||
|
parentWatcher: Watcher<FileWatcherEvents> | null;
|
||||||
|
refs: number;
|
||||||
|
/** @type {Map<string, boolean>} */
|
||||||
|
_activeEvents: Map<string, boolean>;
|
||||||
|
closed: boolean;
|
||||||
|
scanning: boolean;
|
||||||
|
scanAgain: boolean;
|
||||||
|
scanAgainInitial: boolean;
|
||||||
|
createWatcher(): void;
|
||||||
|
watcher: watchEventSource.Watcher | null | undefined;
|
||||||
|
/**
|
||||||
|
* @template {(watcher: Watcher<EventMap>) => void} T
|
||||||
|
* @param {string} path path
|
||||||
|
* @param {T} fn function
|
||||||
|
*/
|
||||||
|
forEachWatcher<T extends (watcher: Watcher<EventMap>) => void>(
|
||||||
|
path: string,
|
||||||
|
fn: T,
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @param {string} itemPath an item path
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @param {EventType} type even type
|
||||||
|
*/
|
||||||
|
setMissing(itemPath: string, initial: boolean, type: EventType): void;
|
||||||
|
/**
|
||||||
|
* @param {string} target a target to set file time
|
||||||
|
* @param {number} mtime mtime
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @param {boolean} ignoreWhenEqual true to ignore when equal, otherwise false
|
||||||
|
* @param {EventType} type type
|
||||||
|
*/
|
||||||
|
setFileTime(
|
||||||
|
target: string,
|
||||||
|
mtime: number,
|
||||||
|
initial: boolean,
|
||||||
|
ignoreWhenEqual: boolean,
|
||||||
|
type: EventType,
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @param {string} directoryPath directory path
|
||||||
|
* @param {number} birthtime birthtime
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @param {EventType} type even type
|
||||||
|
*/
|
||||||
|
setDirectory(
|
||||||
|
directoryPath: string,
|
||||||
|
birthtime: number,
|
||||||
|
initial: boolean,
|
||||||
|
type: EventType,
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @param {string} directoryPath directory path
|
||||||
|
*/
|
||||||
|
createNestedWatcher(directoryPath: string): void;
|
||||||
|
/**
|
||||||
|
* @param {boolean} flag true when nested, otherwise false
|
||||||
|
*/
|
||||||
|
setNestedWatching(flag: boolean): void;
|
||||||
|
/**
|
||||||
|
* @param {string} target a target to watch
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
* @returns {Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>} watcher
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
target: string,
|
||||||
|
startTime?: number | undefined,
|
||||||
|
): Watcher<DirectoryWatcherEvents> | Watcher<FileWatcherEvents>;
|
||||||
|
/**
|
||||||
|
* @param {EventType} eventType event type
|
||||||
|
* @param {string=} filename filename
|
||||||
|
*/
|
||||||
|
onWatchEvent(eventType: EventType, filename?: string | undefined): void;
|
||||||
|
/**
|
||||||
|
* @param {unknown=} err error
|
||||||
|
*/
|
||||||
|
onWatcherError(err?: unknown | undefined): void;
|
||||||
|
/**
|
||||||
|
* @param {Error | NodeJS.ErrnoException=} err error
|
||||||
|
*/
|
||||||
|
onStatsError(err?: (Error | NodeJS.ErrnoException) | undefined): void;
|
||||||
|
/**
|
||||||
|
* @param {Error | NodeJS.ErrnoException=} err error
|
||||||
|
*/
|
||||||
|
onScanError(err?: (Error | NodeJS.ErrnoException) | undefined): void;
|
||||||
|
onScanFinished(): void;
|
||||||
|
/**
|
||||||
|
* @param {string} reason a reason
|
||||||
|
*/
|
||||||
|
onDirectoryRemoved(reason: string): void;
|
||||||
|
watchInParentDirectory(): void;
|
||||||
|
/**
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
*/
|
||||||
|
doScan(initial: boolean): void;
|
||||||
|
/**
|
||||||
|
* @returns {Record<string, number>} times
|
||||||
|
*/
|
||||||
|
getTimes(): Record<string, number>;
|
||||||
|
/**
|
||||||
|
* @param {TimeInfoEntries} fileTimestamps file timestamps
|
||||||
|
* @param {TimeInfoEntries} directoryTimestamps directory timestamps
|
||||||
|
* @returns {number} safe time
|
||||||
|
*/
|
||||||
|
collectTimeInfoEntries(
|
||||||
|
fileTimestamps: TimeInfoEntries,
|
||||||
|
directoryTimestamps: TimeInfoEntries,
|
||||||
|
): number;
|
||||||
|
close(): void;
|
||||||
|
}
|
||||||
|
declare namespace DirectoryWatcher {
|
||||||
|
export {
|
||||||
|
EXISTANCE_ONLY_TIME_ENTRY,
|
||||||
|
Watcher,
|
||||||
|
IgnoredFunction,
|
||||||
|
EventType,
|
||||||
|
TimeInfoEntries,
|
||||||
|
Entry,
|
||||||
|
ExistanceOnlyTimeEntry,
|
||||||
|
OnlySafeTimeEntry,
|
||||||
|
EventMap,
|
||||||
|
WatcherManager,
|
||||||
|
EventSourceWatcher,
|
||||||
|
FileWatcherEvents,
|
||||||
|
DirectoryWatcherEvents,
|
||||||
|
InitialScanRemoved,
|
||||||
|
WatchpackEvents,
|
||||||
|
DirectoryWatcherOptions,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
import { EventEmitter } from "events";
|
||||||
|
/**
|
||||||
|
* @typedef {object} FileWatcherEvents
|
||||||
|
* @property {(type: EventType) => void} initial-missing initial missing event
|
||||||
|
* @property {(mtime: number, type: EventType, initial: boolean) => void} change change event
|
||||||
|
* @property {(type: EventType) => void} remove remove event
|
||||||
|
* @property {() => void} closed closed event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @typedef {object} DirectoryWatcherEvents
|
||||||
|
* @property {(type: EventType) => void} initial-missing initial missing event
|
||||||
|
* @property {((file: string, mtime: number, type: EventType, initial: boolean) => void)} change change event
|
||||||
|
* @property {(type: EventType) => void} remove remove event
|
||||||
|
* @property {() => void} closed closed event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @template {EventMap} T
|
||||||
|
* @extends {EventEmitter<{ [K in keyof T]: Parameters<T[K]> }>}
|
||||||
|
*/
|
||||||
|
declare class Watcher<T extends EventMap> extends EventEmitter<{
|
||||||
|
[K in keyof T]: Parameters<T[K]>;
|
||||||
|
}> {
|
||||||
|
/**
|
||||||
|
* @param {DirectoryWatcher} directoryWatcher a directory watcher
|
||||||
|
* @param {string} target a target to watch
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
directoryWatcher: DirectoryWatcher,
|
||||||
|
target: string,
|
||||||
|
startTime?: number | undefined,
|
||||||
|
);
|
||||||
|
directoryWatcher: DirectoryWatcher;
|
||||||
|
path: string;
|
||||||
|
startTime: number | undefined;
|
||||||
|
/**
|
||||||
|
* @param {number} mtime mtime
|
||||||
|
* @param {boolean} initial true when initial, otherwise false
|
||||||
|
* @returns {boolean} true of start time less than mtile, otherwise false
|
||||||
|
*/
|
||||||
|
checkStartTime(mtime: number, initial: boolean): boolean;
|
||||||
|
close(): void;
|
||||||
|
}
|
||||||
|
import watchEventSource = require("./watchEventSource");
|
||||||
|
/** @typedef {import("./index").IgnoredFunction} IgnoredFunction */
|
||||||
|
/** @typedef {import("./index").EventType} EventType */
|
||||||
|
/** @typedef {import("./index").TimeInfoEntries} TimeInfoEntries */
|
||||||
|
/** @typedef {import("./index").Entry} Entry */
|
||||||
|
/** @typedef {import("./index").ExistanceOnlyTimeEntry} ExistanceOnlyTimeEntry */
|
||||||
|
/** @typedef {import("./index").OnlySafeTimeEntry} OnlySafeTimeEntry */
|
||||||
|
/** @typedef {import("./index").EventMap} EventMap */
|
||||||
|
/** @typedef {import("./getWatcherManager").WatcherManager} WatcherManager */
|
||||||
|
/** @typedef {import("./watchEventSource").Watcher} EventSourceWatcher */
|
||||||
|
/** @type {ExistanceOnlyTimeEntry} */
|
||||||
|
declare const EXISTANCE_ONLY_TIME_ENTRY: ExistanceOnlyTimeEntry;
|
||||||
|
type IgnoredFunction = import("./index").IgnoredFunction;
|
||||||
|
type EventType = import("./index").EventType;
|
||||||
|
type TimeInfoEntries = import("./index").TimeInfoEntries;
|
||||||
|
type Entry = import("./index").Entry;
|
||||||
|
type ExistanceOnlyTimeEntry = import("./index").ExistanceOnlyTimeEntry;
|
||||||
|
type OnlySafeTimeEntry = import("./index").OnlySafeTimeEntry;
|
||||||
|
type EventMap = import("./index").EventMap;
|
||||||
|
type WatcherManager = import("./getWatcherManager").WatcherManager;
|
||||||
|
type EventSourceWatcher = import("./watchEventSource").Watcher;
|
||||||
|
type FileWatcherEvents = {
|
||||||
|
/**
|
||||||
|
* initial missing event
|
||||||
|
*/
|
||||||
|
"initial-missing": (type: EventType) => void;
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: (mtime: number, type: EventType, initial: boolean) => void;
|
||||||
|
/**
|
||||||
|
* remove event
|
||||||
|
*/
|
||||||
|
remove: (type: EventType) => void;
|
||||||
|
/**
|
||||||
|
* closed event
|
||||||
|
*/
|
||||||
|
closed: () => void;
|
||||||
|
};
|
||||||
|
type DirectoryWatcherEvents = {
|
||||||
|
/**
|
||||||
|
* initial missing event
|
||||||
|
*/
|
||||||
|
"initial-missing": (type: EventType) => void;
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: (
|
||||||
|
file: string,
|
||||||
|
mtime: number,
|
||||||
|
type: EventType,
|
||||||
|
initial: boolean,
|
||||||
|
) => void;
|
||||||
|
/**
|
||||||
|
* remove event
|
||||||
|
*/
|
||||||
|
remove: (type: EventType) => void;
|
||||||
|
/**
|
||||||
|
* closed event
|
||||||
|
*/
|
||||||
|
closed: () => void;
|
||||||
|
};
|
||||||
|
type InitialScanRemoved = Set<string>;
|
||||||
|
type WatchpackEvents = {
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: (
|
||||||
|
target: string,
|
||||||
|
mtime: string,
|
||||||
|
type: EventType,
|
||||||
|
initial: boolean,
|
||||||
|
) => void;
|
||||||
|
/**
|
||||||
|
* closed event
|
||||||
|
*/
|
||||||
|
closed: () => void;
|
||||||
|
};
|
||||||
|
type DirectoryWatcherOptions = {
|
||||||
|
/**
|
||||||
|
* true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
*/
|
||||||
|
followSymlinks?: boolean | undefined;
|
||||||
|
/**
|
||||||
|
* ignore some files from watching (glob pattern or regexp)
|
||||||
|
*/
|
||||||
|
ignored?: IgnoredFunction | undefined;
|
||||||
|
/**
|
||||||
|
* true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
poll?: (number | boolean) | undefined;
|
||||||
|
};
|
||||||
10
node_modules/watchpack/types/LinkResolver.d.ts
generated
vendored
Normal file
10
node_modules/watchpack/types/LinkResolver.d.ts
generated
vendored
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export = LinkResolver;
|
||||||
|
declare class LinkResolver {
|
||||||
|
/** @type {Map<string, readonly string[]>} */
|
||||||
|
cache: Map<string, readonly string[]>;
|
||||||
|
/**
|
||||||
|
* @param {string} file path to file or directory
|
||||||
|
* @returns {readonly string[]} array of file and all symlinks contributed in the resolving process (first item is the resolved file)
|
||||||
|
*/
|
||||||
|
resolve(file: string): readonly string[];
|
||||||
|
}
|
||||||
62
node_modules/watchpack/types/getWatcherManager.d.ts
generated
vendored
Normal file
62
node_modules/watchpack/types/getWatcherManager.d.ts
generated
vendored
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
declare namespace _exports {
|
||||||
|
export {
|
||||||
|
EventMap,
|
||||||
|
DirectoryWatcherOptions,
|
||||||
|
DirectoryWatcherEvents,
|
||||||
|
FileWatcherEvents,
|
||||||
|
Watcher,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
declare function _exports(options: DirectoryWatcherOptions): WatcherManager;
|
||||||
|
declare namespace _exports {
|
||||||
|
export { WatcherManager };
|
||||||
|
}
|
||||||
|
export = _exports;
|
||||||
|
type EventMap = import("./index").EventMap;
|
||||||
|
type DirectoryWatcherOptions =
|
||||||
|
import("./DirectoryWatcher").DirectoryWatcherOptions;
|
||||||
|
type DirectoryWatcherEvents =
|
||||||
|
import("./DirectoryWatcher").DirectoryWatcherEvents;
|
||||||
|
type FileWatcherEvents = import("./DirectoryWatcher").FileWatcherEvents;
|
||||||
|
type Watcher<T extends EventMap> = import("./DirectoryWatcher").Watcher<T>;
|
||||||
|
/** @typedef {import("./index").EventMap} EventMap */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").DirectoryWatcherOptions} DirectoryWatcherOptions */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").DirectoryWatcherEvents} DirectoryWatcherEvents */
|
||||||
|
/** @typedef {import("./DirectoryWatcher").FileWatcherEvents} FileWatcherEvents */
|
||||||
|
/**
|
||||||
|
* @template {EventMap} T
|
||||||
|
* @typedef {import("./DirectoryWatcher").Watcher<T>} Watcher
|
||||||
|
*/
|
||||||
|
declare class WatcherManager {
|
||||||
|
/**
|
||||||
|
* @param {DirectoryWatcherOptions=} options options
|
||||||
|
*/
|
||||||
|
constructor(options?: DirectoryWatcherOptions | undefined);
|
||||||
|
options: DirectoryWatcher.DirectoryWatcherOptions;
|
||||||
|
/** @type {Map<string, DirectoryWatcher>} */
|
||||||
|
directoryWatchers: Map<string, DirectoryWatcher>;
|
||||||
|
/**
|
||||||
|
* @param {string} directory a directory
|
||||||
|
* @returns {DirectoryWatcher} a directory watcher
|
||||||
|
*/
|
||||||
|
getDirectoryWatcher(directory: string): DirectoryWatcher;
|
||||||
|
/**
|
||||||
|
* @param {string} file file
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
* @returns {Watcher<FileWatcherEvents> | null} watcher or null if file has no directory
|
||||||
|
*/
|
||||||
|
watchFile(
|
||||||
|
file: string,
|
||||||
|
startTime?: number | undefined,
|
||||||
|
): Watcher<FileWatcherEvents> | null;
|
||||||
|
/**
|
||||||
|
* @param {string} directory directory
|
||||||
|
* @param {number=} startTime start time
|
||||||
|
* @returns {Watcher<DirectoryWatcherEvents>} watcher
|
||||||
|
*/
|
||||||
|
watchDirectory(
|
||||||
|
directory: string,
|
||||||
|
startTime?: number | undefined,
|
||||||
|
): Watcher<DirectoryWatcherEvents>;
|
||||||
|
}
|
||||||
|
import DirectoryWatcher = require("./DirectoryWatcher");
|
||||||
261
node_modules/watchpack/types/index.d.ts
generated
vendored
Normal file
261
node_modules/watchpack/types/index.d.ts
generated
vendored
Normal file
@@ -0,0 +1,261 @@
|
|||||||
|
export = Watchpack;
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatchpackEvents
|
||||||
|
* @property {(file: string, mtime: number, type: EventType) => void} change change event
|
||||||
|
* @property {(file: string, type: EventType) => void} remove remove event
|
||||||
|
* @property {(changes: Changes, removals: Removals) => void} aggregated aggregated event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @extends {EventEmitter<{ [K in keyof WatchpackEvents]: Parameters<WatchpackEvents[K]> }>}
|
||||||
|
*/
|
||||||
|
declare class Watchpack extends EventEmitter<{
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: [file: string, mtime: number, type: EventType];
|
||||||
|
/**
|
||||||
|
* remove event
|
||||||
|
*/
|
||||||
|
remove: [file: string, type: EventType];
|
||||||
|
/**
|
||||||
|
* aggregated event
|
||||||
|
*/
|
||||||
|
aggregated: [changes: Changes, removals: Removals];
|
||||||
|
}> {
|
||||||
|
/**
|
||||||
|
* @param {WatchOptions=} options options
|
||||||
|
*/
|
||||||
|
constructor(options?: WatchOptions | undefined);
|
||||||
|
/** @type {WatchOptions} */
|
||||||
|
options: WatchOptions;
|
||||||
|
aggregateTimeout: number;
|
||||||
|
/** @type {NormalizedWatchOptions} */
|
||||||
|
watcherOptions: NormalizedWatchOptions;
|
||||||
|
/** @type {WatcherManager} */
|
||||||
|
watcherManager: WatcherManager;
|
||||||
|
/** @type {Map<string, WatchpackFileWatcher>} */
|
||||||
|
fileWatchers: Map<string, WatchpackFileWatcher>;
|
||||||
|
/** @type {Map<string, WatchpackDirectoryWatcher>} */
|
||||||
|
directoryWatchers: Map<string, WatchpackDirectoryWatcher>;
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
_missing: Set<string>;
|
||||||
|
startTime: number | undefined;
|
||||||
|
paused: boolean;
|
||||||
|
/** @type {Changes} */
|
||||||
|
aggregatedChanges: Changes;
|
||||||
|
/** @type {Removals} */
|
||||||
|
aggregatedRemovals: Removals;
|
||||||
|
/** @type {undefined | NodeJS.Timeout} */
|
||||||
|
aggregateTimer: undefined | NodeJS.Timeout;
|
||||||
|
_onTimeout(): void;
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
* @param {Iterable<string>} arg1 files
|
||||||
|
* @param {Iterable<string>} arg2 directories
|
||||||
|
* @param {number=} arg3 startTime
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
watch(
|
||||||
|
arg1: Iterable<string>,
|
||||||
|
arg2: Iterable<string>,
|
||||||
|
arg3?: number | undefined,
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @overload
|
||||||
|
* @param {WatchMethodOptions} arg1 watch options
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
watch(arg1: WatchMethodOptions): void;
|
||||||
|
close(): void;
|
||||||
|
pause(): void;
|
||||||
|
/**
|
||||||
|
* @returns {Record<string, number>} times
|
||||||
|
*/
|
||||||
|
getTimes(): Record<string, number>;
|
||||||
|
/**
|
||||||
|
* @returns {TimeInfoEntries} time info entries
|
||||||
|
*/
|
||||||
|
getTimeInfoEntries(): TimeInfoEntries;
|
||||||
|
/**
|
||||||
|
* @param {TimeInfoEntries} fileTimestamps file timestamps
|
||||||
|
* @param {TimeInfoEntries} directoryTimestamps directory timestamps
|
||||||
|
*/
|
||||||
|
collectTimeInfoEntries(
|
||||||
|
fileTimestamps: TimeInfoEntries,
|
||||||
|
directoryTimestamps: TimeInfoEntries,
|
||||||
|
): void;
|
||||||
|
/**
|
||||||
|
* @returns {Aggregated} aggregated info
|
||||||
|
*/
|
||||||
|
getAggregated(): Aggregated;
|
||||||
|
/**
|
||||||
|
* @param {string} item item
|
||||||
|
* @param {number} mtime mtime
|
||||||
|
* @param {string} file file
|
||||||
|
* @param {EventType} type type
|
||||||
|
*/
|
||||||
|
_onChange(item: string, mtime: number, file: string, type: EventType): void;
|
||||||
|
/**
|
||||||
|
* @param {string} item item
|
||||||
|
* @param {string} file file
|
||||||
|
* @param {EventType} type type
|
||||||
|
*/
|
||||||
|
_onRemove(item: string, file: string, type: EventType): void;
|
||||||
|
}
|
||||||
|
declare namespace Watchpack {
|
||||||
|
export {
|
||||||
|
WatcherManager,
|
||||||
|
DirectoryWatcher,
|
||||||
|
DirectoryWatcherEvents,
|
||||||
|
FileWatcherEvents,
|
||||||
|
EventMap,
|
||||||
|
Watcher,
|
||||||
|
IgnoredFunction,
|
||||||
|
Ignored,
|
||||||
|
WatcherOptions,
|
||||||
|
WatchOptions,
|
||||||
|
NormalizedWatchOptions,
|
||||||
|
EventType,
|
||||||
|
Entry,
|
||||||
|
OnlySafeTimeEntry,
|
||||||
|
ExistanceOnlyTimeEntry,
|
||||||
|
TimeInfoEntries,
|
||||||
|
Changes,
|
||||||
|
Removals,
|
||||||
|
Aggregated,
|
||||||
|
WatchMethodOptions,
|
||||||
|
Times,
|
||||||
|
WatchpackEvents,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
import { EventEmitter } from "events";
|
||||||
|
declare class WatchpackFileWatcher {
|
||||||
|
/**
|
||||||
|
* @param {Watchpack} watchpack watchpack
|
||||||
|
* @param {Watcher<FileWatcherEvents>} watcher watcher
|
||||||
|
* @param {string | string[]} files files
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
watchpack: Watchpack,
|
||||||
|
watcher: Watcher<FileWatcherEvents>,
|
||||||
|
files: string | string[],
|
||||||
|
);
|
||||||
|
/** @type {string[]} */
|
||||||
|
files: string[];
|
||||||
|
watcher: import("./DirectoryWatcher").Watcher<
|
||||||
|
import("./DirectoryWatcher").FileWatcherEvents
|
||||||
|
>;
|
||||||
|
/**
|
||||||
|
* @param {string | string[]} files files
|
||||||
|
*/
|
||||||
|
update(files: string | string[]): void;
|
||||||
|
close(): void;
|
||||||
|
}
|
||||||
|
declare class WatchpackDirectoryWatcher {
|
||||||
|
/**
|
||||||
|
* @param {Watchpack} watchpack watchpack
|
||||||
|
* @param {Watcher<DirectoryWatcherEvents>} watcher watcher
|
||||||
|
* @param {string} directories directories
|
||||||
|
*/
|
||||||
|
constructor(
|
||||||
|
watchpack: Watchpack,
|
||||||
|
watcher: Watcher<DirectoryWatcherEvents>,
|
||||||
|
directories: string,
|
||||||
|
);
|
||||||
|
/** @type {string[]} */
|
||||||
|
directories: string[];
|
||||||
|
watcher: import("./DirectoryWatcher").Watcher<
|
||||||
|
import("./DirectoryWatcher").DirectoryWatcherEvents
|
||||||
|
>;
|
||||||
|
/**
|
||||||
|
* @param {string | string[]} directories directories
|
||||||
|
*/
|
||||||
|
update(directories: string | string[]): void;
|
||||||
|
close(): void;
|
||||||
|
}
|
||||||
|
type WatcherManager = import("./getWatcherManager").WatcherManager;
|
||||||
|
type DirectoryWatcher = import("./DirectoryWatcher");
|
||||||
|
type DirectoryWatcherEvents =
|
||||||
|
import("./DirectoryWatcher").DirectoryWatcherEvents;
|
||||||
|
type FileWatcherEvents = import("./DirectoryWatcher").FileWatcherEvents;
|
||||||
|
type EventMap = Record<string, (...args: any[]) => any>;
|
||||||
|
type Watcher<T extends EventMap> = import("./DirectoryWatcher").Watcher<T>;
|
||||||
|
type IgnoredFunction = (item: string) => boolean;
|
||||||
|
type Ignored = string[] | RegExp | string | IgnoredFunction;
|
||||||
|
type WatcherOptions = {
|
||||||
|
/**
|
||||||
|
* true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
*/
|
||||||
|
followSymlinks?: boolean | undefined;
|
||||||
|
/**
|
||||||
|
* ignore some files from watching (glob pattern or regexp)
|
||||||
|
*/
|
||||||
|
ignored?: Ignored | undefined;
|
||||||
|
/**
|
||||||
|
* true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
poll?: (number | boolean) | undefined;
|
||||||
|
};
|
||||||
|
type WatchOptions = WatcherOptions & {
|
||||||
|
aggregateTimeout?: number;
|
||||||
|
};
|
||||||
|
type NormalizedWatchOptions = {
|
||||||
|
/**
|
||||||
|
* true when need to resolve symlinks and watch symlink and real file, otherwise false
|
||||||
|
*/
|
||||||
|
followSymlinks: boolean;
|
||||||
|
/**
|
||||||
|
* ignore some files from watching (glob pattern or regexp)
|
||||||
|
*/
|
||||||
|
ignored: IgnoredFunction;
|
||||||
|
/**
|
||||||
|
* true when need to enable polling mode for watching, otherwise false
|
||||||
|
*/
|
||||||
|
poll?: (number | boolean) | undefined;
|
||||||
|
};
|
||||||
|
type EventType =
|
||||||
|
| `scan (${string})`
|
||||||
|
| "change"
|
||||||
|
| "rename"
|
||||||
|
| `watch ${string}`
|
||||||
|
| `directory-removed ${string}`;
|
||||||
|
type Entry = {
|
||||||
|
safeTime: number;
|
||||||
|
timestamp: number;
|
||||||
|
accuracy: number;
|
||||||
|
};
|
||||||
|
type OnlySafeTimeEntry = {
|
||||||
|
safeTime: number;
|
||||||
|
};
|
||||||
|
type ExistanceOnlyTimeEntry = {};
|
||||||
|
type TimeInfoEntries = Map<
|
||||||
|
string,
|
||||||
|
Entry | OnlySafeTimeEntry | ExistanceOnlyTimeEntry | null
|
||||||
|
>;
|
||||||
|
type Changes = Set<string>;
|
||||||
|
type Removals = Set<string>;
|
||||||
|
type Aggregated = {
|
||||||
|
changes: Changes;
|
||||||
|
removals: Removals;
|
||||||
|
};
|
||||||
|
type WatchMethodOptions = {
|
||||||
|
files?: Iterable<string>;
|
||||||
|
directories?: Iterable<string>;
|
||||||
|
missing?: Iterable<string>;
|
||||||
|
startTime?: number;
|
||||||
|
};
|
||||||
|
type Times = Record<string, number>;
|
||||||
|
type WatchpackEvents = {
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: (file: string, mtime: number, type: EventType) => void;
|
||||||
|
/**
|
||||||
|
* remove event
|
||||||
|
*/
|
||||||
|
remove: (file: string, type: EventType) => void;
|
||||||
|
/**
|
||||||
|
* aggregated event
|
||||||
|
*/
|
||||||
|
aggregated: (changes: Changes, removals: Removals) => void;
|
||||||
|
};
|
||||||
34
node_modules/watchpack/types/reducePlan.d.ts
generated
vendored
Normal file
34
node_modules/watchpack/types/reducePlan.d.ts
generated
vendored
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
declare namespace _exports {
|
||||||
|
export { TreeNode };
|
||||||
|
}
|
||||||
|
declare function _exports<T>(
|
||||||
|
plan: Map<string, T[] | T>,
|
||||||
|
limit: number,
|
||||||
|
): Map<string, Map<T, string>>;
|
||||||
|
export = _exports;
|
||||||
|
type TreeNode<T> = {
|
||||||
|
/**
|
||||||
|
* target
|
||||||
|
*/
|
||||||
|
target: string;
|
||||||
|
/**
|
||||||
|
* parent
|
||||||
|
*/
|
||||||
|
parent: TreeNode<T>;
|
||||||
|
/**
|
||||||
|
* children
|
||||||
|
*/
|
||||||
|
children: TreeNode<T>[];
|
||||||
|
/**
|
||||||
|
* number of entries
|
||||||
|
*/
|
||||||
|
entries: number;
|
||||||
|
/**
|
||||||
|
* true when active, otherwise false
|
||||||
|
*/
|
||||||
|
active: boolean;
|
||||||
|
/**
|
||||||
|
* value
|
||||||
|
*/
|
||||||
|
value: T[] | T | undefined;
|
||||||
|
};
|
||||||
53
node_modules/watchpack/types/watchEventSource.d.ts
generated
vendored
Normal file
53
node_modules/watchpack/types/watchEventSource.d.ts
generated
vendored
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
export function batch(fn: () => void): void;
|
||||||
|
export function getNumberOfWatchers(): number;
|
||||||
|
export function watch(filePath: string): Watcher;
|
||||||
|
export type FSWatcher = import("fs").FSWatcher;
|
||||||
|
export type EventType = import("./index").EventType;
|
||||||
|
export type WatcherSet = Set<Watcher>;
|
||||||
|
export type WatcherEvents = {
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: (eventType: EventType, filename?: string) => void;
|
||||||
|
/**
|
||||||
|
* error event
|
||||||
|
*/
|
||||||
|
error: (err: unknown) => void;
|
||||||
|
};
|
||||||
|
/**
|
||||||
|
* @typedef {object} WatcherEvents
|
||||||
|
* @property {(eventType: EventType, filename?: string) => void} change change event
|
||||||
|
* @property {(err: unknown) => void} error error event
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @extends {EventEmitter<{ [K in keyof WatcherEvents]: Parameters<WatcherEvents[K]> }>}
|
||||||
|
*/
|
||||||
|
export class Watcher extends EventEmitter<{
|
||||||
|
/**
|
||||||
|
* change event
|
||||||
|
*/
|
||||||
|
change: [
|
||||||
|
eventType: import("./index").EventType,
|
||||||
|
filename?: string | undefined,
|
||||||
|
];
|
||||||
|
/**
|
||||||
|
* error event
|
||||||
|
*/
|
||||||
|
error: [err: unknown];
|
||||||
|
}> {
|
||||||
|
constructor();
|
||||||
|
close(): void;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param {FSWatcher} watcher watcher
|
||||||
|
* @param {string} filePath a file path
|
||||||
|
* @param {(type: "rename" | "change", filename: string) => void} handleChangeEvent function to handle change
|
||||||
|
* @returns {(type: "rename" | "change", filename: string) => void} handler of change event
|
||||||
|
*/
|
||||||
|
export function createHandleChangeEvent(
|
||||||
|
watcher: FSWatcher,
|
||||||
|
filePath: string,
|
||||||
|
handleChangeEvent: (type: "rename" | "change", filename: string) => void,
|
||||||
|
): (type: "rename" | "change", filename: string) => void;
|
||||||
|
export const watcherLimit: number;
|
||||||
|
import { EventEmitter } from "events";
|
||||||
2
node_modules/watchpack/types/watchpack.d.ts
generated
vendored
Normal file
2
node_modules/watchpack/types/watchpack.d.ts
generated
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
declare const _exports: typeof import("./index");
|
||||||
|
export = _exports;
|
||||||
30
package-lock.json
generated
30
package-lock.json
generated
@@ -2659,9 +2659,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/core": {
|
"node_modules/@jqhtml/core": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/core/-/core-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/core/-/core-2.3.29.tgz",
|
||||||
"integrity": "sha512-jnm3GFudWzudwhlClcBNM2p1W74lSpnyqHp27riht+i25o5vHXEXC5/MC0RG/J7H1zcXIB67XTucC5mgfKt3TA==",
|
"integrity": "sha512-uMqxheBuB5r0nSXSFZaU4ad8z9wKDbzN4fD+FUxJPeoGAfCPdyuGWHHwlS+WyC+J7V42qhL2H28VLGmVutHi/g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@rollup/plugin-node-resolve": "^16.0.1",
|
"@rollup/plugin-node-resolve": "^16.0.1",
|
||||||
@@ -2685,9 +2685,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/parser": {
|
"node_modules/@jqhtml/parser": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/parser/-/parser-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/parser/-/parser-2.3.29.tgz",
|
||||||
"integrity": "sha512-Y9HyrCNJXkg3h3ILzSoWeHB53Fl8Q5hBrjdGeyg3eq4j7MFrD8iHBKChoaywzC1CuU00Ir6jsNlofXz9sOVuZQ==",
|
"integrity": "sha512-Ez0z11v8SCp6phJA2XAW+TBmGgYYDs88SeQd6YGX1ap8vCxF2MXe3A6ZlUHvOMiYNT1ONGR5zIcyIuNDJe5Mcg==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@types/jest": "^29.5.11",
|
"@types/jest": "^29.5.11",
|
||||||
@@ -2725,9 +2725,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/ssr": {
|
"node_modules/@jqhtml/ssr": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/ssr/-/ssr-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/ssr/-/ssr-2.3.29.tgz",
|
||||||
"integrity": "sha512-MN98llN00aEgAizgMPVdCKlK964kxVig1kt5F2NTIjXH2FnsWxHQJJJyfbEAedRrvlLO1W9ciPD7mjP2iP2/og==",
|
"integrity": "sha512-IVuJNbwA9Ve/sw1KK+GBbK+4ahCkts+9ZLIdgOsYbU7owOIbxOJe1iZ2IBB4hV/I9M9c54Q8+rw4iD0E99P/nw==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"jquery": "^3.7.1",
|
"jquery": "^3.7.1",
|
||||||
@@ -2821,9 +2821,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@jqhtml/vscode-extension": {
|
"node_modules/@jqhtml/vscode-extension": {
|
||||||
"version": "2.3.28",
|
"version": "2.3.29",
|
||||||
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/vscode-extension/-/vscode-extension-2.3.28.tgz",
|
"resolved": "http://privatenpm.hanson.xyz/@jqhtml/vscode-extension/-/vscode-extension-2.3.29.tgz",
|
||||||
"integrity": "sha512-fY85EHAJclDkUX68hHd3q9hAC0Y/MwMYZgJnKOd2Js08tYD3OW7QD3zoOPR/dVhDKwEWfvXOKPDG5UO2ifTg5g==",
|
"integrity": "sha512-4ULz3axCs4ytYgtf5QpyfMBA4jLDujBibJ7mpRoyqXpuS9NsoTCsvPKdIc5F/Y3mJBFhRpsbPtiRDiiunM7XtQ==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"engines": {
|
"engines": {
|
||||||
"vscode": "^1.74.0"
|
"vscode": "^1.74.0"
|
||||||
@@ -13481,9 +13481,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/watchpack": {
|
"node_modules/watchpack": {
|
||||||
"version": "2.4.4",
|
"version": "2.5.0",
|
||||||
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.4.4.tgz",
|
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz",
|
||||||
"integrity": "sha512-c5EGNOiyxxV5qmTtAB7rbiXxi1ooX1pQKMLX/MIabJjRA0SJBQOjKF+KSVfHkr9U1cADPon0mRiVe/riyaiDUA==",
|
"integrity": "sha512-e6vZvY6xboSwLz2GD36c16+O/2Z6fKvIf4pOXptw2rY9MVwE/TXc6RGqxD3I3x0a28lwBY7DE+76uTPSsBrrCA==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob-to-regexp": "^0.4.1",
|
"glob-to-regexp": "^0.4.1",
|
||||||
|
|||||||
Reference in New Issue
Block a user