diff --git a/HISTORY.md b/HISTORY.md index a40704ade2..cb7b7e4659 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,5 +1,12 @@ # Keyman Version History +## 14.0.77 alpha 2020-05-19 + +* refactor(web/engine): Moves common utility functions into separate `web-utils` package (#3130) +* refactor(web/engine): renames DeviceSpec, moves to utils (#3132) +* fix(ios): Fixes keyboard metadata decoding, tweaks to project files (#3137) +* feat(windows): Use http: instead of file: for Configuration UI (#3127) + ## 14.0.76 alpha 2020-05-15 * fix(windows): use correct name for Sentry in C++ (#3129) diff --git a/VERSION.md b/VERSION.md index 5e0feefd1c..5206b08bb1 100644 --- a/VERSION.md +++ b/VERSION.md @@ -1 +1 @@ -14.0.77 \ No newline at end of file +14.0.78 \ No newline at end of file diff --git a/common/core/web/input-processor/package-lock.json b/common/core/web/input-processor/package-lock.json index 5376fb80d0..03ce768cfa 100644 --- a/common/core/web/input-processor/package-lock.json +++ b/common/core/web/input-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.77", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/input-processor/package.json b/common/core/web/input-processor/package.json index c65c41f636..7690ef7658 100644 --- a/common/core/web/input-processor/package.json +++ b/common/core/web/input-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/input-processor", - "version": "14.0.77", + "version": "14.0.78", "description": "The core text and prediction processing engine for KeymanWeb", "repository": { "type": "git", @@ -28,9 +28,9 @@ "test": "bash ./unit_tests/test.sh" }, "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.77", - "@keymanapp/lexical-model-layer": "^14.0.77", - "@keymanapp/lexical-model-types": "^14.0.77", + "@keymanapp/keyboard-processor": "^14.0.78", + "@keymanapp/lexical-model-layer": "^14.0.78", + "@keymanapp/lexical-model-types": "^14.0.78", "@keymanapp/web-utils": "^14.0.77", "@types/node": "^11.9.4", "eventemitter3": "^4.0.0", diff --git a/common/core/web/keyboard-processor/package-lock.json b/common/core/web/keyboard-processor/package-lock.json index 39dc169f25..7f1afcfd20 100644 --- a/common/core/web/keyboard-processor/package-lock.json +++ b/common/core/web/keyboard-processor/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.77", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/keyboard-processor/package.json b/common/core/web/keyboard-processor/package.json index 2d72cb0801..23db578ef6 100644 --- a/common/core/web/keyboard-processor/package.json +++ b/common/core/web/keyboard-processor/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/keyboard-processor", - "version": "14.0.77", + "version": "14.0.78", "description": "Core module for Keyman keyboard support in KeymanWeb.", "repository": { "type": "git", @@ -30,8 +30,8 @@ "mocha": "mocha" }, "dependencies": { + "@keymanapp/lexical-model-types": "^14.0.78", "@keymanapp/web-utils": "^14.0.77", - "@keymanapp/lexical-model-types": "^14.0.77", "@types/node": "^11.9.4", "ts-node": "^8.0.2" } diff --git a/common/core/web/tools/recorder/package-lock.json b/common/core/web/tools/recorder/package-lock.json index 491ed7ad29..51287c0da7 100644 --- a/common/core/web/tools/recorder/package-lock.json +++ b/common/core/web/tools/recorder/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.77", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/tools/recorder/package.json b/common/core/web/tools/recorder/package.json index 96c43d9e89..cce5948b80 100644 --- a/common/core/web/tools/recorder/package.json +++ b/common/core/web/tools/recorder/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/recorder-core", - "version": "14.0.77", + "version": "14.0.78", "description": "Core classes used to develop KeymanWeb test cases based on keystrokes", "main": "index.js", "scripts": { @@ -17,9 +17,9 @@ }, "homepage": "https://github.com/keymanapp/keyman#readme", "dependencies": { - "@keymanapp/keyboard-processor": "^14.0.77", - "@keymanapp/web-utils": "^14.0.77", - "@keymanapp/lexical-model-types": "^14.0.77" + "@keymanapp/keyboard-processor": "^14.0.78", + "@keymanapp/lexical-model-types": "^14.0.78", + "@keymanapp/web-utils": "^14.0.77" }, "devDependencies": { "typescript": "^3.7.2" diff --git a/common/core/web/utils/package-lock.json b/common/core/web/utils/package-lock.json index db9940f030..26b3c5f720 100644 --- a/common/core/web/utils/package-lock.json +++ b/common/core/web/utils/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.76", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/core/web/utils/package.json b/common/core/web/utils/package.json index 5c809b9fea..530320674c 100644 --- a/common/core/web/utils/package.json +++ b/common/core/web/utils/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/web-utils", - "version": "14.0.76", + "version": "14.0.78", "description": "Common utility functions used throughout other Keyman packages", "main": "index.js", "scripts": { diff --git a/common/lexical-model-types/package-lock.json b/common/lexical-model-types/package-lock.json index f2a9b4895e..558015421c 100644 --- a/common/lexical-model-types/package-lock.json +++ b/common/lexical-model-types/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-types", - "version": "14.0.77", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/lexical-model-types/package.json b/common/lexical-model-types/package.json index aa577f3305..241f78bbed 100644 --- a/common/lexical-model-types/package.json +++ b/common/lexical-model-types/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-types", - "version": "14.0.77", + "version": "14.0.78", "description": "Type definitions in used in the LMLayer (lexical model/predictive text) component of Keyman.", "types": "./index.d.ts", "scripts": { diff --git a/common/models/wordbreakers/.gitignore b/common/models/wordbreakers/.gitignore new file mode 100644 index 0000000000..75871e6dc2 --- /dev/null +++ b/common/models/wordbreakers/.gitignore @@ -0,0 +1,3 @@ +*.js +*.js.map +*.d.ts diff --git a/common/models/wordbreakers/README.md b/common/models/wordbreakers/README.md new file mode 100644 index 0000000000..29ba5d51c7 --- /dev/null +++ b/common/models/wordbreakers/README.md @@ -0,0 +1,19 @@ +# `@keymanapp/models-wordbreakers` + +The word breakers bundled in Keyman's modeling layer (common/models). + +Includes: + + - `default` — a word breaker based on the Unicode default word boundary specification + - _deprecated_ `ascii` — an example word breaker + - _deprecated_ `placeholder` — an example word breaker + +## Usage + +``` +import {wordBreakers} from '@keymanapp/models-wordbreakers'; +const breakWords = wordBreakers['default']; + +console.log(breakWords('Hello, World!').map(span => span.text)); +// prints: [ 'Hello', ',', 'World', '!' ] +``` diff --git a/common/models/wordbreakers/package-lock.json b/common/models/wordbreakers/package-lock.json new file mode 100644 index 0000000000..8e636b7edf --- /dev/null +++ b/common/models/wordbreakers/package-lock.json @@ -0,0 +1,333 @@ +{ + "name": "@keymanapp/models-wordbreakers", + "version": "14.0.75", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.11.tgz", + "integrity": "sha512-t7uW6eFafjO+qJ3BIV2gGUyZs27egcNRkUdalkud+Qa3+kg//f129iuOFivHDXQ+vnU3fDXuwgv0cqMCbcE8sw==", + "dev": true + }, + "@types/mocha": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-7.0.2.tgz", + "integrity": "sha512-ZvO2tAcjmMi8V/5Z3JsyofMe3hasRcaw88cto5etSVMwVQfeivGAlEYmaQgceUSVYFofVjT+ioHsATjdWcFt1w==", + "dev": true + }, + "@types/node": { + "version": "14.0.3", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.0.3.tgz", + "integrity": "sha512-a8TR2N5VEJCL9HEJrAfwv3UI1bZq50HydowDDVV6pfnY7ZwG5Pjii+nSDhrDtGW3XKMoVKOgG8zS/Kv5j399uA==" + }, + "arg": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", + "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", + "dev": true + }, + "assertion-error": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.1.0.tgz", + "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==", + "dev": true + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", + "dev": true + }, + "chai": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-4.2.0.tgz", + "integrity": "sha512-XQU3bhBukrOsQCuwZndwGcCVQHyZi53fQ6Ys1Fym7E4olpIqqZZhhoFJoaKVvV17lWQoXYwgWN2nF5crA8J2jw==", + "dev": true, + "requires": { + "assertion-error": "^1.1.0", + "check-error": "^1.0.2", + "deep-eql": "^3.0.1", + "get-func-name": "^2.0.0", + "pathval": "^1.1.0", + "type-detect": "^4.0.5" + } + }, + "check-error": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-1.0.2.tgz", + "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=", + "dev": true + }, + "commander": { + "version": "2.15.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", + "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", + "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "deep-eql": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-3.0.1.tgz", + "integrity": "sha512-+QeIQyN5ZuO+3Uk5DYh6/1eKO0m0YmJFGNmFHGACpf1ClL1nmlV/p4gNgbl2pJGxgXb4faqo6UE+M5ACEMyVcw==", + "dev": true, + "requires": { + "type-detect": "^4.0.0" + } + }, + "diff": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", + "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "get-func-name": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/get-func-name/-/get-func-name-2.0.0.tgz", + "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=", + "dev": true + }, + "glob": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz", + "integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "he": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz", + "integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "make-error": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", + "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "mocha": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz", + "integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==", + "dev": true, + "requires": { + "browser-stdout": "1.3.1", + "commander": "2.15.1", + "debug": "3.1.0", + "diff": "3.5.0", + "escape-string-regexp": "1.0.5", + "glob": "7.1.2", + "growl": "1.10.5", + "he": "1.1.1", + "minimatch": "3.0.4", + "mkdirp": "0.5.1", + "supports-color": "5.4.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "pathval": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/pathval/-/pathval-1.1.0.tgz", + "integrity": "sha1-uULm1L3mUwBe9rcTYd74cn0GReA=", + "dev": true + }, + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-support": { + "version": "0.5.19", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.19.tgz", + "integrity": "sha512-Wonm7zOCIJzBGQdB+thsPar0kYuCIzYvxZwlBa87yi/Mdjv7Tip2cyVbLj5o0cFPN4EVkuTwb3GDDyUx2DGnGw==", + "dev": true, + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + } + }, + "supports-color": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz", + "integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "ts-node": { + "version": "8.10.1", + "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-8.10.1.tgz", + "integrity": "sha512-bdNz1L4ekHiJul6SHtZWs1ujEKERJnHs4HxN7rjTyyVOFf3HaJ6sLqe6aPG62XTzAB/63pKRh5jTSWL0D7bsvw==", + "dev": true, + "requires": { + "arg": "^4.1.0", + "diff": "^4.0.1", + "make-error": "^1.1.1", + "source-map-support": "^0.5.17", + "yn": "3.1.1" + }, + "dependencies": { + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + } + } + }, + "type-detect": { + "version": "4.0.8", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-4.0.8.tgz", + "integrity": "sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==", + "dev": true + }, + "typescript": { + "version": "3.9.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.9.2.tgz", + "integrity": "sha512-q2ktq4n/uLuNNShyayit+DTobV2ApPEo/6so68JaD5ojvc/6GClBipedB9zNWYxRSAlZXAe405Rlijzl6qDiSw==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "yn": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", + "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", + "dev": true + } + } +} diff --git a/common/models/wordbreakers/package.json b/common/models/wordbreakers/package.json new file mode 100644 index 0000000000..143c08c773 --- /dev/null +++ b/common/models/wordbreakers/package.json @@ -0,0 +1,54 @@ +{ + "name": "@keymanapp/models-wordbreakers", + "version": "14.0.75", + "description": "Word breakers bundled in the modeling layer", + "keywords": [ + "lexical model", + "models", + "word", + "breaker", + "breaking", + "lmlayer" + ], + "contributors": [ + "Eddie Antonio Santos " + ], + "homepage": "https://github.com/keymanapp/keyman", + "license": "MIT", + "main": "lib/index.js", + "directories": { + "lib": "lib", + "test": "test" + }, + "files": [ + "lib" + ], + "publishConfig": { + "access": "public" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/keymanapp/keyman.git" + }, + "scripts": { + "build": "tsc", + "prepublish": "npm run build", + "pretest": "npm run build", + "test": "mocha" + }, + "bugs": { + "url": "https://github.com/keymanapp/keyman/issues" + }, + "devDependencies": { + "@keymanapp/lexical-model-types": "^14.0.75", + "@types/chai": "^4.2.11", + "@types/mocha": "^7.0.2", + "chai": "^4.2.0", + "mocha": "^5.2.0", + "ts-node": "^8.10.1", + "typescript": "^3.2.1" + }, + "dependencies": { + "@types/node": "^14.0.3" + } +} diff --git a/common/predictive-text/worker/word_breaking/ascii-word-breaker.ts b/common/models/wordbreakers/src/ascii.ts similarity index 92% rename from common/predictive-text/worker/word_breaking/ascii-word-breaker.ts rename to common/models/wordbreakers/src/ascii.ts index c7c10726bb..81be11f395 100644 --- a/common/predictive-text/worker/word_breaking/ascii-word-breaker.ts +++ b/common/models/wordbreakers/src/ascii.ts @@ -1,4 +1,20 @@ namespace wordBreakers { + /** + * Splits ASCII words. + * + * @param phrase + */ + export function ascii(phrase: string): Span[] { + let matchWord = /[A-Za-z0-9']+/g; + let words: Span[] = []; + let match: RegExpExecArray | null; + while ((match = matchWord.exec(phrase)) !== null) { + words.push(new RegExpDerivedSpan(match[0], match.index)); + } + + return words; + } + /** * A concrete span class that derives its properties from the result of * RegExp.exec() array. @@ -20,20 +36,4 @@ namespace wordBreakers { return this.start + this.text.length; } } - - /** - * Splits ASCII words. - * - * @param phrase - */ - export function ascii(phrase: string): Span[] { - let matchWord = /[A-Za-z0-9']+/g; - let words: Span[] = []; - let match: RegExpExecArray; - while ((match = matchWord.exec(phrase)) !== null) { - words.push(new RegExpDerivedSpan(match[0], match.index)); - } - - return words; - } -} \ No newline at end of file +} diff --git a/common/predictive-text/worker/word_breaking/default-word-breaking/data.ts b/common/models/wordbreakers/src/default/data.ts similarity index 100% rename from common/predictive-text/worker/word_breaking/default-word-breaking/data.ts rename to common/models/wordbreakers/src/default/data.ts diff --git a/common/predictive-text/worker/word_breaking/default-word-breaking/index.ts b/common/models/wordbreakers/src/default/index.ts similarity index 100% rename from common/predictive-text/worker/word_breaking/default-word-breaking/index.ts rename to common/models/wordbreakers/src/default/index.ts diff --git a/common/models/wordbreakers/src/index.ts b/common/models/wordbreakers/src/index.ts new file mode 100644 index 0000000000..2140ae6bf4 --- /dev/null +++ b/common/models/wordbreakers/src/index.ts @@ -0,0 +1,8 @@ +/// +/// +/// + +// Let the word breakers be available both in the browser and in Node. +if (typeof module !== "undefined" && (module as any).exports) { + (module as any).exports['wordBreakers'] = wordBreakers; +} diff --git a/common/predictive-text/worker/word_breaking/placeholder-word-breaker.ts b/common/models/wordbreakers/src/placeholder.ts similarity index 100% rename from common/predictive-text/worker/word_breaking/placeholder-word-breaker.ts rename to common/models/wordbreakers/src/placeholder.ts diff --git a/common/predictive-text/unit_tests/headless/ascii-word-breaker.js b/common/models/wordbreakers/test/test-ascii-word-breaker.js similarity index 82% rename from common/predictive-text/unit_tests/headless/ascii-word-breaker.js rename to common/models/wordbreakers/test/test-ascii-word-breaker.js index 7e6d129905..598780ad95 100644 --- a/common/predictive-text/unit_tests/headless/ascii-word-breaker.js +++ b/common/models/wordbreakers/test/test-ascii-word-breaker.js @@ -1,6 +1,5 @@ var assert = require('chai').assert; - -var breakASCIIWords = require('../../build/intermediate').wordBreakers['ascii']; +var breakASCIIWords = require('..').wordBreakers['ascii']; describe('The ASCII word breaker', function () { it('should break simple English sentences', function () { @@ -8,4 +7,4 @@ describe('The ASCII word breaker', function () { let words = breaks.map(span => span.text); assert.deepEqual(words, ['Look', 'The', 'quick', 'brown', 'fox', 'jumps', 'over', 'the', 'lazy', 'dog']); }); -}); \ No newline at end of file +}); diff --git a/common/models/wordbreakers/test/test-default-word-breaker.js b/common/models/wordbreakers/test/test-default-word-breaker.js new file mode 100644 index 0000000000..6cf2362695 --- /dev/null +++ b/common/models/wordbreakers/test/test-default-word-breaker.js @@ -0,0 +1,23 @@ +/** + * Smoke-test the default + */ + +const assert = require('chai').assert; +const breakWords = require('..').wordBreakers['default']; + +const SHY = '\u00AD'; + +describe('The default word breaker', function () { + it('should break multilingual text', function () { + let breaks = breakWords( + `Добрый день! ᑕᐻ᙮ — after working on ka${SHY}wen${SHY}non:${SHY}nis, + let's eat phở! 🥣` + ); + let words = breaks.map(span => span.text); + assert.deepEqual(words, [ + 'Добрый', 'день', '!', 'ᑕᐻ', '᙮', '—', 'after', + 'working', 'on', `ka${SHY}wen${SHY}non:${SHY}nis`, ',', + "let's", 'eat', 'phở', '!', '🥣' + ]); + }); +}); diff --git a/common/models/wordbreakers/test/test-placeholder-word-breaker.js b/common/models/wordbreakers/test/test-placeholder-word-breaker.js new file mode 100644 index 0000000000..b23fd5d6bb --- /dev/null +++ b/common/models/wordbreakers/test/test-placeholder-word-breaker.js @@ -0,0 +1,11 @@ +const assert = require('chai').assert; +const breakWords = require('..').wordBreakers['placeholder']; + + +describe('The placeholder word breaker', function () { + it('should break simple English sentences', function () { + let breaks = breakWords('Look! -- The quick brown fox jumps... over the lazy dog!'); + let words = breaks.map(span => span.text); + assert.deepEqual(words, ['Look!', '--', 'The', 'quick', 'brown', 'fox', 'jumps...', 'over', 'the', 'lazy', 'dog!']); + }); +}); diff --git a/common/models/wordbreakers/tsconfig.json b/common/models/wordbreakers/tsconfig.json new file mode 100644 index 0000000000..5d9b97a291 --- /dev/null +++ b/common/models/wordbreakers/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "module": "none", + "lib": ["es6"], + "target": "es5", + "declaration": true, + "sourceMap": true, + "outFile": "index.js", + "strict": true, + "allowJs": false, + "typeRoots": [ + "node_modules/@types", + "node_modules/@keymanapp" + ] + }, + "include": [ + "src/**/*" + ], + "exclude": [ + "node_modules", + "test/**/*.ts" + ] +} diff --git a/common/predictive-text/package-lock.json b/common/predictive-text/package-lock.json index dcf31ec62f..6e90be1cb8 100644 --- a/common/predictive-text/package-lock.json +++ b/common/predictive-text/package-lock.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.77", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/common/predictive-text/package.json b/common/predictive-text/package.json index f31c796aa1..33515545c2 100644 --- a/common/predictive-text/package.json +++ b/common/predictive-text/package.json @@ -1,6 +1,6 @@ { "name": "@keymanapp/lexical-model-layer", - "version": "14.0.77", + "version": "14.0.78", "description": "Keyman/Predictive Text integration layer", "main": "build/index.js", "scripts": { @@ -44,8 +44,9 @@ "typescript": "^3.7.2" }, "dependencies": { + "@keymanapp/lexical-model-types": "^14.0.78", + "@keymanapp/models-wordbreakers": "^14.0.75", "@keymanapp/web-utils": "^14.0.77", - "@keymanapp/lexical-model-types": "^14.0.77", "es6-shim": "^0.35.5", "string.prototype.codepointat": "^0.2.1", "string.prototype.startswith": "^0.2.0" diff --git a/common/predictive-text/unit_tests/headless/default-word-breaker.js b/common/predictive-text/unit_tests/headless/default-word-breaker.js index bcf08efd83..613336458e 100644 --- a/common/predictive-text/unit_tests/headless/default-word-breaker.js +++ b/common/predictive-text/unit_tests/headless/default-word-breaker.js @@ -1,5 +1,5 @@ /** - * Smoke-test the default + * Smoke-test the default word breaker. */ var assert = require('chai').assert; var TrieModel = require('../../build/intermediate').models.TrieModel; @@ -7,29 +7,19 @@ var TrieModel = require('../../build/intermediate').models.TrieModel; var breakWords = require('../../build/intermediate').wordBreakers['default']; const SHY = '\u00AD'; +// The following are **integration tests** testing the interaction between the +// Trie model "template" and the default word breaker. +// +// They exercise whether the default word breaker produces the correct word +// breaks, and whether the Trie model can consume the word breaks properly. describe('The default word breaker', function () { - it('should break multilingual text', function () { - let breaks = breakWords( - `Добрый день! ᑕᐻ᙮ — after working on ka${SHY}wen${SHY}non:${SHY}nis, - let's eat phở! 🥣` - ); - let words = breaks.map(span => span.text); - assert.deepEqual(words, [ - 'Добрый', 'день', '!', 'ᑕᐻ', '᙮', '—', 'after', - 'working', 'on', `ka${SHY}wen${SHY}non:${SHY}nis`, ',', - "let's", 'eat', 'phở', '!', '🥣' - ]); - }); - - // The following tests are performed with model integration as an internal - // test for the wordbreaking API. it('recognizes a word at end of complete lefthand context', function () { var model = new TrieModel(jsonFixture('tries/english-1000'), { wordBreaker: breakWords // wordBreakers['default'] when fully integrated. }); // Standard case - wordbreaking at the end of a word. - var context = { + var context = { left: 'The quick brown fox jumped', startOfBuffer: true, right: ' over the lazy dog.', endOfBuffer: true }; @@ -47,7 +37,7 @@ describe('The default word breaker', function () { }); // Standard case - wordbreaking at the end of a word. - var context = { + var context = { left: 'The quick brown fox jumped', startOfBuffer: false, right: ' over the lazy dog.', endOfBuffer: false }; @@ -63,7 +53,7 @@ describe('The default word breaker', function () { }); // Standard case - midword (xylophone) call - var context = { + var context = { left: 'xyl', startOfBuffer: true, right: '', endOfBuffer: true }; @@ -72,14 +62,14 @@ describe('The default word breaker', function () { assert.strictEqual(broken, 'xyl'); }); - + it('returns empty string when called without word text', function() { var model = new TrieModel(jsonFixture('tries/english-1000'), { wordBreaker: breakWords }); // Wordbreaking on a empty space => no word. - context = { + context = { left: 'The quick brown fox jumped ', startOfBuffer: true, right: 'over the lazy dog.', endOfBuffer: true }; @@ -95,7 +85,7 @@ describe('The default word breaker', function () { }); // Wordbreaking on a empty space => no word. - context = { + context = { left: '', startOfBuffer: true, right: '', endOfBuffer: true }; @@ -111,7 +101,7 @@ describe('The default word breaker', function () { }); // Wordbreaking on a empty space => no word. - context = { + context = { left: '', startOfBuffer: false, right: '', endOfBuffer: false }; @@ -128,13 +118,13 @@ describe('The default word breaker', function () { // A limitation of the current implementation; we should fix this before release. // Then again, when typing this is probably fine; just not when not typing. - context = { + context = { left: 'The quick brown fox jum', startOfBuffer: true, right: 'ped over the lazy dog.', endOfBuffer: true }; broken = model.wordbreak(context); - assert.strictEqual(broken, 'jumped'); // Current result: 'jum'. + assert.strictEqual(broken, 'jumped'); // Current result: 'jum'. }); }); diff --git a/common/predictive-text/worker/index.ts b/common/predictive-text/worker/index.ts index de7b70699f..3529cf4005 100644 --- a/common/predictive-text/worker/index.ts +++ b/common/predictive-text/worker/index.ts @@ -31,7 +31,7 @@ /// /// -/// +/// /// /** diff --git a/common/predictive-text/worker/models/trie-model.ts b/common/predictive-text/worker/models/trie-model.ts index 896c3c1d45..1a2a1e80ac 100644 --- a/common/predictive-text/worker/models/trie-model.ts +++ b/common/predictive-text/worker/models/trie-model.ts @@ -22,7 +22,6 @@ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/// /// /** diff --git a/lerna.json b/lerna.json index 961634f053..080660cc0c 100644 --- a/lerna.json +++ b/lerna.json @@ -6,7 +6,8 @@ "common/core/web/utils", "common/lexical-model-types", "common/predictive-text", + "common/models/*", "web" ], - "version": "14.0.77" + "version": "14.0.78" } diff --git a/web/package-lock.json b/web/package-lock.json index 1ae91f7351..aa5301dfd8 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.77", + "version": "14.0.78", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/web/package.json b/web/package.json index 755a67ea93..bf89b75d2f 100644 --- a/web/package.json +++ b/web/package.json @@ -1,6 +1,6 @@ { "name": "keyman", - "version": "14.0.77", + "version": "14.0.78", "description": "Facilitates text input in any language.", "repository": { "type": "git", @@ -48,11 +48,11 @@ "modernizr": "modernizr" }, "dependencies": { - "@keymanapp/input-processor": "^14.0.77", - "@keymanapp/keyboard-processor": "^14.0.77", - "@keymanapp/lexical-model-layer": "^14.0.77", - "@keymanapp/lexical-model-types": "^14.0.77", - "@keymanapp/recorder-core": "^14.0.77", + "@keymanapp/input-processor": "^14.0.78", + "@keymanapp/keyboard-processor": "^14.0.78", + "@keymanapp/lexical-model-layer": "^14.0.78", + "@keymanapp/lexical-model-types": "^14.0.78", + "@keymanapp/recorder-core": "^14.0.78", "@keymanapp/web-utils": "^14.0.77", "@types/node": "^11.9.4", "es6-shim": "^0.35.5",