瀏覽代碼

feat: Add exit status code to apps

`puter.exit()` now takes a status code, similar to the exit status on
desktop OSes. This is passed to the appClosed event, so that eg a
parent app can know whether its child app ran successfully.
Sam Atkins 1 年之前
父節點
當前提交
7674da4cd2
共有 5 個文件被更改,包括 23 次插入5 次删除
  1. 7 1
      packages/puter-js/src/index.js
  2. 1 0
      packages/puter-js/src/modules/UI.js
  3. 11 2
      src/IPC.js
  4. 1 1
      src/UI/UIWindow.js
  5. 3 1
      src/helpers.js

+ 7 - 1
packages/puter-js/src/index.js

@@ -262,10 +262,16 @@ window.puter = (function() {
             this.updateSubmodules();
         }
 
-        exit = function() {
+        exit = function(statusCode = 0) {
+            if (statusCode && (typeof statusCode !== 'number')) {
+                console.warn('puter.exit() requires status code to be a number. Treating it as 1');
+                statusCode = 1;
+            }
+
             window.parent.postMessage({
                 msg: "exit",
                 appInstanceID: this.appInstanceID,
+                statusCode,
             }, '*');
         }
 

+ 1 - 0
packages/puter-js/src/modules/UI.js

@@ -54,6 +54,7 @@ class AppConnection extends EventListener {
                 this.#isOpen = false;
                 this.emit('close', {
                     appInstanceID: this.targetAppInstanceID,
+                    statusCode: event.data.statusCode,
                 });
             }
         });

+ 11 - 2
src/IPC.js

@@ -1201,6 +1201,15 @@ window.addEventListener('message', async (event) => {
     // exit
     //--------------------------------------------------------
     else if(event.data.msg === 'exit'){
-        $(window.window_for_app_instance(event.data.appInstanceID)).close({bypass_iframe_messaging: true});
+        // Ensure status code is a number. Convert any truthy non-numbers to 1.
+        let status_code = event.data.statusCode ?? 0;
+        if (status_code && (typeof status_code !== 'number')) {
+            status_code = 1;
+        }
+
+        $(window.window_for_app_instance(event.data.appInstanceID)).close({
+            bypass_iframe_messaging: true,
+            status_code,
+        });
     }
-});
+});

+ 1 - 1
src/UI/UIWindow.js

@@ -2887,7 +2887,7 @@ $.fn.close = async function(options) {
             $(`.window[data-parent_uuid="${window_uuid}"]`).close();
 
             // notify other apps that we're closing
-            window.report_app_closed(window_uuid);
+            window.report_app_closed(window_uuid, options.status_code ?? 0);
 
             // remove backdrop
             $(this).closest('.window-backdrop').remove();

+ 3 - 1
src/helpers.js

@@ -3511,7 +3511,7 @@ window.report_app_launched = (instance_id, { uses_sdk = true }) => {
 };
 
 // Run any callbacks to say that the app has closed
-window.report_app_closed = (instance_id) => {
+window.report_app_closed = (instance_id, status_code) => {
     const el_window = window.window_for_app_instance(instance_id);
 
     // notify parent app, if we have one, that we're closing
@@ -3521,6 +3521,7 @@ window.report_app_closed = (instance_id) => {
         parent.contentWindow.postMessage({
             msg: 'appClosed',
             appInstanceID: instance_id,
+            statusCode: status_code ?? 0,
         }, '*');
     }
 
@@ -3530,6 +3531,7 @@ window.report_app_closed = (instance_id) => {
         child.contentWindow.postMessage({
             msg: 'appClosed',
             appInstanceID: instance_id,
+            statusCode: status_code ?? 0,
         }, '*');
     });