diff --git a/HISTORY.md b/HISTORY.md
index b406ebf4a9..f42af6d60b 100644
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -1,5 +1,23 @@
# Keyman Version History
+## 19.0.206 alpha 2026-02-25
+
+* maint(ios): upgrade to Xcode 26.2 (#15498)
+
+## 19.0.205 alpha 2026-02-24
+
+* fix(core): fix iterator in backspace handling (#15596)
+* refactor(core): simplify loop for removing text (#15600)
+* test(core): add LDML baseline test with minimal keyboard (#15608)
+
+## 19.0.204 alpha 2026-02-20
+
+* maint(web): ensure Web build scripts handle paths with spaces properly (#15598)
+
+## 19.0.203 alpha 2026-02-16
+
+* docs: Add status.keyman.com info to website readme (#15591)
+
## 19.0.202 alpha 2026-02-12
* fix(linux): check for existing file before trying to install (#15573)
diff --git a/VERSION.md b/VERSION.md
index 312b5b0587..3027f050d0 100644
--- a/VERSION.md
+++ b/VERSION.md
@@ -1 +1 @@
-19.0.203
\ No newline at end of file
+19.0.207
\ No newline at end of file
diff --git a/core/src/ldml/ldml_processor.cpp b/core/src/ldml/ldml_processor.cpp
index 63e7995273..17e4d634eb 100644
--- a/core/src/ldml/ldml_processor.cpp
+++ b/core/src/ldml/ldml_processor.cpp
@@ -233,15 +233,15 @@ void ldml_event_state::emit_backspace() {
// Find out what the last actual character was and remove it.
// attempt to get the last char
// TODO-LDML: emoji backspace
- auto end = state->context().rbegin();
- while (end != state->context().rend()) {
- if (end->type == KM_CORE_CT_CHAR) {
+ while (!state->context().empty()) {
+ auto end = state->context().back();
+ if (end.type == KM_CORE_CT_CHAR) {
actions.code_points_to_delete++;
state->context().pop_back();
return;
}
// else loop again
- assert(end->type != KM_CORE_CT_END); // inappropriate here.
+ assert(end.type != KM_CORE_CT_END); // inappropriate here.
state->context().pop_back();
}
/*
@@ -415,26 +415,25 @@ void
ldml_event_state::remove_text(std::u32string &str, size_t length) {
// str is the string to remove, so it should be at least as long as length
assert(length <= str.length());
- /** track how many context items have been removed, via push_backspace() */
- size_t contextRemoved = 0;
- for (auto c = state->context().rbegin(); length > 0 && c != state->context().rend(); c++, contextRemoved++) {
+ while (length > 0 && !state->context().empty()) {
#ifndef NDEBUG
/** last char of context */
km_core_usv lastCtx = str.back();
#endif
- uint8_t type = c->type;
+ auto lastStateCtx = state->context().back();
+ uint8_t type = lastStateCtx.type;
assert(type == KM_CORE_BT_CHAR || type == KM_CORE_BT_MARKER);
if (type == KM_CORE_BT_CHAR) {
// single char, drop it
length--;
- assert(c->character == lastCtx);
+ assert(lastStateCtx.character == lastCtx);
str.pop_back();
// Cause prior char to be removed
actions.code_points_to_delete++;
} else if (type == KM_CORE_BT_MARKER) {
assert(length >= 3);
// #3 - the marker.
- assert(lastCtx == c->marker);
+ assert(lastCtx == lastStateCtx.marker);
str.pop_back();
length--;
// #2 - the code
@@ -447,13 +446,9 @@ ldml_event_state::remove_text(std::u32string &str, size_t length) {
// Nothing in actions
length--;
}
- }
- assert(length == 0);
- // now, pop the context items
- for (size_t i = 0; i < contextRemoved; i++) {
- // we don't pop during the above loop because the iterator gets confused
state->context().pop_back();
}
+ assert(length == 0);
}
void
diff --git a/core/tests/unit/ldml/keyboards/k_000_minimal_keyboard.xml b/core/tests/unit/ldml/keyboards/k_000_minimal_keyboard.xml
new file mode 100644
index 0000000000..44c043f891
--- /dev/null
+++ b/core/tests/unit/ldml/keyboards/k_000_minimal_keyboard.xml
@@ -0,0 +1,23 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/core/tests/unit/ldml/keyboards/k_000_null_keyboard.xml b/core/tests/unit/ldml/keyboards/k_000_null_keyboard.xml
deleted file mode 100644
index 73dfce5dd9..0000000000
--- a/core/tests/unit/ldml/keyboards/k_000_null_keyboard.xml
+++ /dev/null
@@ -1,10 +0,0 @@
-
-
diff --git a/core/tests/unit/ldml/keyboards/meson.build b/core/tests/unit/ldml/keyboards/meson.build
index 55004f78b8..29aa37541b 100644
--- a/core/tests/unit/ldml/keyboards/meson.build
+++ b/core/tests/unit/ldml/keyboards/meson.build
@@ -17,8 +17,7 @@ tests_from_cldr = [
# these have 'embedded' (@@) testdata instead of a separate file
tests_without_testdata = [
-# disabling 000 until we have updates to core or to the keyboard so that it passes
-# 'k_000_null_keyboard',
+ 'k_000_minimal_keyboard',
'k_002_tinyu32',
'k_003_transform',
'k_004_tinyshift',
diff --git a/core/tests/unit/ldml/ldml.cpp b/core/tests/unit/ldml/ldml.cpp
index b040df7e76..2acced0018 100644
--- a/core/tests/unit/ldml/ldml.cpp
+++ b/core/tests/unit/ldml/ldml.cpp
@@ -40,7 +40,7 @@
namespace {
-void print_context(std::u16string &text_store, km_core_state *&test_state, std::vector &test_context);
+void print_context(std::u16string &text_store, km_core_state *&test_state, std::list &test_context);
bool g_beep_found = false;
@@ -68,10 +68,10 @@ string_to_hex(const std::u16string &input) {
void
-copy_context_items_to_vector(km_core_context_item *citems, std::vector &vector) {
- vector.clear();
+copy_context_items_to_list(km_core_context_item *citems, std::list &list) {
+ list.clear();
for(km_core_context_item *ci = citems; ci->type != KM_CORE_CT_END; ci++) {
- vector.emplace_back(*ci);
+ list.emplace_back(*ci);
}
}
@@ -81,9 +81,9 @@ apply_action(
km_core_state *test_state,
km_core_action_item const &act,
std::u16string &text_store,
- std::vector &context,
+ std::list &context,
km::tests::LdmlTestSource &test_source,
- std::vector &test_context) {
+ std::list &test_context) {
// print_context(text_store, test_state, test_context);
switch (act.type) {
@@ -157,21 +157,20 @@ apply_action(
matched_text = true; // no text to match as context is empty.
}
// now, we need to simulate what ldml_processor::emit_backspace() is going to do.
- auto end = context.rbegin();
- while (end != context.rend()) {
- if (end->type == KM_CORE_CT_CHAR) {
- test_assert(!matched_text);
- test_assert_equal(end->character, ch); // expect popped char to be same as what's in context
- matched_text = true;
- context.pop_back();
- break; // exit on first real char
- }
- test_assert(end->type != KM_CORE_CT_END); // inappropriate here.
+ while (!context.empty()) {
+ if (context.back().type == KM_CORE_CT_CHAR) {
+ test_assert(!matched_text);
+ test_assert_equal(context.back().character, ch); // expect popped char to be same as what's in context
+ matched_text = true;
context.pop_back();
+ break; // exit on first real char
}
- test_assert(matched_text);
+ test_assert(context.back().type != KM_CORE_CT_END); // inappropriate here.
+ context.pop_back();
}
+ test_assert(matched_text);
break;
+ }
case KM_CORE_IT_PERSIST_OPT:
std::cout << " + TODO-LDML: persist_opt()" << std::endl;
break;
@@ -184,9 +183,9 @@ apply_action(
// We replace the cached context with the current application context
km_core_status status = context_items_from_utf16(text_store.c_str(), &new_context_items);
test_assert(status == KM_CORE_STATUS_OK);
- copy_context_items_to_vector(new_context_items, context);
+ copy_context_items_to_list(new_context_items, context);
// also update the test context
- copy_context_items_to_vector(new_context_items, test_context);
+ copy_context_items_to_list(new_context_items, test_context);
// TODO-LDML: now we need to SET the core context!
status = km_core_context_set(km_core_state_context(test_state), new_context_items);
km_core_context_items_dispose(new_context_items);
@@ -212,9 +211,9 @@ apply_actions(
km_core_state *test_state,
km_core_actions const *actions,
std::u16string &text_store,
- std::vector &context,
+ std::list &context,
km::tests::LdmlTestSource &test_source,
- std::vector &test_context
+ std::list &test_context
) {
if(actions->do_alert) {
@@ -245,7 +244,7 @@ apply_actions(
}
void
-print_context(std::u16string &text_store, km_core_state *&test_state, std::vector &test_context) {
+print_context(std::u16string &text_store, km_core_state *&test_state, std::list &test_context) {
// Compare context and text store at each step - should be identical
size_t n = 0;
km_core_context_item *citems = nullptr;
@@ -280,7 +279,7 @@ print_context(std::u16string &text_store, km_core_state *&test_state, std::vecto
std::cout << "test_context : ";
std::cout.fill('0');
- for (auto i = test_context.begin(); i < test_context.end(); i++) {
+ for (auto i = test_context.begin(); i != test_context.end(); i++) {
switch (i->type) {
case KM_CORE_CT_CHAR:
std::cout << "U+" << std::setw(4) << std::hex << i->character << std::dec << " ";
@@ -302,7 +301,7 @@ print_context(std::u16string &text_store, km_core_state *&test_state, std::vecto
* verify the current context
*/
void
-verify_context(std::u16string &text_store, km_core_state *&test_state, std::vector &test_context, bool fully_normalized_mode, bool normalization_enabled) {
+verify_context(std::u16string &text_store, km_core_state *&test_state, std::list &test_context, bool fully_normalized_mode, bool normalization_enabled) {
// Compare context and text store at each step - should be identical
print_context(text_store, test_state, test_context);
@@ -435,7 +434,7 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests
g_beep_found = false;
- std::vector test_context;
+ std::list test_context;
km_core_context_item *citems = nullptr;
// setup test_context
@@ -448,7 +447,7 @@ run_test(const km::core::path &source, const km::core::path &compiled, km::tests
}
// Make a copy of the setup context for the test
- copy_context_items_to_vector(citems, test_context);
+ copy_context_items_to_list(citems, test_context);
km_core_context_items_dispose(citems);
// Setup baseline text store
diff --git a/docs/websites/README.md b/docs/websites/README.md
index 3c68874019..9813fcc2ae 100644
--- a/docs/websites/README.md
+++ b/docs/websites/README.md
@@ -60,14 +60,19 @@ The link file also appears locally.
##### Port lookup table
After this, you can access the website at the following ports:
-| Website | URL | with website-local-proxy running | Docker Container Name |
-|----------------|-----------------------|-----------------------------------|------------------------|
-| keyman.com | http://localhost:8053 | http://keyman.com.localhost | keyman-website |
-| s.keyman.com | http://localhost:8054 | http://s.keyman.com.localhost | s-keyman-website |
-| help.keyman | http://localhost:8055 | http://help.keyman.com.localhost | help-keyman-website |
-| keymanweb.com | http://localhost:8057 | http://keymanweb.com.localhost | web-keyman-website |
-| | | http://web.keyman.com.localhost | |
-| api.keyman.com | http://localhost:8058 | http://api.keyman.com.localhost | api-keyman-com-website |
+| Website | URL | with website-local-proxy running | Docker Container Name |
+|--------------------|-----------------------|--------------------------------------------|------------------------|
+| keyman.com | http://localhost:8053 | http://keyman.com.localhost | keyman-website |
+| s.keyman.com | http://localhost:8054 | http://s.keyman.com.localhost | s-keyman-website |
+| help.keyman | http://localhost:8055 | http://help.keyman.com.localhost | help-keyman-website |
+| keymanweb.com | http://localhost:8057 | http://keymanweb.com.localhost | web-keyman-website |
+| | | http://web.keyman.com.localhost | |
+| api.keyman.com | http://localhost:8058 | http://api.keyman.com.localhost | api-keyman-com-website |
+| status.keyman.com* | http://localhost:8060 | http://status-backend.keyman.com.localhost | status-keyman-website |
+| | http://localhost:8061 | http://status.keyman.com.localhost | status-keyman-public |
+
+\* Note that status.keyman.com runs in two containers in development to allow for live reload and separation of logs for backend and frontend.
+In production, only port 8060 is used.
#### Remove the Docker container and image
1. Run `./build.sh clean`.
@@ -96,15 +101,15 @@ Refer to **Port lookup table** above for Docker container names
The table below shows server-side dependencies for each website
-|Website | Depends On |
-|----------------------|------------- |
-| s.keyman.com |
|
-| downloads.keyman.com |
|
-| api.keyman.com | downloads.keyman.com
s.keyman.com |
-| keymanweb.com | api.keyman.com |
+| Website | Depends On |
+|----------------------|----------------------------------------|
+| s.keyman.com |
|
+| downloads.keyman.com |
|
+| api.keyman.com | downloads.keyman.com
s.keyman.com |
+| keymanweb.com | api.keyman.com |
| keyman.com | api.keyman.com
downloads.keyman.com |
| help.keyman.com | api.keyman.com
downloads.keyman.com |
-
+| status.keyman.com | api.keyman.com
downloads.keyman.com |
---------
diff --git a/ios/Cartfile b/ios/Cartfile
index 9ffc07d330..49beca6729 100644
--- a/ios/Cartfile
+++ b/ios/Cartfile
@@ -1,4 +1,4 @@
github "weichsel/ZIPFoundation" ~> 0.9
github "devicekit/DeviceKit" ~> 5.0
github "ashleymills/Reachability.swift"
-github "getsentry/sentry-cocoa" ~> 8.38.0
+github "getsentry/sentry-cocoa" ~> 8.58
diff --git a/ios/Cartfile.resolved b/ios/Cartfile.resolved
index ca05da1ae9..54775dca04 100644
--- a/ios/Cartfile.resolved
+++ b/ios/Cartfile.resolved
@@ -1,4 +1,4 @@
github "ashleymills/Reachability.swift" "v5.2.4"
-github "devicekit/DeviceKit" "5.5.0"
-github "getsentry/sentry-cocoa" "8.44.0"
-github "weichsel/ZIPFoundation" "0.9.19"
+github "devicekit/DeviceKit" "5.7.0"
+github "getsentry/sentry-cocoa" "8.58.0"
+github "weichsel/ZIPFoundation" "0.9.20"
diff --git a/web/build.sh b/web/build.sh
index 2d7aed9a48..cbbaaca183 100755
--- a/web/build.sh
+++ b/web/build.sh
@@ -9,6 +9,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
## END STANDARD BUILD SCRIPT INCLUDE
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
+. "$KEYMAN_ROOT/web/common.inc.sh"
# ################################ Main script ################################
@@ -75,8 +76,6 @@ builder_describe_outputs \
build:tools "/web/build/tools/building/sourcemap-root/index.js" \
build:test-pages "/web/build/test-resources/sentry-manager.js"
-BUNDLE_CMD="node ${KEYMAN_ROOT}/web/src/tools/es-bundling/build/common-bundle.mjs"
-
#### Build action definitions ####
##################### TODO: call child action, verify things work as expected!
@@ -107,8 +106,8 @@ precompile() {
# types built-in to Node aren't available, and @web/test-runner doesn't do
# treeshaking when loading the imports. We work around by pre-compiling.
for f in "${DIR}"/*.js; do
- ${BUNDLE_CMD} "${f}" \
- --out "${f%.js}".mjs \
+ node "${LIB_BUNDLER}" "${f}" \
+ --out "${f%.js}".mjs \
--format esm
done
}
diff --git a/web/common.inc.sh b/web/common.inc.sh
index 32249094a3..c88c081900 100644
--- a/web/common.inc.sh
+++ b/web/common.inc.sh
@@ -1,7 +1,7 @@
#!/usr/bin/env bash
#
-BUNDLE_CMD="node $KEYMAN_ROOT/web/src/tools/es-bundling/build/common-bundle.mjs"
+LIB_BUNDLER="${KEYMAN_ROOT}/web/src/tools/es-bundling/build/common-bundle.mjs"
# Compiles all build products corresponding to the specified target.
# This should be called from the working directory of a child project's
diff --git a/web/src/app/browser/build.sh b/web/src/app/browser/build.sh
index a61ce1517c..7a168a5d46 100755
--- a/web/src/app/browser/build.sh
+++ b/web/src/app/browser/build.sh
@@ -49,25 +49,25 @@ compile_and_copy() {
BUILD_ROOT="${KEYMAN_ROOT}/web/build/app/browser"
SRC_ROOT="${KEYMAN_ROOT}/web/src/app/browser/src"
- $BUNDLE_CMD "${SRC_ROOT}/debug-main.js" \
- --out "${BUILD_ROOT}/debug/keymanweb.js" \
- --charset "utf8" \
- --sourceRoot "@keymanapp/keyman/web/build/app/browser/debug" \
- --target "es6"
+ node "${LIB_BUNDLER}" "${SRC_ROOT}/debug-main.js" \
+ --out "${BUILD_ROOT}/debug/keymanweb.js" \
+ --charset "utf8" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/browser/debug" \
+ --target "es6"
- $BUNDLE_CMD "${SRC_ROOT}/release-main.js" \
- --out "${BUILD_ROOT}/release/keymanweb.js" \
- --charset "utf8" \
- --profile "${BUILD_ROOT}/filesize-profile.log" \
- --sourceRoot "@keymanapp/keyman/web/build/app/browser/release" \
- --minify \
- --target "es6"
+ node "${LIB_BUNDLER}" "${SRC_ROOT}/release-main.js" \
+ --out "${BUILD_ROOT}/release/keymanweb.js" \
+ --charset "utf8" \
+ --profile "${BUILD_ROOT}/filesize-profile.log" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/browser/release" \
+ --minify \
+ --target "es6"
- $BUNDLE_CMD "${BUILD_ROOT}/obj/test-index.js" \
- --out "${BUILD_ROOT}/lib/index.mjs" \
- --charset "utf8" \
- --sourceRoot "@keymanapp/keyman/web/build/app/browser/lib" \
- --format esm
+ node "${LIB_BUNDLER}" "${BUILD_ROOT}/obj/test-index.js" \
+ --out "${BUILD_ROOT}/lib/index.mjs" \
+ --charset "utf8" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/browser/lib" \
+ --format esm
mkdir -p "$KEYMAN_ROOT/web/build/app/resources/osk"
cp -R "$KEYMAN_ROOT/web/src/resources/osk/." "$KEYMAN_ROOT/web/build/app/resources/osk/"
diff --git a/web/src/app/ui/build.sh b/web/src/app/ui/build.sh
index 045cdac8d0..145cea8e4b 100755
--- a/web/src/app/ui/build.sh
+++ b/web/src/app/ui/build.sh
@@ -51,13 +51,13 @@ compile_and_copy() {
for type in ${types[@]}
do
filename="kmwui${type}"
- $BUNDLE_CMD "${BUILD_ROOT}/obj/$filename.js" \
- --out "${BUILD_ROOT}/debug/$filename.js" \
- --sourceRoot "@keymanapp/keyman/web/build/app/ui/debug"
+ node "${LIB_BUNDLER}" "${BUILD_ROOT}/obj/$filename.js" \
+ --out "${BUILD_ROOT}/debug/$filename.js" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/ui/debug"
- $BUNDLE_CMD "${BUILD_ROOT}/obj/$filename.js" \
- --out "${BUILD_ROOT}/release/$filename.js" \
- --sourceRoot "@keymanapp/keyman/web/build/app/ui/release" \
+ node "${LIB_BUNDLER}" "${BUILD_ROOT}/obj/$filename.js" \
+ --out "${BUILD_ROOT}/release/$filename.js" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/ui/release" \
--minify
done
diff --git a/web/src/app/webview/build.sh b/web/src/app/webview/build.sh
index 32534e6950..72708eabea 100755
--- a/web/src/app/webview/build.sh
+++ b/web/src/app/webview/build.sh
@@ -43,19 +43,19 @@ compile_and_copy() {
BUILD_ROOT="${KEYMAN_ROOT}/web/build/app/webview"
SRC_ROOT="${KEYMAN_ROOT}/web/src/app/webview/src"
- $BUNDLE_CMD "${SRC_ROOT}/debug-main.js" \
- --out "${BUILD_ROOT}/debug/keymanweb-webview.js" \
- --charset "utf8" \
- --sourceRoot "@keymanapp/keyman/web/build/app/webview/debug" \
- --target "es6"
+ node "${LIB_BUNDLER}" "${SRC_ROOT}/debug-main.js" \
+ --out "${BUILD_ROOT}/debug/keymanweb-webview.js" \
+ --charset "utf8" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/webview/debug" \
+ --target "es6"
- $BUNDLE_CMD "${SRC_ROOT}/release-main.js" \
- --out "${BUILD_ROOT}/release/keymanweb-webview.js" \
- --charset "utf8" \
- --profile "${BUILD_ROOT}/filesize-profile.log" \
- --sourceRoot "@keymanapp/keyman/web/build/app/webview/release" \
- --minify \
- --target "es6"
+ node "${LIB_BUNDLER}" "${SRC_ROOT}/release-main.js" \
+ --out "${BUILD_ROOT}/release/keymanweb-webview.js" \
+ --charset "utf8" \
+ --profile "${BUILD_ROOT}/filesize-profile.log" \
+ --sourceRoot "@keymanapp/keyman/web/build/app/webview/release" \
+ --minify \
+ --target "es6"
mkdir -p "$KEYMAN_ROOT/web/build/app/resources/osk"
cp -R "$KEYMAN_ROOT/web/src/resources/osk/." "$KEYMAN_ROOT/web/build/app/resources/osk/"
diff --git a/web/src/engine/attachment/build.sh b/web/src/engine/attachment/build.sh
index 042c5aa83e..0c37fb62c1 100755
--- a/web/src/engine/attachment/build.sh
+++ b/web/src/engine/attachment/build.sh
@@ -36,8 +36,8 @@ builder_parse "$@"
do_build () {
compile $SUBPROJECT_NAME
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/common/web-utils/build.sh b/web/src/engine/common/web-utils/build.sh
index 23d38cb952..8be7be6df3 100755
--- a/web/src/engine/common/web-utils/build.sh
+++ b/web/src/engine/common/web-utils/build.sh
@@ -15,8 +15,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
SUBPROJECT_NAME=engine/common/web-utils
BUILD_DIR="/web/src/engine/common/web-utils/build"
-BUNDLE_CMD="node ${KEYMAN_ROOT}/web/src/tools/es-bundling/build/common-bundle.mjs"
-
################################ Main script ################################
builder_describe \
@@ -37,11 +35,10 @@ function do_build() {
# May be useful one day, for building a mass .d.ts for KMW as a whole.
# So... tsc does declaration-bundling on its own pretty well, at least for local development.
tsc --emitDeclarationOnly --outFile "${KEYMAN_ROOT}/${BUILD_DIR}/lib/index.d.ts"
-
# One of the functions (timedPromise) is quite helpful for automated testing, even in the DOM.
# So, to make sure it's easily-accessible for the DOM-based tests...
- ${BUNDLE_CMD} "${KEYMAN_ROOT}/${BUILD_DIR}/obj/index.js" \
- --out "${KEYMAN_ROOT}/${BUILD_DIR}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/${BUILD_DIR}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/${BUILD_DIR}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/element-wrappers/build.sh b/web/src/engine/element-wrappers/build.sh
index 055c93b00e..18d7f2c0ed 100755
--- a/web/src/engine/element-wrappers/build.sh
+++ b/web/src/engine/element-wrappers/build.sh
@@ -34,8 +34,8 @@ builder_parse "$@"
do_build () {
compile $SUBPROJECT_NAME
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/events/build.sh b/web/src/engine/events/build.sh
index eeeb144949..256404680f 100755
--- a/web/src/engine/events/build.sh
+++ b/web/src/engine/events/build.sh
@@ -35,8 +35,8 @@ builder_parse "$@"
do_build () {
compile $SUBPROJECT_NAME
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/interfaces/build.sh b/web/src/engine/interfaces/build.sh
index 3ea80fdc7a..8611be7ad4 100755
--- a/web/src/engine/interfaces/build.sh
+++ b/web/src/engine/interfaces/build.sh
@@ -36,8 +36,8 @@ builder_parse "$@"
do_build () {
compile $SUBPROJECT_NAME
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/js-processor/build.sh b/web/src/engine/js-processor/build.sh
index 6d5989b515..8faaaeded5 100755
--- a/web/src/engine/js-processor/build.sh
+++ b/web/src/engine/js-processor/build.sh
@@ -31,8 +31,8 @@ builder_parse "$@"
do_build () {
compile "${SUBPROJECT_NAME}"
- ${BUNDLE_CMD} "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/keyboard-storage/build.sh b/web/src/engine/keyboard-storage/build.sh
index a6a233bfd8..fc38ed3993 100755
--- a/web/src/engine/keyboard-storage/build.sh
+++ b/web/src/engine/keyboard-storage/build.sh
@@ -34,16 +34,16 @@ builder_parse "$@"
do_build () {
compile $SUBPROJECT_NAME
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/domCloudRequester.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/dom-cloud-requester.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/domCloudRequester.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/dom-cloud-requester.mjs" \
--format esm
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/nodeCloudRequester.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/node-cloud-requester.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/nodeCloudRequester.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/node-cloud-requester.mjs" \
--format esm \
--platform node
}
diff --git a/web/src/engine/keyboard/build.sh b/web/src/engine/keyboard/build.sh
index 7260bc5cc6..3a79bbe64c 100755
--- a/web/src/engine/keyboard/build.sh
+++ b/web/src/engine/keyboard/build.sh
@@ -49,20 +49,20 @@ function do_build() {
# Base product - the main keyboard processor
builder_echo "Bundle base product - the main keyboard processor"
- ${BUNDLE_CMD} "${BUILD_DIR}/obj/index.js" \
- --out "${BUILD_DIR}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${BUILD_DIR}/obj/index.js" \
+ --out "${BUILD_DIR}/lib/index.mjs" \
--format esm
# The DOM-oriented keyboard loader
builder_echo "Bundle the DOM-oriented keyboard loader"
- ${BUNDLE_CMD} "${BUILD_DIR}/obj/keyboards/loaders/dom-keyboard-loader.js" \
- --out "${BUILD_DIR}/lib/dom-keyboard-loader.mjs" \
+ node "${LIB_BUNDLER}" "${BUILD_DIR}/obj/keyboards/loaders/dom-keyboard-loader.js" \
+ --out "${BUILD_DIR}/lib/dom-keyboard-loader.mjs" \
--format esm
# The Node-oriented keyboard loader
builder_echo "Bundle the Node-oriented keyboard loader"
- ${BUNDLE_CMD} "${BUILD_DIR}/obj/keyboards/loaders/node-keyboard-loader.js" \
- --out "${BUILD_DIR}/lib/node-keyboard-loader.mjs" \
+ node "${LIB_BUNDLER}" "${BUILD_DIR}/obj/keyboards/loaders/node-keyboard-loader.js" \
+ --out "${BUILD_DIR}/lib/node-keyboard-loader.mjs" \
--format esm \
--platform node
diff --git a/web/src/engine/main/build.sh b/web/src/engine/main/build.sh
index 6cca867d88..54a12cc841 100755
--- a/web/src/engine/main/build.sh
+++ b/web/src/engine/main/build.sh
@@ -41,8 +41,8 @@ builder_parse "$@"
do_build () {
compile $SUBPROJECT_NAME
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/osk/build.sh b/web/src/engine/osk/build.sh
index 8c82560f4e..09ab1818c3 100755
--- a/web/src/engine/osk/build.sh
+++ b/web/src/engine/osk/build.sh
@@ -49,8 +49,8 @@ do_configure() {
do_build() {
compile "${SUBPROJECT_NAME}"
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/${SUBPROJECT_NAME}/lib/index.mjs" \
--format esm
echo "Validating gesture model and set references"
diff --git a/web/src/engine/osk/gesture-processor/build.sh b/web/src/engine/osk/gesture-processor/build.sh
index 77c5e3454e..d207e8d587 100755
--- a/web/src/engine/osk/gesture-processor/build.sh
+++ b/web/src/engine/osk/gesture-processor/build.sh
@@ -12,8 +12,6 @@ SUBPROJECT_NAME=engine/osk/gesture-processor
. "${KEYMAN_ROOT}/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
-BUNDLE_CMD="node $KEYMAN_ROOT/web/src/tools/es-bundling/build/common-bundle.mjs"
-
BUILD_DIR="/web/src/engine/osk/gesture-processor/build"
################################ Main script ################################
@@ -46,8 +44,8 @@ function do_build_module() {
# Build
tsc --build $builder_verbose
- $BUNDLE_CMD "${KEYMAN_ROOT}/${BUILD_DIR}/obj/index.js" \
- --out "${KEYMAN_ROOT}/${BUILD_DIR}/lib/index.mjs" \
+ node "$LIB_BUNDLER" "${KEYMAN_ROOT}/${BUILD_DIR}/obj/index.js" \
+ --out "${KEYMAN_ROOT}/${BUILD_DIR}/lib/index.mjs" \
--format esm
}
diff --git a/web/src/engine/osk/gesture-processor/src/tools/build.sh b/web/src/engine/osk/gesture-processor/src/tools/build.sh
index 735e943ecc..0fe33fe784 100755
--- a/web/src/engine/osk/gesture-processor/src/tools/build.sh
+++ b/web/src/engine/osk/gesture-processor/src/tools/build.sh
@@ -9,8 +9,6 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/web/common.inc.sh"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
-BUNDLE_CMD="node $KEYMAN_ROOT/web/src/tools/es-bundling/build/common-bundle.mjs"
-
BASE_DIR="/web/src/engine/osk/gesture-processor"
BUILD_DIR="${BASE_DIR}/build"
@@ -71,8 +69,8 @@ function do_build_fixture() {
function do_build_testmodule() {
compile "" "${THIS_SCRIPT_PATH}/unit-test-resources" "${KEYMAN_ROOT}/${BUILD_DIR}/tools"
- $BUNDLE_CMD "${KEYMAN_ROOT}/${BUILD_DIR}/tools/obj/index.js" \
- --out "${KEYMAN_ROOT}/${BUILD_DIR}/tools/lib/index.mjs" \
+ node "$LIB_BUNDLER" "${KEYMAN_ROOT}/${BUILD_DIR}/tools/obj/index.js" \
+ --out "${KEYMAN_ROOT}/${BUILD_DIR}/tools/lib/index.mjs" \
--format "esm"
}
diff --git a/web/src/engine/osk/gesture-processor/src/tools/host-fixture/extract-fixture.sh b/web/src/engine/osk/gesture-processor/src/tools/host-fixture/extract-fixture.sh
index f8a1998104..f0549af298 100755
--- a/web/src/engine/osk/gesture-processor/src/tools/host-fixture/extract-fixture.sh
+++ b/web/src/engine/osk/gesture-processor/src/tools/host-fixture/extract-fixture.sh
@@ -7,7 +7,7 @@ set -eu
# This script operates from the perspective of its own directory.
THIS_SCRIPT="$(greadlink -f "${BASH_SOURCE[0]}" 2>/dev/null || readlink -f "${BASH_SOURCE[0]}")"
-cd $(dirname "$THIS_SCRIPT")
+cd "$(dirname "$THIS_SCRIPT")"
# On Windows, `node extractor.cjs` cannot be directly piped; that requires `node.exe`.
# But that doesn't make sense on other platforms, so... wrapper script.
diff --git a/web/src/engine/predictive-text/build.sh b/web/src/engine/predictive-text/build.sh
index f4872bcd7f..10637db851 100755
--- a/web/src/engine/predictive-text/build.sh
+++ b/web/src/engine/predictive-text/build.sh
@@ -40,8 +40,6 @@ builder_describe_outputs \
build:worker-main "/web/src/engine/worker-main/build/obj/lmlayer.js" \
build:worker-thread "/web/src/engine/worker-thread/build/obj/worker-main.wrapped.js"
-BUNDLE_CMD="node ${KEYMAN_ROOT}/web/src/tools/es-bundling/build/common-bundle.mjs"
-
#### Build action definitions ####
# We can run all clean & configure actions at once without much issue.
diff --git a/web/src/engine/predictive-text/worker-main/build.sh b/web/src/engine/predictive-text/worker-main/build.sh
index 0fc63bfb32..1cfe2ff0dc 100755
--- a/web/src/engine/predictive-text/worker-main/build.sh
+++ b/web/src/engine/predictive-text/worker-main/build.sh
@@ -13,8 +13,7 @@ THIS_SCRIPT="$(readlink -f "${BASH_SOURCE[0]}")"
. "$KEYMAN_ROOT/resources/build/utils.inc.sh"
. "$KEYMAN_ROOT/resources/build/node.inc.sh"
-
-BUNDLE_CMD="node $KEYMAN_ROOT/web/src/tools/es-bundling/build/common-bundle.mjs"
+. "$KEYMAN_ROOT/web/common.inc.sh"
################################ Main script ################################
@@ -47,8 +46,8 @@ function do_build() {
tsc -b ./tsconfig.all.json
# esbuild-bundled products at this level are not intended to be used for anything but testing.
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/src/engine/predictive-text/worker-main/build/obj/web/index.js" \
- --out "${KEYMAN_ROOT}/web/src/engine/predictive-text/worker-main/build/lib/web/index.mjs" \
+ node "$LIB_BUNDLER" "${KEYMAN_ROOT}/web/src/engine/predictive-text/worker-main/build/obj/web/index.js" \
+ --out "${KEYMAN_ROOT}/web/src/engine/predictive-text/worker-main/build/lib/web/index.mjs" \
--format esm
}
diff --git a/web/src/engine/predictive-text/worker-thread/build.sh b/web/src/engine/predictive-text/worker-thread/build.sh
index 25276eaa6e..0b950479b6 100755
--- a/web/src/engine/predictive-text/worker-thread/build.sh
+++ b/web/src/engine/predictive-text/worker-thread/build.sh
@@ -19,9 +19,7 @@ WORKER_OUTPUT_FILENAME=build/lib/worker-main.js
INTERMEDIATE=./build/intermediate
LIB=./build/lib
-bundle_cmd="node ${KEYMAN_ROOT}/web/src/tools/es-bundling/build/common-bundle.mjs"
-
-SRCMAP_CLEANER="node $KEYMAN_ROOT/web/build/tools/building/sourcemap-root/index.js"
+SRCMAP_CLEANER="${KEYMAN_ROOT}/web/build/tools/building/sourcemap-root/index.js"
################################ Main script ################################
@@ -62,26 +60,26 @@ function do_build() {
# The ES6 target needs no polyfills - we go straight to the wrapped version.
- $bundle_cmd src/main/worker-main.ts \
- --out $INTERMEDIATE/worker-main.js \
+ node "$LIB_BUNDLER" src/main/worker-main.ts \
+ --out $INTERMEDIATE/worker-main.js \
--charset "utf8" \
--target "es6" \
--sourceRoot '@keymanapp/keyman/web/src/engine/predictive-text/worker-thread/src/main'
- $SRCMAP_CLEANER \
+ node "$SRCMAP_CLEANER" \
$INTERMEDIATE/worker-main.js.map \
$INTERMEDIATE/worker-main.js.map \
--clean
- $bundle_cmd src/main/worker-main.ts \
- --out $INTERMEDIATE/worker-main.min.js \
+ node "$LIB_BUNDLER" src/main/worker-main.ts \
+ --out $INTERMEDIATE/worker-main.min.js \
--minify \
--charset "utf8" \
--profile build/filesize-profile.log \
--target "es6" \
--sourceRoot '@keymanapp/keyman/web/src/engine/predictive-text/worker-thread/src/main'
- $SRCMAP_CLEANER \
+ node "$SRCMAP_CLEANER" \
$INTERMEDIATE/worker-main.min.js.map \
$INTERMEDIATE/worker-main.min.js.map \
--clean
diff --git a/web/src/engine/sentry-manager/build.sh b/web/src/engine/sentry-manager/build.sh
index 1054e152bc..6c5dd03064 100755
--- a/web/src/engine/sentry-manager/build.sh
+++ b/web/src/engine/sentry-manager/build.sh
@@ -39,9 +39,9 @@ fi
if builder_start_action build; then
tsc --build "$THIS_SCRIPT_PATH/src/tsconfig.json"
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/src/engine/sentry-manager/build/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/src/engine/sentry-manager/build/lib/index.js" \
- --sourceRoot "@keymanapp/keyman/web/src/engine/sentry-manager/build/lib/"
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/src/engine/sentry-manager/build/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/src/engine/sentry-manager/build/lib/index.js" \
+ --sourceRoot "@keymanapp/keyman/web/src/engine/sentry-manager/build/lib/"
builder_finish_action success build
fi
diff --git a/web/src/tools/testing/bulk_rendering/build.sh b/web/src/tools/testing/bulk_rendering/build.sh
index 6c93d9862c..578a1056ab 100755
--- a/web/src/tools/testing/bulk_rendering/build.sh
+++ b/web/src/tools/testing/bulk_rendering/build.sh
@@ -31,9 +31,9 @@ builder_parse "$@"
function do_build ( ) {
tsc --build "$THIS_SCRIPT_PATH/tsconfig.json" $builder_verbose
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/obj/renderer_core.js" \
- --out "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/lib/bulk_render.js" \
- --sourceRoot "@keymanapp/keyman/web/build/$SUBPROJECT_NAME/lib/"
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/obj/renderer_core.js" \
+ --out "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/lib/bulk_render.js" \
+ --sourceRoot "@keymanapp/keyman/web/build/$SUBPROJECT_NAME/lib/"
# To ensure it's available to the testing pages when served via localhost or build agent.
cp "${KEYMAN_ROOT}/node_modules/@zip.js/zip.js/dist/zip.min.js" \
diff --git a/web/src/tools/testing/recorder/build.sh b/web/src/tools/testing/recorder/build.sh
index 7a9b0187ec..ab8f3c6471 100755
--- a/web/src/tools/testing/recorder/build.sh
+++ b/web/src/tools/testing/recorder/build.sh
@@ -33,8 +33,8 @@ do_build ( ) {
compile $SUBPROJECT_NAME
# Base product - the main keyboard processor
- $BUNDLE_CMD "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/obj/index.js" \
- --out "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/lib/index.mjs" \
+ node "${LIB_BUNDLER}" "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/obj/index.js" \
+ --out "${KEYMAN_ROOT}/web/build/$SUBPROJECT_NAME/lib/index.mjs" \
--format esm
}