Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
278178f
feat: update Gradle and Android build tools versions to 8.14.3 and 8.…
edusperoni Aug 19, 2025
6b76cad
chore: 9.0.0-alpha.0
NathanWalker Aug 24, 2025
6ab9f01
Merge remote-tracking branch 'origin/main' into feat/allow-conditiona…
NathanWalker Aug 24, 2025
00529a8
feat: es module support
NathanWalker Aug 26, 2025
48d5939
feat: es module support
NathanWalker Aug 26, 2025
fbfb74e
feat: es module support
NathanWalker Aug 27, 2025
2067b0b
feat: sbg support for es modules
NathanWalker Aug 27, 2025
bd24b43
fix: application path to use absolute path instead of relative, more …
NathanWalker Aug 27, 2025
66eff21
feat: handle .js and .mjs extensions when loading main
NathanWalker Aug 27, 2025
25ff64e
chore: es module tests
NathanWalker Aug 27, 2025
74e4097
chore: 9.0.0-alpha.1
NathanWalker Aug 28, 2025
9275d5b
feat: provide node:url polyfill
NathanWalker Aug 28, 2025
1d7e32b
chore: 9.0.0-alpha.2
NathanWalker Aug 28, 2025
bd900f7
feat: use terminal reporter and fix tests
NathanWalker Sep 7, 2025
d25130f
fix: unique filename handling with static binding generator
NathanWalker Sep 7, 2025
e66a428
feat: es module dynamic import support
NathanWalker Sep 7, 2025
ce03b17
feat: logScriptLoading - this may be unnecessary really, added for al…
NathanWalker Sep 7, 2025
ccef166
chore: 9.0.0-alpha.3
NathanWalker Sep 9, 2025
bee756c
Merge remote-tracking branch 'origin/main' into feat/allow-conditiona…
NathanWalker Sep 11, 2025
116a45d
Merge remote-tracking branch 'origin/main' into feat/allow-conditiona…
NathanWalker Oct 23, 2025
5b41f8e
feat: esm http loading for hmr enhancements
NathanWalker Oct 23, 2025
cb9390e
feat: http es module support for HMR improvements
NathanWalker Oct 28, 2025
155acd3
feat: improved diagnostic logging for debugging
NathanWalker Oct 28, 2025
e614fd2
Merge remote-tracking branch 'origin/main' into feat/hmr-improvements
NathanWalker Nov 6, 2025
db2cdec
chore: unit test improvements
NathanWalker Nov 6, 2025
1362852
chore: cleanup
NathanWalker Nov 6, 2025
1f348ed
chore: string comparison perf note feedback
NathanWalker Nov 6, 2025
655c2ee
chore: unit test feedback on optional chaining
NathanWalker Nov 6, 2025
f2f5c35
chore: esmodule comparison check in unit test feedback
NathanWalker Nov 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion test-app/app/src/main/assets/app/mainpage.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,4 @@ require('./tests/testQueueMicrotask');

// ES MODULE TESTS
__log("=== Running ES Modules Tests ===");
require("./tests/testESModules");
require("./tests/testESModules.mjs");
103 changes: 0 additions & 103 deletions test-app/app/src/main/assets/app/tests/testESModules.js

This file was deleted.

167 changes: 167 additions & 0 deletions test-app/app/src/main/assets/app/tests/testESModules.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
async function runESModuleTests() {
let passed = 0;
let failed = 0;
const failureDetails = [];

const recordPass = (message, ...args) => {
console.log(`✅ PASS: ${message}`, ...args);
passed++;
};

const recordFailure = (message, options = {}) => {
const { error, details = [] } = options;
const fullMessage = error?.message
? `${message}: ${error.message}`
: message;
console.log(`❌ FAIL: ${fullMessage}`);
details.forEach((detail) => console.log(detail));
if (error?.stack) {
console.log("Stack trace:", error.stack);
}
failed++;
failureDetails.push(fullMessage);
};

const logFinalSummary = () => {
console.log("\n=== ES MODULE TEST RESULTS ===");
console.log("Tests passed:", passed);
console.log("Tests failed:", failed);
console.log("Total tests:", passed + failed);

if (failed === 0) {
console.log("ALL ES MODULE TESTS PASSED!");
} else {
console.log("SOME ES MODULE TESTS FAILED!");
console.log("FAILURE DETECTED: Starting failure logging");
failureDetails.forEach((detail) => {
console.log(` ❌ ${detail}`);
});
}
};

try {
// Test 1: Load .mjs files as ES modules
console.log("\n--- Test 1: Loading .mjs files as ES modules ---");
try {
const moduleExports = await import("~/testSimpleESModule.mjs");
if (moduleExports) {
recordPass("Module exports:", JSON.stringify(moduleExports));
} else {
recordFailure("ES Module loaded but exports are null");
}

if (moduleExports?.moduleType === "ES Module") {
recordPass("moduleType check passed");
} else {
recordFailure("moduleType check failed");
}
} catch (e) {
recordFailure("Error loading ES module", { error: e });
}

// Test 2: Test import.meta functionality
console.log("\n--- Test 2: Testing import.meta functionality ---");
try {
const importMetaModule = await import("~/testImportMeta.mjs");
if (
importMetaModule &&
importMetaModule.default &&
typeof importMetaModule.default === "function"
) {
const metaResults = importMetaModule.default();
console.log(
"import.meta test results:",
JSON.stringify(metaResults, null, 2)
);

if (
metaResults &&
metaResults.hasImportMeta &&
metaResults.hasUrl &&
metaResults.hasDirname
) {
recordPass("import.meta properties present");
console.log(" - import.meta.url:", metaResults.url);
console.log(" - import.meta.dirname:", metaResults.dirname);
} else {
recordFailure("import.meta properties missing", {
details: [
` - hasImportMeta: ${metaResults?.hasImportMeta}`,
` - hasUrl: ${metaResults?.hasUrl}`,
` - hasDirname: ${metaResults?.hasDirname}`,
],
});
}
} else {
recordFailure("import.meta module has no default export function");
}
} catch (e) {
recordFailure("Error testing import.meta", { error: e });
}

// Test 3: Test Worker enhancements
console.log("\n--- Test 3: Testing Worker enhancements ---");
try {
const workerModule = await import("~/testWorkerFeatures.mjs");
if (
workerModule &&
workerModule.testWorkerFeatures &&
typeof workerModule.testWorkerFeatures === "function"
) {
const workerResults = workerModule.testWorkerFeatures();
console.log(
"Worker features test results:",
JSON.stringify(workerResults, null, 2)
);

if (
workerResults &&
workerResults.stringPathSupported &&
workerResults.urlObjectSupported &&
workerResults.tildePathSupported
) {
recordPass("Worker enhancement features present");
console.log(
" - String path support:",
workerResults.stringPathSupported
);
console.log(
" - URL object support:",
workerResults.urlObjectSupported
);
console.log(
" - Tilde path support:",
workerResults.tildePathSupported
);
} else {
recordFailure("Worker enhancement features missing", {
details: [
` - stringPathSupported: ${workerResults?.stringPathSupported}`,
` - urlObjectSupported: ${workerResults?.urlObjectSupported}`,
` - tildePathSupported: ${workerResults?.tildePathSupported}`,
],
});
}
} else {
recordFailure(
"Worker features module has no testWorkerFeatures function"
);
}
} catch (e) {
recordFailure("Error testing Worker features", { error: e });
}
} catch (unexpectedError) {
recordFailure("Unexpected ES module test harness failure", {
error: unexpectedError,
});
} finally {
logFinalSummary();
}

return { passed, failed };
}

