Skip to content

Commit

Permalink
refactor(runtime): improve refresh control and libomp integration
Browse files Browse the repository at this point in the history
  • Loading branch information
jwerle committed Feb 16, 2025
1 parent a7dde15 commit 8d3b71c
Show file tree
Hide file tree
Showing 18 changed files with 385 additions and 128 deletions.
20 changes: 18 additions & 2 deletions api/conduit.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,19 @@ export const DEFAULT_MAX_RECONNECT_TIMEOUT = 256
export const pool = new Set()

// reconnect when application resumes
hooks.onApplicationResume(() => {
hooks.onApplicationResume(async () => {
isApplicationPaused = false
let result
result = await ipc.request('internal.conduit.stop')
if (result.err) {
console.warn(result.err)
}

result = await ipc.request('internal.conduit.start')
if (result.err) {
console.warn(result.err)
}

for (const conduit of pool) {
// @ts-ignore
if (conduit?.shouldReconnect) {
Expand All @@ -51,8 +62,13 @@ hooks.onApplicationResume(() => {
}
})

hooks.onApplicationPause(() => {
hooks.onApplicationPause(async () => {
isApplicationPaused = true
const result = await ipc.request('internal.conduit.stop')
if (result.err) {
console.warn(result.err)
}

for (const conduit of pool) {
if (conduit) {
// @ts-ignore
Expand Down
9 changes: 6 additions & 3 deletions api/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16478,7 +16478,10 @@ declare module "socket:navigation/navigation" {
}

declare module "socket:navigation" {
export {};
export const Navigation: any;
export const NavigationHistoryEntry: any;
const _default: any;
export default _default;
}

declare module "socket:node-esm-loader" {
Expand Down Expand Up @@ -17587,7 +17590,7 @@ declare module "socket:service-worker/notification" {
}

declare module "socket:service-worker/registration" {
export class ServiceWorkerRegistration {
export class ServiceWorkerRegistration extends EventTarget {
constructor(info: any, serviceWorker: any);
get scope(): any;
get updateViaCache(): string;
Expand All @@ -17599,7 +17602,7 @@ declare module "socket:service-worker/registration" {
get navigationPreload(): any;
getNotifications(): Promise<any>;
showNotification(title: any, options: any): Promise<void>;
unregister(): Promise<void>;
unregister(): Promise<boolean>;
update(): Promise<void>;
#private;
}
Expand Down
4 changes: 0 additions & 4 deletions api/internal/primitives.js
Original file line number Diff line number Diff line change
Expand Up @@ -309,10 +309,6 @@ export function init () {
// @ts-ignore
install({ geolocation }, globalThis.navigator, 'geolocation')

if (!globalThis.navigation) {
navigation.apply
}

install({ close })

async function close () {
Expand Down
5 changes: 4 additions & 1 deletion api/service-worker/registration.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
import { showNotification, getNotifications } from './notification.js'
import ipc from '../ipc.js'

export class ServiceWorkerRegistration {
export class ServiceWorkerRegistration extends EventTarget {
#info = null
#active = null
#waiting = null
#installing = null
#onupdatefound = null

constructor (info, serviceWorker) {
super()
this.#info = info

serviceWorker[Symbol.for('socket.runtime.serviceWorker.state')] = info.registration.state
Expand Down Expand Up @@ -110,6 +111,8 @@ export class ServiceWorkerRegistration {
if (result.err) {
throw result.err
}

return true
}

async update () {}
Expand Down
50 changes: 43 additions & 7 deletions bin/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -165,9 +165,6 @@ if [ "$host" == "Darwin" ]; then
die $? "not ok - missing build tools, try \"$(advice "libtool")\""
quiet command -v curl
die $? "not ok - missing curl, try \"$(advice "curl")\""
if ! brew list | grep libomp >/dev/null 2>&1; then
die $? "not ok - missing libomp, try \"$(advice "libomp")\""
fi
fi

if [ "$host" == "Linux" ]; then
Expand Down Expand Up @@ -598,11 +595,47 @@ function _install {
cp -rfp "$BUILD_DIR/$arch-$platform"/lib$_d/*.a "$SOCKET_HOME/lib$_d/$arch-$platform"
fi

if [[ "$host" == "Darwin" ]] && [[ "$platform" != "desktop" ]]; then
if (( do_link == 1 )); then
ln -sf "$BUILD_DIR/$arch-$platform"/lib/*.metallib "$SOCKET_HOME/lib/$arch-$platform"
if [[ "$host" == "Darwin" ]]; then
if [[ "$platform" == "desktop" ]]; then
echo "# locating 'libomp.dylib...'"
local llvms=()
local libomp_path=""

llvms+=($(find /opt/homebrew/opt/llvm* 2>/dev/null))
llvms+=($(echo $LLVM_PATHS | tr ':' ' '))

for path in ${llvms[@]}; do
local libomp="$(find -L "$path" -path '*/lib/libomp.dylib' 2>/dev/null | head -n1)"
if [ -n "$libomp" ] && [ -f "$libomp" ]; then
libomp_path="$libomp"
echo "# found LLVM libomp at: '$libomp_path'"
break
fi
done

if [ -z "$libomp_path" ] || ! [ -f "$libomp_path" ]; then
# Fallback: try to locate a libomp from the standalone libomp package via Homebrew
local fallback_prefix=$(brew --prefix libomp 2>/dev/null || true)
if [ -n "$fallback_prefix" ] && [ -f "$fallback_prefix/lib/libomp.dylib" ]; then
libomp_path="$fallback_prefix/lib/libomp.dylib"
echo "# found standalone libomp at: '$libomp_path'"
else
die 1 "not ok - could not locate 'libomp.dylib'. Please install an LLVM package (preferred) or the libomp package: \"$(advice "libomp")\""
fi
fi

cp -f "$libomp" "$SOCKET_HOME/lib/$arch-desktop/$(basename "$libomp")"
echo "# copied '$libomp_path'"

echo "# modifying the install name of the copied 'libomp.dylib'"
quiet install_name_tool -id "@rpath/$(basename "$libomp_path")" "$SOCKET_HOME/lib/$arch-desktop/$(basename "$libomp")"
die $? "not ok - failed to modify the install name of copied 'libomp.dylib'"
else
cp -rfp "$BUILD_DIR/$arch-$platform"/lib/*.metallib "$SOCKET_HOME/lib/$arch-$platform"
if (( do_link == 1 )); then
ln -sf "$BUILD_DIR/$arch-$platform"/lib/*.metallib "$SOCKET_HOME/lib/$arch-$platform"
else
cp -rfp "$BUILD_DIR/$arch-$platform"/lib/*.metallib "$SOCKET_HOME/lib/$arch-$platform"
fi
fi
fi
fi
Expand Down Expand Up @@ -934,6 +967,9 @@ function _compile_llama {
if [[ "$host" != "Win32" ]]; then
quiet command -v cmake
die $? "not ok - missing cmake, \"$(advice 'cmake')\""
local cflags="-fPIC"
export CFLAGS="$cflags"
export CXXFLAGS="$cflags"

quiet cmake -S . -B build -DCMAKE_INSTALL_PREFIX="$BUILD_DIR/$target-$platform" ${cmake_args[@]}
die $? "not ok - libllama.a (desktop)"
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
"standard": {
"ignore": [
"/api/external/",
"/api/navigation/navigation.js",
"/api/test/fast-deep-equal.js",
"/api/crypto/sodium.js",
"/api/url/urlpattern/urlpattern.js",
Expand Down
33 changes: 29 additions & 4 deletions src/cli/main.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3069,7 +3069,10 @@ int main (int argc, char* argv[]) {
if (platform.mac && isForDesktop) {
log("preparing build for mac");

flags = "-std=c++2a -ObjC++ -v -fopenmp";
flags = "-std=c++2a -ObjC++ -v";
if (!flagCodeSign) {
flags += " -fopenmp";
}
flags += " -framework UniformTypeIdentifiers";
flags += " -framework CoreBluetooth";
flags += " -framework CoreLocation";
Expand All @@ -3091,6 +3094,10 @@ int main (int argc, char* argv[]) {
flags += " -I" + prefixFile();
flags += " -I" + prefixFile("include");
flags += " -L" + prefixFile("lib/" + platform.arch + "-desktop");
if (flagCodeSign) {
flags += " -Wl,-rpath,@executable_path";
}
flags += " -fPIC";
flags += " -lsocket-runtime";
flags += " -lomp";
flags += " -luv";
Expand Down Expand Up @@ -3243,6 +3250,13 @@ int main (int argc, char* argv[]) {
auto credits = tmpl(gCredits, defaultTemplateAttrs);

writeFile(paths.pathResourcesRelativeToUserBuild / "Credits.html", credits);

fs::create_directories(paths.pathPackage / pathBase / "MacOS");
fs::copy(
trim(prefixFile("lib/" + platform.arch + "-desktop/libomp.dylib")),
paths.pathPackage / pathBase / "MacOS" / "libomp.dylib",
fs::copy_options::overwrite_existing
);
}

if (platform.mac && isForDesktop) {
Expand Down Expand Up @@ -5243,6 +5257,13 @@ int main (int argc, char* argv[]) {

entitlementSettings["configured_entitlements"] = "";

if (settings["permissions_allow_unvalidated_native_libraries"] == "true") {
entitlementSettings["configured_entitlements"] += (
" <key>com.apple.security.cs.disable-library-validation</key>\n"
" <true/>\n"
);
}

if (settings["permissions_allow_push_notifications"] == "true") {
entitlementSettings["configured_entitlements"] += (
" <key>com.apple.developer.usernotifications.filtering</key>\n"
Expand Down Expand Up @@ -6623,9 +6644,13 @@ int main (int argc, char* argv[]) {

<< " && codesign"
<< commonFlags.str()
<< paths.pathPackage.string();
<< paths.pathPackage.string()

if (flagDebugMode) {
<< " && codesign"
<< commonFlags.str()
<< (paths.pathPackage / "Contents" / "MacOS" / "libomp.dylib").string();

if (flagDebugMode || flagVerboseMode) {
log(signCommand.str());
}

Expand All @@ -6634,7 +6659,7 @@ int main (int argc, char* argv[]) {
if (r.output.size() > 0) {
if (r.exitCode != 0) {
log("ERROR: Unable to sign application with 'codesign'");
if (flagDebugMode) {
if (flagDebugMode || flagVerboseMode) {
log(r.output);
}
exit(r.exitCode);
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/app/apple.mm
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ - (void) menuWillOpen: (NSMenu*) menu {
if (!w) return;

[w makeKeyAndOrderFront: nil];
[NSApp activateIgnoringOtherApps:YES];
[NSApp activateIgnoringOtherApps: YES];

if (app != nullptr) {
for (auto window : self.app->runtime.windowManager.windows) {
Expand Down
1 change: 1 addition & 0 deletions src/runtime/bridge.hh
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ namespace ssc::runtime::bridge {
Manager& operator = (Manager&&) = delete;

SharedPointer<Bridge> get (int, const BridgeOptions&);
SharedPointer<Bridge> get (int);
bool has (int) const;
bool remove (int);
};
Expand Down
12 changes: 11 additions & 1 deletion src/runtime/bridge/manager.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,17 @@ namespace ssc::runtime::bridge {
});
}

return this->entries[index];
return this->entries.at(index);
}

SharedPointer<Bridge> Manager::get (int index) {
Lock lock(this->mutex);

if (index >= this->entries.size()) {
return nullptr;
}

return this->entries.at(index);
}

bool Manager::has (int index) const {
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/debug.hh
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ static os_log_t SOCKET_RUNTIME_OS_LOG_DEBUG = nullptr;
} \
\
auto string = [NSString stringWithFormat: @fmt, ##__VA_ARGS__]; \
os_log_error( \
os_log_debug( \
SOCKET_RUNTIME_OS_LOG_DEBUG, \
"%{public}s", \
string.UTF8String \
Expand Down
2 changes: 1 addition & 1 deletion src/runtime/ipc/routes.cc
Original file line number Diff line number Diff line change
Expand Up @@ -3807,7 +3807,7 @@ static void mapIPCRoutes (Router *router) {

reply(Result::Data { message, window->json() });

app->runtime.services.timers.setTimeout(16, [=] () {
app->dispatch([app, targetWindowIndex]() {
app->runtime.windowManager.destroyWindow(targetWindowIndex);
});
});
Expand Down
22 changes: 22 additions & 0 deletions src/runtime/webview/navigator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,28 @@ using ssc::runtime::app::App;
{
decisionHandler(WKNavigationResponsePolicyAllow);
}

#if SOCKET_RUNTIME_PLATFORM_IOS
- (void) webView: (WKWebView*) webview
didFinishNavigation: (WKNavigation*) navigation
{
auto app = App::sharedApplication();
if (webview.scrollView.refreshControl && webview.scrollView.refreshControl.refreshing) {
app->dispatch([webview](){
[webview.scrollView.refreshControl endRefreshing];
[UIView animateWithDuration: 0.25 animations: ^{
const auto topInset = webview.superview.safeAreaInsets.top;
auto insets = webview.scrollView.contentInset;
auto offset = webview.scrollView.contentOffset;
insets.top = topInset;
offset.y = -topInset;
webview.scrollView.contentInset = insets;
webview.scrollView.contentOffset = offset;
}];
});
}
}
#endif
@end
#endif

Expand Down
2 changes: 2 additions & 0 deletions src/runtime/webview/preload.cc
Original file line number Diff line number Diff line change
Expand Up @@ -557,7 +557,9 @@ namespace ssc::runtime::webview {
buffers.push_back(";(() => {");
buffers.push_back(tmpl(
R"JAVASCRIPT(
let userScriptExecuted = false
async function userScriptCallback () {
if (userScriptExecuted) return; else userScriptExecuted = true;
{{userScript}}
}

Expand Down
Loading

0 comments on commit 8d3b71c

Please sign in to comment.