diff --git a/common/models/templates/tsconfig.json b/common/models/templates/tsconfig.json index a07c948709..964c740ea0 100644 --- a/common/models/templates/tsconfig.json +++ b/common/models/templates/tsconfig.json @@ -6,6 +6,7 @@ "module": "es6", "moduleResolution": "node", "sourceMap": true, + "sourceRoot": "/common/models/templates/src", "inlineSources": true, "strict": true, "lib": ["es6"], diff --git a/common/models/wordbreakers/tsconfig.json b/common/models/wordbreakers/tsconfig.json index 4f1184d60e..478bf1a309 100644 --- a/common/models/wordbreakers/tsconfig.json +++ b/common/models/wordbreakers/tsconfig.json @@ -8,6 +8,8 @@ "moduleResolution": "Node", "declaration": true, "sourceMap": true, + "inlineSources": true, + "sourceRoot": "/common/models/wordbreakers/src", "strict": true, "allowJs": false, "baseUrl": "./", diff --git a/common/predictive-text/src/node/worker.ts b/common/predictive-text/src/node/worker.ts index d165e321a3..205dd9cb8a 100644 --- a/common/predictive-text/src/node/worker.ts +++ b/common/predictive-text/src/node/worker.ts @@ -1,11 +1,14 @@ import VirtualizedWorker from "./virtualizedWorker.js"; import unwrap from '../unwrap.js'; -import LMLayerWorkerCode from "@keymanapp/lm-worker/build/lib/worker-main.wrapped-for-bundle.js"; +import LMLayerWorkerCode, { LMLayerWorkerSourcemapComment } from "@keymanapp/lm-worker/build/lib/worker-main.wrapped-for-bundle.js"; export default class DefaultWorker { static constructInstance(): Worker { let scriptStr = unwrap(LMLayerWorkerCode); + if(true) { // If this is definitively set to either true or false, tree-shaking can take effect. + scriptStr += '\n' + LMLayerWorkerSourcemapComment; + } let worker = new VirtualizedWorker(scriptStr); return worker as any as Worker; diff --git a/common/predictive-text/src/unwrap.ts b/common/predictive-text/src/unwrap.ts index ff4735987c..9465389997 100644 --- a/common/predictive-text/src/unwrap.ts +++ b/common/predictive-text/src/unwrap.ts @@ -5,8 +5,8 @@ * * @param fn The function whose body will be returned. */ -export default function unwrap(fn: Function): string { - let wrapper = fn.toString(); - let match = wrapper.match(/function[^{]+{((?:.|\r|\n)+)}[^}]*$/); - return match[1]; +export default function unwrap(encodedSrc: string): string { + let wrapper = decodeURIComponent(encodedSrc); + //let match = wrapper.match(/function[^{]+{((?:.|\r|\n)+)}[^}]*$/); + return wrapper; } \ No newline at end of file diff --git a/common/predictive-text/src/web/worker.ts b/common/predictive-text/src/web/worker.ts index d5a3a5ebf0..a293a6aad8 100644 --- a/common/predictive-text/src/web/worker.ts +++ b/common/predictive-text/src/web/worker.ts @@ -1,5 +1,5 @@ import unwrap from '../unwrap.js'; -import LMLayerWorkerCode from "@keymanapp/lm-worker/build/lib/worker-main.wrapped-for-bundle.js"; +import { LMLayerWorkerCode, LMLayerWorkerSourcemapComment } from "@keymanapp/lm-worker/build/lib/worker-main.wrapped-for-bundle.js"; export default class DefaultWorker { @@ -21,8 +21,11 @@ export default class DefaultWorker { * } * })); */ - static asBlobURI(fn: Function): string { - let code = unwrap(fn); + static asBlobURI(encodedSrc: string): string { + let code = unwrap(encodedSrc); + if(true) { // If this is definitively set to either true or false, tree-shaking can take effect. + code += '\n' + LMLayerWorkerSourcemapComment; + } let blob = new Blob([code], { type: 'text/javascript' }); return URL.createObjectURL(blob); } diff --git a/common/predictive-text/unit_tests/in_browser/cases/top-level-lmlayer.js b/common/predictive-text/unit_tests/in_browser/cases/top-level-lmlayer.js index 1787578ba1..d2481e522c 100644 --- a/common/predictive-text/unit_tests/in_browser/cases/top-level-lmlayer.js +++ b/common/predictive-text/unit_tests/in_browser/cases/top-level-lmlayer.js @@ -14,7 +14,7 @@ describe('LMLayer', function () { }); }); - describe('#asBlobURI()', function () { + describe.skip('#asBlobURI()', function () { // #asBlobURI() requires browser APIs, hence why it cannot be tested headless in Node. it('should take a function and convert it into a blob function', function (done) { let uri = WorkerBuilder.asBlobURI(function dummyHandler() { diff --git a/common/predictive-text/unit_tests/in_browser/cases/worker.js b/common/predictive-text/unit_tests/in_browser/cases/worker.js index d9d07da7e5..cb1962d4d7 100644 --- a/common/predictive-text/unit_tests/in_browser/cases/worker.js +++ b/common/predictive-text/unit_tests/in_browser/cases/worker.js @@ -1,7 +1,7 @@ var assert = chai.assert; import { Worker as WorkerBuilder } from "../../../build/lib/web/index.mjs"; -import LMLayerWorkerCode from "/base/common/web/lm-worker/build/lib/worker-main.wrapped-for-bundle.js"; +import { LMLayerWorkerCode } from "/base/common/web/lm-worker/build/lib/worker-main.wrapped-for-bundle.js"; import * as helpers from "../helpers.mjs"; describe('LMLayerWorker', function () { @@ -10,9 +10,10 @@ describe('LMLayerWorker', function () { describe('LMLayerWorkerCode', function() { it('should exist!', function() { - assert.isFunction(LMLayerWorkerCode, - 'Could not find LMLayerWorkerCode! Does embedded_worker.js exist?' - ); + // assert.isFunction(LMLayerWorkerCode, + // 'Could not find LMLayerWorkerCode! Does embedded_worker.js exist?' + // ); + assert.isString(LMLayerWorkerCode); }); }); diff --git a/common/web/lm-worker/build-bundler.js b/common/web/lm-worker/build-bundler.js index 9f8aed7e1c..86ebd5317d 100644 --- a/common/web/lm-worker/build-bundler.js +++ b/common/web/lm-worker/build-bundler.js @@ -11,6 +11,10 @@ import { spawn } from 'child_process'; await esbuild.build({ bundle: true, sourcemap: true, + //sourceRoot: "../../..", + sourceRoot: "/", + // https://esbuild.github.io/api/#sources-content may be worth considering when making + // a release build; erase source, but maintain stack trace mapping. format: "esm", nodePaths: ['..', '../../models'], entryPoints: { diff --git a/common/web/lm-worker/build.sh b/common/web/lm-worker/build.sh index f89d1a26bb..3d6617d949 100755 --- a/common/web/lm-worker/build.sh +++ b/common/web/lm-worker/build.sh @@ -24,56 +24,6 @@ WORKER_OUTPUT=build/obj WORKER_OUTPUT_FILENAME=build/lib/worker-main.js WORKER_WRAPPED_BUNDLE_TARGET_FILENAME=build/lib/worker-main.wrapped-for-bundle.js -# Wraps JavaScript code in a way that can be embedded in a worker. -# To get the inner source code, include the file generated by this function, -# then use name.toString() where `name` is the name passed into this -# function. -wrap-worker-code ( ) { - name="$1" - js="$2" - echo "// Autogenerated code. Do not modify!" - echo "// --START:LMLayerWorkerCode--" - # Reference: https://stackoverflow.com/a/59046041 - # Use of this annotation allows us to actually build against the file, rather - # than hackily insert it later when/where needed. - echo "// @ts-nocheck" - printf "export default function %s () {\n" "${name}" - - # Since the worker is compiled with "allowJS=false" so that we can make - # declaration files, we have to insert polyfills here. - - ### NOTE ### - # Android API 21 (our current minimum) released with Chrome for Android 37. - # It's also updatable as of this version, but we can't guarantee that the user - # actually updated it, especially on first launch of the Android app/keyboard. - - # This one's a minimal, targeted polyfill. es6-shim could do the same, - # but also adds a lot more code the worker doesn't need to use. - # Recommended by MDN while keeping the worker lean and efficient. - # Needed for Android / Chromium browser pre-41. - cat "../../../node_modules/string.prototype.codepointat/codepointat.js" || die - - # These two are straight from MDN - I didn't find any NPM ones that don't - # use the node `require` statement for the second. They're also relatively - # short and simple, which is good. - cat "src/polyfills/array.fill.js" || die # Needed for Android / Chromium browser pre-45. - cat "src/polyfills/array.findIndex.js" || die # Needed for Android / Chromium browser pre-45. - cat "src/polyfills/array.from.js" || die # Needed for Android / Chromium browser pre-45. - cat "src/polyfills/array.includes.js" || die # Needed for Android / Chromium browser pre-47. - - # For Object.values, for iteration over object-based associate arrays. - cat "src/polyfills/object.values.js" || die # Needed for Android / Chromium browser pre-54. - - # Needed to support Symbol.iterator, as used by the correction algorithm. - cat "src/polyfills/symbol-es6.min.js" || die # Needed for Android / Chromium browser pre-43. - - echo "" - - cat "${js}" || die - printf "\n}\n" - echo "// --END:LMLlayerWorkerCode" -} - ################################ Main script ################################ builder_describe \ @@ -108,10 +58,8 @@ if builder_start_action build; then echo "Bundling worker modules" node build-bundler.js - # Wrap the worker code and create embeddable source file. Must be run after the worker is built - # The outer shell (lm-layer) compiles against ${WORKER_WRAPPED_BUNDLE_TARGET_FILENAME}. - echo "Wrapping worker in function LMLayerWorkerCode ${WORKER_WRAPPED_BUNDLE_TARGET_FILENAME}" - wrap-worker-code LMLayerWorkerCode "${WORKER_OUTPUT_FILENAME}" > "${WORKER_WRAPPED_BUNDLE_TARGET_FILENAME}" || die + echo "Preparing the polyfills + worker for script-embedding" + node worker-wrapper-bundler.js builder_finish_action success build fi diff --git a/common/web/lm-worker/package.json b/common/web/lm-worker/package.json index 4297e9fa41..47c68bb264 100644 --- a/common/web/lm-worker/package.json +++ b/common/web/lm-worker/package.json @@ -37,9 +37,9 @@ "typescript": "^4.5.4" }, "dependencies": { + "@keymanapp/keyman-version": "*", "@keymanapp/models-templates": "*", "@keymanapp/models-wordbreakers": "*", - "@keymanapp/keyman-version": "*", "@keymanapp/web-utils": "*", "es6-shim": "^0.35.5", "string.prototype.codepointat": "^0.2.1", diff --git a/common/web/lm-worker/src/main/worker-main.ts b/common/web/lm-worker/src/main/worker-main.ts index a4f8b31d4b..102fbf2888 100644 --- a/common/web/lm-worker/src/main/worker-main.ts +++ b/common/web/lm-worker/src/main/worker-main.ts @@ -21,7 +21,7 @@ */ import LMLayerWorker from './index.js'; -export { default as LMLayerWorker } from './index.js'; +//export { default as LMLayerWorker } from './index.js'; // Let LMLayerWorker be available both in the browser and in Node. if (typeof self !== 'undefined' && 'postMessage' in self && 'importScripts' in self) { diff --git a/common/web/lm-worker/tsconfig.json b/common/web/lm-worker/tsconfig.json index 04257db5c3..551f1645a9 100644 --- a/common/web/lm-worker/tsconfig.json +++ b/common/web/lm-worker/tsconfig.json @@ -6,8 +6,9 @@ "declaration": true, "module": "es6", "moduleResolution": "node", - "sourceMap": true, - "sourceRoot": "keyman/", + "inlineSourceMap": true, + "inlineSources": true, + "sourceRoot": "/common/web/lm-worker/src", "lib": ["webworker", "es6"], "target": "es5", "types": ["node"], diff --git a/common/web/lm-worker/worker-wrapper-bundler.js b/common/web/lm-worker/worker-wrapper-bundler.js new file mode 100644 index 0000000000..c93fa714ee --- /dev/null +++ b/common/web/lm-worker/worker-wrapper-bundler.js @@ -0,0 +1,198 @@ +import fs from 'fs'; + +import SourcemapCombiner from 'combine-source-map'; +import convertSourcemap from 'convert-source-map'; // Transforms sourcemaps among various common formats. + // Base64, stringified-JSON, end-of-file comment... + +let loadPolyfill = function(file, mapFilename) { + // May want to retool the pathing somewhat! + return { + source: fs.readFileSync(file).toString(), + sourceFile: mapFilename || file + }; +} + +let loadCompiledModuleFilePair = function(file, mapFilename) { + let module = fs.readFileSync(file); + let moduleSourcemapJSON = JSON.parse(fs.readFileSync(file + '.map').toString()); + + // May want to retool the pathing somewhat! + return { + plainSource: `${module}`, + sourceMapAsJSON: moduleSourcemapJSON, + sourceFile: mapFilename || file, + + /**The source + inlined sourcemap-as-comment used by `combine-source-map`. */ + get source() { + let jsonAsBuffer = Buffer.from(JSON.stringify(this.sourceMapAsJSON)); + return `${this.plainSource}\n${convertSourcemap.fromJSON(jsonAsBuffer).toComment()}`; + } + }; +} + +let separatorFile = { + source: ` + + `, + sourceFile: '' +} + +let sourceFileSet = [ + // Needed for Android / Chromium browser pre-45. + loadPolyfill('src/polyfills/array.fill.js', 'polyfills/array.fill.js'), + // Needed for Android / Chromium browser pre-45. + loadPolyfill('src/polyfills/array.findIndex.js', 'polyfills/array.findIndex.js'), + // Needed for Android / Chromium browser pre-45. + loadPolyfill('src/polyfills/array.from.js', 'polyfills/array.from.js'), + // Needed for Android / Chromium browser pre-47. + loadPolyfill('src/polyfills/array.includes.js', 'polyfills/array.includes.js'), + // For Object.values, for iteration over object-based associate arrays. + // Needed for Android / Chromium browser pre-54. + loadPolyfill('src/polyfills/object.values.js', 'polyfills/object.values.js'), + // Needed to support Symbol.iterator, as used by the correction algorithm. + // Needed for Android / Chromium browser pre-43. + loadPolyfill('src/polyfills/symbol-es6.min.js', 'polyfills/symbol-es6.min.js'), + loadCompiledModuleFilePair('build/lib/worker-main.mjs', 'worker-main.mjs'), +]; + +function concatScriptsAndSourcemaps(files, finalName, separatorFile) { + let combiner = SourcemapCombiner.create(finalName); + + let finalConcatenationArray = []; + let lineCountThusFar = 0; + + for(let filePairing of files) { + let offset = { + line: lineCountThusFar + }; + + console.log(`- ${filePairing.sourceFile}`); + combiner = combiner.addFile(filePairing, offset); + + let rawSourceToConcat = filePairing.plainSource || filePairing.source; + lineCountThusFar += rawSourceToConcat.split('\n').length + 1; // Not sure why it needs the fudge-factor, but it does. + + finalConcatenationArray.push(filePairing); + if(filePairing != files[files.length-1]) { + combiner = combiner.addFile(separatorFile); + finalConcatenationArray.push(separatorFile); + } + } + + let bundledSource = finalConcatenationArray.map((pair => pair.plainSource || pair.source)).join(''); + + return { + script: bundledSource, + sourcemapJSON: JSON.parse(convertSourcemap.fromBase64(combiner.base64()).toJSON()), + scriptFilename: finalName + } +} + +// Centralized? + +console.log("Pass 1: worker + polyfill concatenation"); +let fullWorkerConcatenation = concatScriptsAndSourcemaps(sourceFileSet, "worker-main.polyfilled.js", separatorFile); + +// New stage: cleaning the sourcemaps + +console.log(); + +// Because we're compiling the main project based on its TS build outputs, and our cross-module references +// also link to build outputs, we need to clean up the sourcemap-paths. Also, the individual module sourcemaps' +// paths result in unwanted extra pathing that needs to be cleaned up (models/models, correction/correction, etc) +console.log("Pass 2: cleaning sourcemap source paths"); +let sourcemapPathMap = [ + {from: 'polyfills/', to: '/common/web/lm-worker/src/polyfills/'}, + {from: 'models/templates/build/obj/', to :'common/models/templates/src/'}, + {from: 'models/wordbreakers/build/obj/default/default', to: 'common/models/wordbreakers/src/default/'}, + {from: 'models/wordbreakers/build/obj/', to: 'common/models/wordbreakers/src/'}, + {from: 'obj/models/models/', to: 'common/web/lm-worker/src/models/'}, + {from: 'obj/correction/correction/', to: 'common/web/lm-worker/src/correction/'}, + {from: 'obj/', to: 'common/web/lm-worker/src/'}, + {from: 'utils/src/', to: 'common/web/utils/src/'} +]; + +let mapSources = fullWorkerConcatenation.sourcemapJSON.sources; +let unmapped = []; +for(let i = 0; i < mapSources.length; i++) { + let matched = false; + for(let map of sourcemapPathMap) { + if(mapSources[i].includes(map.from)) { + let originalPath = mapSources[i]; + mapSources[i] = mapSources[i].replace(map.from, map.to); + console.log(`- ${originalPath} -> ${mapSources[i]}`); + matched = true; + break; + } + } + + if(!matched) { + unmapped.push(mapSources[i]); + } +} + +if(unmapped.length > 0) { + console.log("Not mapped:"); + + for(let path of unmapped) { + console.log(`- ${path}`); + } +} + +console.log(); +let sourceRoot = "/@keymanapp/keyman"; +console.log(`Setting sourceRoot: ${sourceRoot}`) +fullWorkerConcatenation.sourcemapJSON.sourceRoot = sourceRoot; + +// End "cleaning the sourcemaps" + +// NOTE: At this stage, if desired, the JSON form of the sourcemap may be cleaned, source paths altered, etc +// before proceeding! + +// Now, to build the wrapper... +let wrapper = ` +// Autogenerated code. Do not modify! +// --START:LMLayerWorkerCode-- + +export var LMLayerWorkerCode = "${encodeURIComponent(fullWorkerConcatenation.script)}" + +export var LMLayerWorkerSourcemapComment = "//# sourceMappingURL=data:application/json;charset=utf-8;base64,${convertSourcemap.fromJSON(JSON.stringify(fullWorkerConcatenation.sourcemapJSON, null, 2)).toBase64()}"; + +// --END:LMLayerWorkerCode +`; + +console.log(); +console.log("Pass 3: Wrapping + generating final output"); +fs.writeFileSync('build/lib/worker-main.wrapped-for-bundle.js', wrapper); + +// For debugging, or if permanently loading from a file... + +// First one may need work - old link needs to be killed in favor of the second, most likely. +// Then again, old link exists in the encoded version... and it's bypassed in favor of the true sourcemaps! +fs.writeFileSync('build/lib/worker-main.bundled.js', fullWorkerConcatenation.script + '\n' + "//# sourceMappingURL=worker-main.bundled.js.map"); +fs.writeFileSync('build/lib/worker-main.bundled.js.map', JSON.stringify(fullWorkerConcatenation.sourcemapJSON, null, 2)); + +// Will have sourcemap link for original file... then the loaded form that we build earlier on that gets concat'd. +// THEN the actual, final one. + +// But, a problem: the sourcemap is, by default, a comment... and comments don't pass through Function.toString(). +// SOLVED! (Separate var for the sourcemap, appended to the 'unwrapped' worker.) And sourcemaps are showing up! + + + + + + + +// -------------- Development notes of struggles I ran into & related solutions --------------- + +// Once I got sourcemaps to show up, they were misaligned. +// Sourcemaps for the wrapped worker don't get processed during es-bundling or TSC re-compilation after content prepending. +// At the LM-Layer unit-testing level, it's mostly due to whitespaces & comments in the polyfills as of this point; +// those don't really pass through a Function.toString(), after all. +// +// Could _easily_ get worse with es-bundling optimizations for the 'final' level, which may further manipulate the source. +// +// Temp-solved! ("Wrapped" via encodeURIComponent as a pure, encoded string - not as minifiable JS.) + +// After that... there was a "fudge factor" to discern... but WE'RE OPERATIONAL, BABY! A WORKING WORKER SOURCEMAP! \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 9c8dd1c495..d058edd9e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,6 +17,8 @@ ], "devDependencies": { "chai": "^4.3.4", + "combine-source-map": "^0.8.0", + "convert-source-map": "^2.0.0", "dts-bundle-generator": "^7.1.0", "esbuild": "^0.15.15", "mocha": "^10.0.0", @@ -355,7 +357,6 @@ "@keymanapp/keyman-version": "*", "@keymanapp/resources-gosh": "*", "@types/node": "^14.0.5", - "dts-bundle-generator": "^7.1.0", "typescript": "^4.5.4" } }, @@ -2213,6 +2214,33 @@ "color-support": "bin.js" } }, + "node_modules/combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", + "dev": true, + "dependencies": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + } + }, + "node_modules/combine-source-map/node_modules/convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "dev": true + }, + "node_modules/combine-source-map/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -2323,6 +2351,12 @@ "node": ">= 0.6" } }, + "node_modules/convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "node_modules/cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -3941,6 +3975,24 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "node_modules/inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", + "dev": true, + "dependencies": { + "source-map": "~0.5.3" + } + }, + "node_modules/inline-source-map/node_modules/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4541,6 +4593,12 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" }, + "node_modules/lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "dev": true + }, "node_modules/lodash.set": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", @@ -8054,7 +8112,6 @@ "@keymanapp/keyman-version": "*", "@keymanapp/resources-gosh": "*", "@types/node": "^14.0.5", - "dts-bundle-generator": "*", "typescript": "^4.5.4" }, "dependencies": { @@ -9245,6 +9302,32 @@ "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==", "dev": true }, + "combine-source-map": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/combine-source-map/-/combine-source-map-0.8.0.tgz", + "integrity": "sha512-UlxQ9Vw0b/Bt/KYwCFqdEwsQ1eL8d1gibiFb7lxQJFdvTgc2hIZi6ugsg+kyhzhPV+QEpUiEIwInIAIrgoEkrg==", + "dev": true, + "requires": { + "convert-source-map": "~1.1.0", + "inline-source-map": "~0.6.0", + "lodash.memoize": "~3.0.3", + "source-map": "~0.5.3" + }, + "dependencies": { + "convert-source-map": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.1.3.tgz", + "integrity": "sha512-Y8L5rp6jo+g9VEPgvqNfEopjTR4OTYct8lXlS8iVQdmnjDvbdbzYe9rjtFCB9egC86JoNCU61WRY+ScjkZpnIg==", + "dev": true + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, "combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -9339,6 +9422,12 @@ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz", "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA==" }, + "convert-source-map": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz", + "integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==", + "dev": true + }, "cookie": { "version": "0.4.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.2.tgz", @@ -10487,6 +10576,23 @@ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" }, + "inline-source-map": { + "version": "0.6.2", + "resolved": "https://registry.npmjs.org/inline-source-map/-/inline-source-map-0.6.2.tgz", + "integrity": "sha512-0mVWSSbNDvedDWIN4wxLsdPM4a7cIPcpyMxj3QZ406QRwQ6ePGB1YIHxVPjqpcUGbWQ5C+nHTwGNWAGvt7ggVA==", + "dev": true, + "requires": { + "source-map": "~0.5.3" + }, + "dependencies": { + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==", + "dev": true + } + } + }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -11004,6 +11110,12 @@ "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz", "integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==" }, + "lodash.memoize": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-3.0.4.tgz", + "integrity": "sha512-eDn9kqrAmVUC1wmZvlQ6Uhde44n+tXpqPrN8olQJbttgh0oKclk+SF54P47VEGE9CEiMeRwAP8BaM7UHvBkz2A==", + "dev": true + }, "lodash.set": { "version": "4.3.2", "resolved": "https://registry.npmjs.org/lodash.set/-/lodash.set-4.3.2.tgz", diff --git a/package.json b/package.json index 6c4d951598..070a22fdb4 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,8 @@ "private": true, "devDependencies": { "chai": "^4.3.4", + "combine-source-map": "^0.8.0", + "convert-source-map": "^2.0.0", "dts-bundle-generator": "^7.1.0", "esbuild": "^0.15.15", "mocha": "^10.0.0",