// Run the tests immediately (avoid top-level await for broader runtime support)
runESModuleTests().catch((e) => {
console.error("ES Module top-level failure:", e?.message ?? e);
});
Original file line number Diff line number Diff line change
@@ -1,30 +1,32 @@
describe("Runtime exposes", function () {
it("__time a low overhead, high resolution, time in ms.", function() {
it("__time a low overhead, high resolution, time in ms.", function () {
// Try to get the times using Date.now and __time and compare the results, expect them to be somewhat "close".
// Sometimes GC hits after Date.now is captured but before __time or the vice-versa and the test fails,
// so we are giving it several attempts.
for(var i = 0; i < 5; i++) {
for (var i = 0; i < 5; i++) {
try {
var dateTimeStart = Date.now();
var timeStart = __time();
var acc = 0;
var s = android.os.SystemClock.elapsedRealtime();
for (var i = 0; i < 1000; i++) {
var c = android.os.SystemClock.elapsedRealtime();
acc += (c - s);
acc += c - s;
s = c;
}
var dateTimeEnd = Date.now();
var timeEnd = __time();
var dateDelta = dateTimeEnd - dateTimeStart;
var timeDelta = timeEnd - timeStart;
expect(Math.abs(dateDelta - timeDelta) < dateDelta * 0.25).toBe(true);
var tolerance = Math.max(10, dateDelta * 0.5);
expect(timeDelta > 0).toBe(true);
expect(Math.abs(dateDelta - timeDelta) < tolerance).toBe(true);
break;
} catch(e) {
} catch (e) {
if (i == 4) {
throw e;
}
}
}
});
});
});
2 changes: 2 additions & 0 deletions test-app/runtime/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,8 @@ add_library(
src/main/cpp/URLImpl.cpp
src/main/cpp/URLSearchParamsImpl.cpp
src/main/cpp/URLPatternImpl.cpp
src/main/cpp/HMRSupport.cpp
src/main/cpp/DevFlags.cpp

# V8 inspector source files will be included only in Release mode
${INSPECTOR_SOURCES}
Expand Down
38 changes: 38 additions & 0 deletions test-app/runtime/src/main/cpp/DevFlags.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// DevFlags.cpp
#include "DevFlags.h"
#include "JEnv.h"
#include <atomic>
#include <mutex>

namespace tns {

bool IsScriptLoadingLogEnabled() {
static std::atomic<int> cached{-1}; // -1 unknown, 0 false, 1 true
int v = cached.load(std::memory_order_acquire);
if (v != -1) {
return v == 1;
}

static std::once_flag initFlag;
std::call_once(initFlag, []() {
bool enabled = false;
try {
JEnv env;
jclass runtimeClass = env.FindClass("com/tns/Runtime");
if (runtimeClass != nullptr) {
jmethodID mid = env.GetStaticMethodID(runtimeClass, "getLogScriptLoadingEnabled", "()Z");
if (mid != nullptr) {
jboolean res = env.CallStaticBooleanMethod(runtimeClass, mid);
enabled = (res == JNI_TRUE);
}
}
} catch (...) {
// keep default false
}
cached.store(enabled ? 1 : 0, std::memory_order_release);
});

return cached.load(std::memory_order_acquire) == 1;
}

} // namespace tns
10 changes: 10 additions & 0 deletions test-app/runtime/src/main/cpp/DevFlags.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
// DevFlags.h
#pragma once

namespace tns {

// Fast cached flag: whether to log script loading diagnostics.
// First call queries Java once; subsequent calls are atomic loads only.
bool IsScriptLoadingLogEnabled();

}
Loading
Loading