From 5a4ca474b9bd3b3e7277f747771f84051b96886a Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Fri, 24 Mar 2023 01:00:38 -0400 Subject: [PATCH] Removes lodash-es dependency --- .eslintrc.base.json | 2 - ThirdPartyNotices.txt | 76 +++------------------ package.json | 2 - src/system/function.ts | 148 ++++++++++++++++++++++++---------------- src/trackers/documentTracker.ts | 16 ++--- src/trackers/lineTracker.ts | 22 +++--- yarn.lock | 17 ----- 7 files changed, 117 insertions(+), 166 deletions(-) diff --git a/.eslintrc.base.json b/.eslintrc.base.json index eec8ee0..f471c73 100644 --- a/.eslintrc.base.json +++ b/.eslintrc.base.json @@ -56,8 +56,6 @@ "error", { "paths": [ - "lodash", - "lodash-es", // Disallow node imports below "assert", "buffer", diff --git a/ThirdPartyNotices.txt b/ThirdPartyNotices.txt index c1b0dfb..f6bac40 100644 --- a/ThirdPartyNotices.txt +++ b/ThirdPartyNotices.txt @@ -7,8 +7,8 @@ This project incorporates components from the projects listed below. 2. @microsoft/fast-react-wrapper version 0.3.16-0 (https://github.com/Microsoft/fast) 3. @octokit/core version 4.2.0 (https://github.com/octokit/core.js) 4. @opentelemetry/api version 1.4.1 (https://github.com/open-telemetry/opentelemetry-js) -5. @opentelemetry/exporter-trace-otlp-http version 0.36.0 (https://github.com/open-telemetry/opentelemetry-js) -6. @opentelemetry/sdk-trace-base version 1.10.0 (https://github.com/open-telemetry/opentelemetry-js) +5. @opentelemetry/exporter-trace-otlp-http version 0.36.1 (https://github.com/open-telemetry/opentelemetry-js) +6. @opentelemetry/sdk-trace-base version 1.10.1 (https://github.com/open-telemetry/opentelemetry-js) 7. @vscode/codicons version 0.0.32 (https://github.com/microsoft/vscode-codicons) 8. @vscode/webview-ui-toolkit version 1.2.2 (https://github.com/microsoft/vscode-webview-ui-toolkit) 9. ansi-regex version 6.0.1 (https://github.com/chalk/ansi-regex) @@ -16,16 +16,15 @@ This project incorporates components from the projects listed below. 11. https-proxy-agent version 5.0.1 (https://github.com/TooTallNate/node-https-proxy-agent) 12. iconv-lite version 0.6.3 (https://github.com/ashtuchkin/iconv-lite) 13. lit version 2.6.1 (https://github.com/lit/lit) -14. lodash-es version 4.17.21 (https://github.com/lodash/lodash) -15. microsoft/vscode (https://github.com/microsoft/vscode) -16. node-fetch version 2.6.9 (https://github.com/bitinn/node-fetch) -17. os-browserify version 0.3.0 (https://github.com/CoderPuppy/os-browserify) -18. path-browserify version 1.0.1 (https://github.com/browserify/path-browserify) -19. react-dom version 16.8.4 (https://github.com/facebook/react) -20. react version 16.8.4 (https://github.com/facebook/react) -21. sindresorhus/is-fullwidth-code-point (https://github.com/sindresorhus/is-fullwidth-code-point) -22. sindresorhus/string-width (https://github.com/sindresorhus/string-width) -23. sortablejs version 1.15.0 (https://github.com/SortableJS/Sortable) +14. microsoft/vscode (https://github.com/microsoft/vscode) +15. node-fetch version 2.6.9 (https://github.com/bitinn/node-fetch) +16. os-browserify version 0.3.0 (https://github.com/CoderPuppy/os-browserify) +17. path-browserify version 1.0.1 (https://github.com/browserify/path-browserify) +18. react-dom version 16.8.4 (https://github.com/facebook/react) +19. react version 16.8.4 (https://github.com/facebook/react) +20. sindresorhus/is-fullwidth-code-point (https://github.com/sindresorhus/is-fullwidth-code-point) +21. sindresorhus/string-width (https://github.com/sindresorhus/string-width) +22. sortablejs version 1.15.0 (https://github.com/SortableJS/Sortable) %% @microsoft/fast-element NOTICES AND INFORMATION BEGIN HERE ========================================= @@ -1451,59 +1450,6 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ========================================= END OF lit NOTICES AND INFORMATION -%% lodash-es NOTICES AND INFORMATION BEGIN HERE -========================================= -Copyright OpenJS Foundation and other contributors - -Based on Underscore.js, copyright Jeremy Ashkenas, -DocumentCloud and Investigative Reporters & Editors - -This software consists of voluntary contributions made by many -individuals. For exact contribution history, see the revision history -available at https://github.com/lodash/lodash - -The following license applies to all parts of this software except as -documented below: - -==== - -Permission is hereby granted, free of charge, to any person obtaining -a copy of this software and associated documentation files (the -"Software"), to deal in the Software without restriction, including -without limitation the rights to use, copy, modify, merge, publish, -distribute, sublicense, and/or sell copies of the Software, and to -permit persons to whom the Software is furnished to do so, subject to -the following conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -==== - -Copyright and related rights for sample code are waived via CC0. Sample -code is defined as all source code displayed within the prose of the -documentation. - -CC0: http://creativecommons.org/publicdomain/zero/1.0/ - -==== - -Files located in the node_modules and vendor directories are externally -maintained libraries used by this software which have their own -licenses; we recommend you read them, as their terms may differ from the -terms above. - -========================================= -END OF lodash-es NOTICES AND INFORMATION - %% microsoft/vscode NOTICES AND INFORMATION BEGIN HERE ========================================= MIT License diff --git a/package.json b/package.json index ccc254b..c864b02 100644 --- a/package.json +++ b/package.json @@ -13422,7 +13422,6 @@ "https-proxy-agent": "5.0.1", "iconv-lite": "0.6.3", "lit": "2.6.1", - "lodash-es": "4.17.21", "node-fetch": "2.6.9", "os-browserify": "0.3.0", "path-browserify": "1.0.1", @@ -13432,7 +13431,6 @@ }, "devDependencies": { "@types/glob": "8.0.1", - "@types/lodash-es": "4.17.7", "@types/mocha": "10.0.1", "@types/node": "16.11.47", "@types/react": "17.0.47", diff --git a/src/system/function.ts b/src/system/function.ts index c925bd5..751bb7d 100644 --- a/src/system/function.ts +++ b/src/system/function.ts @@ -1,6 +1,3 @@ -/* eslint-disable @typescript-eslint/no-unsafe-return */ -// eslint-disable-next-line no-restricted-imports -import { debounce as _debounce, once as _once } from 'lodash-es'; import type { Disposable } from 'vscode'; export interface Deferrable any> { @@ -15,69 +12,95 @@ interface PropOfValue { value: string | undefined; } -export interface DebounceOptions { - leading?: boolean; - maxWait?: number; - track?: boolean; - trailing?: boolean; -} +export function debounce ReturnType>(fn: T, wait: number): Deferrable { + let lastArgs: Parameters; + let lastCallTime: number | undefined; + let lastThis: ThisType; + let result: ReturnType | undefined; + let timer: ReturnType | undefined; -export function debounce any>( - fn: T, - wait?: number, - options?: DebounceOptions, -): Deferrable { - const { track, ...opts }: DebounceOptions = { - track: false, - ...(options ?? {}), - }; + function invoke(): ReturnType | undefined { + const args = lastArgs; + const thisArg = lastThis; - if (track !== true) return _debounce(fn, wait, opts); + lastArgs = lastThis = undefined!; + result = fn.apply(thisArg, args); + return result; + } - let pending = false; + function shouldInvoke(time: number) { + const timeSinceLastCall = time - (lastCallTime ?? 0); - const debounced = _debounce( - function (this: any, ...args: any[]) { - pending = false; - return fn.apply(this, args); - } as any as T, - wait, - options, - ); + // Either this is the first call, activity has stopped and we're at the + // trailing edge, the system time has gone backwards and we're treating + // it as the trailing edge + return lastCallTime == null || timeSinceLastCall >= wait || timeSinceLastCall < 0; + } - const tracked: Deferrable = function (this: any, ...args: Parameters) { - pending = true; - return debounced.apply(this, args); - } as any; + function timerExpired() { + const time = Date.now(); + if (shouldInvoke(time)) { + trailingEdge(); + } else { + // Restart the timer + const timeSinceLastCall = time - (lastCallTime ?? 0); + timer = setTimeout(timerExpired, wait - timeSinceLastCall); + } + } - tracked.pending = function () { - return pending; - }; - tracked.cancel = function () { - return debounced.cancel.apply(debounced); - }; - tracked.flush = function () { - return debounced.flush.apply(debounced); - }; + function trailingEdge() { + timer = undefined; - return tracked; -} + // Only invoke if we have `lastArgs` which means `fn` has been debounced at least once + if (lastArgs) return invoke(); + lastArgs = lastThis = undefined!; -// export function debounceMemoized any>( -// fn: T, -// wait?: number, -// options?: DebounceOptions & { resolver?(...args: any[]): any } -// ): T { -// const { resolver, ...opts } = options || ({} as DebounceOptions & { resolver?: T }); + return result; + } -// const memo = _memoize(() => { -// return debounce(fn, wait, opts); -// }, resolver); + function cancel() { + if (timer != null) { + clearTimeout(timer); + } + lastArgs = lastCallTime = lastThis = timer = undefined!; + } -// return function(this: any, ...args: []) { -// return memo.apply(this, args).apply(this, args); -// } as T; -// } + function flush() { + return timer != null ? trailingEdge() : result; + } + + function pending() { + return timer != null; + } + + function debounced(this: any, ...args: Parameters) { + const time = Date.now(); + const isInvoking = shouldInvoke(time); + + lastArgs = args; + // eslint-disable-next-line @typescript-eslint/no-this-alias + lastThis = this; + lastCallTime = time; + + if (isInvoking) { + if (timer == null) { + // Start the timer for the trailing edge. + timer = setTimeout(timerExpired, wait); + return result; + } + } + if (timer == null) { + timer = setTimeout(timerExpired, wait); + } + + return result; + } + + debounced.cancel = cancel; + debounced.flush = flush; + debounced.pending = pending; + return debounced; +} const comma = ','; const emptyStr = ''; @@ -125,7 +148,18 @@ export function is(o: object, propOrMatcher?: keyof T | ((o: a } export function once any>(fn: T): T { - return _once(fn); + let result: ReturnType; + let called = false; + + return function (this: any, ...args: Parameters): ReturnType { + if (!called) { + called = true; + result = fn.apply(this, args); + fn = undefined!; + } + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return result; + } as T; } export function propOf>(o: T, key: K) { diff --git a/src/trackers/documentTracker.ts b/src/trackers/documentTracker.ts index 2f93aa1..6597404 100644 --- a/src/trackers/documentTracker.ts +++ b/src/trackers/documentTracker.ts @@ -361,16 +361,12 @@ export class DocumentTracker implements Disposable { if (this._dirtyIdleTriggerDelay > 0) { if (this._dirtyIdleTriggeredDebounced == null) { - this._dirtyIdleTriggeredDebounced = debounce( - (e: DocumentDirtyIdleTriggerEvent) => { - if (this._dirtyIdleTriggeredDebounced?.pending!()) return; - - e.document.isDirtyIdle = true; - this._onDidTriggerDirtyIdle.fire(e); - }, - this._dirtyIdleTriggerDelay, - { track: true }, - ); + this._dirtyIdleTriggeredDebounced = debounce((e: DocumentDirtyIdleTriggerEvent) => { + if (this._dirtyIdleTriggeredDebounced?.pending!()) return; + + e.document.isDirtyIdle = true; + this._onDidTriggerDirtyIdle.fire(e); + }, this._dirtyIdleTriggerDelay); } this._dirtyIdleTriggeredDebounced({ editor: e.editor, document: e.document }); diff --git a/src/trackers/lineTracker.ts b/src/trackers/lineTracker.ts index 580b94e..5c36c14 100644 --- a/src/trackers/lineTracker.ts +++ b/src/trackers/lineTracker.ts @@ -222,19 +222,15 @@ export class LineTracker implements Disposable { } if (this._linesChangedDebounced == null) { - this._linesChangedDebounced = debounce( - (e: LinesChangeEvent) => { - if (e.editor !== window.activeTextEditor) return; - // Make sure we are still on the same lines - if (!LineTracker.includes(e.selections, LineTracker.toLineSelections(e.editor?.selections))) { - return; - } - - this.fireLinesChanged(e); - }, - 250, - { track: true }, - ); + this._linesChangedDebounced = debounce((e: LinesChangeEvent) => { + if (e.editor !== window.activeTextEditor) return; + // Make sure we are still on the same lines + if (!LineTracker.includes(e.selections, LineTracker.toLineSelections(e.editor?.selections))) { + return; + } + + this.fireLinesChanged(e); + }, 250); } // If we have no pending moves, then fire an immediate pending event, and defer the real event diff --git a/yarn.lock b/yarn.lock index 587ee26..f1cb00e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -675,18 +675,6 @@ resolved "https://registry.yarnpkg.com/@types/json5/-/json5-0.0.29.tgz#ee28707ae94e11d2b827bcbe5270bcea7f3e71ee" integrity sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ== -"@types/lodash-es@4.17.7": - version "4.17.7" - resolved "https://registry.yarnpkg.com/@types/lodash-es/-/lodash-es-4.17.7.tgz#22edcae9f44aff08546e71db8925f05b33c7cc40" - integrity sha512-z0ptr6UI10VlU6l5MYhGwS4mC8DZyYer2mCoyysZtSF7p26zOX8UpbrV0YpNYLGS8K4PUFIyEr62IMFFjveSiQ== - dependencies: - "@types/lodash" "*" - -"@types/lodash@*": - version "4.14.191" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.191.tgz#09511e7f7cba275acd8b419ddac8da9a6a79e2fa" - integrity sha512-BdZ5BCCvho3EIXw6wUCXHe7rS53AIDPLE+JzwgT+OsJk53oBfbSmZZ7CX4VaRoN78N+TJpFi9QPlfIVNmJYWxQ== - "@types/minimatch@*", "@types/minimatch@^5.1.2": version "5.1.2" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-5.1.2.tgz#07508b45797cb81ec3f273011b054cd0755eddca" @@ -4490,11 +4478,6 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" -lodash-es@4.17.21: - version "4.17.21" - resolved "https://registry.yarnpkg.com/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee" - integrity sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw== - lodash.clonedeep@^4.5.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"