Apps are not required to use the Puter SDK. If they don't, then we can
still launch them, close them, and listen to their close event, but are
unable to send messages to them.
Firstly, I was missing an `async` here, which somehow still worked for
me then, but produced errors for me when I tried it today.
Then, actually await the promise.
Finally, actually check the target's parent is us, and not just that it
has the attribute!
I don't know what was going on in my head that day. 🤦♂️
Sending a 'closeApp' message allows an app to close a target app, if it
has permission to do so. Currently, permission is granted if the
requesting app is the parent of the target app, or has godmode set.
A broadcast is a message sent to every running app that uses Puter.js.
Broadcasts have a name and a data payload, and are sent as a 'broadcast'
message.
Send a broadcast using:
`globalThis.services.get('broadcast').sendBroadcast(...)`
When doing so, you have the option to keep the broadcast message around,
so that it can be sent to any newly-launched apps. Sending another
broadcast with the same name will overwrite the previous one, so you
don't have to worry about flooding a new app with duplicates.
Calling `puter.ui.launchApp()` now treats the new app as a child of the
one that launched it.
A child app is given a `puter.parent_instance_id` URL param, containing
its parent's instance ID.
Previously, `launchApp()` would resolve as soon as the app was launched.
This commit changes that, so that it is notified after the child app
sends its READY event to Puter. This means that as soon as `launchApp()`
has completed, the child app is ready to receive messages. The downside
is that launching an app that does not include Puter.js will now not
cause a notification, so `await puter.ui.launchApp()` will not resolve
in that case.
This lets apps communicate with each other, via Puter.
We probably want to limit this in some way, but for now, all apps are
allowed to send messages to any other apps.
The message is:
- `targetAppInstanceID`: The instance ID to send the message to
- `targetAppOrigin`: targetOrigin passed to postMessage(), in case we
want to restrict which URL can receive the message
- `contents`: The message to send to the target
The resizing and repositioning is safe from abuse in that the window's position and size cannot cause it to escape the viewport. More could be done here, e.g. rate limit resize/repos. I will request rate-limiting in a separate issue.