conductor-remote 1.73.0 → 1.73.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/assets/{index-BGKsDXx_.js → index-CPu66mE4.js} +3 -3
- package/dist/index.html +1 -1
- package/dist/push-sw.js +55 -11
- package/dist/sw.js +1 -1
- package/package.json +1 -1
package/dist/index.html
CHANGED
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
<title>Conductor Remote</title>
|
|
14
14
|
<!-- Runs before the module bundle so it can catch a stale shell that fails to boot. -->
|
|
15
15
|
<script src="/self-heal.js"></script>
|
|
16
|
-
<script type="module" crossorigin src="/assets/index-
|
|
16
|
+
<script type="module" crossorigin src="/assets/index-CPu66mE4.js"></script>
|
|
17
17
|
<link rel="stylesheet" crossorigin href="/assets/index-CXd-zI4t.css">
|
|
18
18
|
<link rel="manifest" href="/manifest.webmanifest"></head>
|
|
19
19
|
<body>
|
package/dist/push-sw.js
CHANGED
|
@@ -6,14 +6,22 @@
|
|
|
6
6
|
// as a static asset, never bundled. Being part of the precache manifest is what makes a
|
|
7
7
|
// change here produce a new `sw.js`, so edits actually ship.
|
|
8
8
|
//
|
|
9
|
-
//
|
|
9
|
+
// Four rules this obeys, every one of them learned from iOS:
|
|
10
10
|
// 1. **Every push shows a notification.** Safari treats a push that resolves without one
|
|
11
11
|
// as abuse and can revoke the subscription, so there is no "suppress if the app is
|
|
12
12
|
// open" branch — the relay only sends when something genuinely happened.
|
|
13
|
-
// 2. **A tap
|
|
13
|
+
// 2. **A tap prefers focusing the existing window** over navigating it. The app is a
|
|
14
14
|
// token-gated SPA; `openWindow` on a live client would remount the whole thing and
|
|
15
15
|
// throw away in-progress composer text, so we focus and post a route instead.
|
|
16
|
-
// 3. **
|
|
16
|
+
// 3. **A focus that didn't land still owes the tap a window.** Nothing here happens by
|
|
17
|
+
// default: a notification click fires this handler and the app comes forward only
|
|
18
|
+
// because the handler asks it to. iOS returns a backgrounded home-screen web app as
|
|
19
|
+
// a live window client whose `focus()` can settle without foregrounding it, so
|
|
20
|
+
// treating "we found a client" as success ended the tap with the phone exactly where
|
|
21
|
+
// it was — a notification that ignores your finger. `focusClient` therefore reports
|
|
22
|
+
// whether the app really came up, and `openWindow` is the fallback rather than the
|
|
23
|
+
// branch for an app that isn't running.
|
|
24
|
+
// 4. **The route is also parked in Cache Storage**, because on iOS neither of the two
|
|
17
25
|
// direct routes survives. A backgrounded home-screen web app is resumed on whatever
|
|
18
26
|
// screen it was left on — `openWindow`'s path is ignored, and a `postMessage` to a
|
|
19
27
|
// frozen page is dropped (WebKit, reported from iOS 17.1 through 18.x and still
|
|
@@ -33,6 +41,43 @@ async function parkRoute(url) {
|
|
|
33
41
|
}
|
|
34
42
|
}
|
|
35
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Is this client one of ours? Parsed in a `try`, because an unparseable client URL
|
|
46
|
+
* throwing here would take the whole handler down and `openWindow` with it — the tap
|
|
47
|
+
* would then do nothing, which is the failure this file is trying to end.
|
|
48
|
+
*/
|
|
49
|
+
function sameOrigin(clientUrl) {
|
|
50
|
+
try {
|
|
51
|
+
return new URL(clientUrl).origin === self.location.origin
|
|
52
|
+
} catch {
|
|
53
|
+
return false
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Bring an already-open app window to the front, and say whether it really came.
|
|
59
|
+
*
|
|
60
|
+
* That answer is the whole point. A notification click has no default action — the app
|
|
61
|
+
* comes forward only because this handler asks it to — so a `focus()` that quietly does
|
|
62
|
+
* nothing ends the tap with the phone exactly where it was, which reads as a
|
|
63
|
+
* notification that ignores your finger. iOS hands back a backgrounded home-screen web
|
|
64
|
+
* app as a live window client, and `focus()` on it can settle without foregrounding
|
|
65
|
+
* anything, so "we found a client" is not "the app is up".
|
|
66
|
+
*
|
|
67
|
+
* A refusal, a resolve with nothing, and a client that reports itself unfocused all
|
|
68
|
+
* count as "no". Answering "no" too readily costs at worst a second `openWindow` on a
|
|
69
|
+
* platform that had already handled the tap; answering "yes" too readily costs the tap.
|
|
70
|
+
*/
|
|
71
|
+
async function focusClient(client) {
|
|
72
|
+
try {
|
|
73
|
+
const focused = await client.focus()
|
|
74
|
+
return !!focused && focused.focused !== false
|
|
75
|
+
} catch {
|
|
76
|
+
// Refused (some platforms want a user activation this event doesn't carry).
|
|
77
|
+
return false
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
36
81
|
self.addEventListener('push', event => {
|
|
37
82
|
const fallback = { title: 'Conductor Remote', body: 'Something changed in a workspace.', url: '/', tag: 'conductor' }
|
|
38
83
|
let data = fallback
|
|
@@ -70,19 +115,18 @@ self.addEventListener('notificationclick', event => {
|
|
|
70
115
|
await parkRoute(url)
|
|
71
116
|
const clients = await self.clients.matchAll({ type: 'window', includeUncontrolled: true })
|
|
72
117
|
for (const client of clients) {
|
|
73
|
-
if (
|
|
118
|
+
if (!sameOrigin(client.url)) continue
|
|
74
119
|
// Handled in web/src/hooks.ts (usePushRouting) — an in-app route change, so the
|
|
75
120
|
// token gate and React state survive the tap. Posted before the focus, since a
|
|
76
121
|
// refused focus is no reason to skip a message the page may well receive.
|
|
77
122
|
client.postMessage({ type: 'push-navigate', url })
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
} catch {
|
|
81
|
-
// focus() can be refused (no user activation on some platforms); on iOS the
|
|
82
|
-
// system foregrounds the web app on the tap regardless.
|
|
83
|
-
}
|
|
84
|
-
return
|
|
123
|
+
if (await focusClient(client)) return
|
|
124
|
+
break
|
|
85
125
|
}
|
|
126
|
+
// Nothing is open, or the focus above never landed. `openWindow` is the only lever
|
|
127
|
+
// left that can put the app on screen, and on an installed iOS web app it launches
|
|
128
|
+
// or resumes the one instance rather than adding a second — the path is what it
|
|
129
|
+
// drops, and the parked route above is what covers that.
|
|
86
130
|
await self.clients.openWindow(url)
|
|
87
131
|
})()
|
|
88
132
|
)
|
package/dist/sw.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const
|
|
1
|
+
if(!self.define){let e,s={};const i=(i,n)=>(i=new URL(i+".js",n).href,s[i]||new Promise(s=>{if("document"in self){const e=document.createElement("script");e.src=i,e.onload=s,document.head.appendChild(e)}else e=i,importScripts(i),s()}).then(()=>{let e=s[i];if(!e)throw new Error(`Module ${i} didn’t register its module`);return e}));self.define=(n,r)=>{const o=e||("document"in self?document.currentScript.src:"")||location.href;if(s[o])return;let l={};const c=e=>i(e,o),t={module:{uri:o},exports:l,require:c};s[o]=Promise.all(n.map(e=>t[e]||c(e))).then(e=>(r(...e),l))}}define(["./workbox-9c191d2f"],function(e){"use strict";importScripts("/push-sw.js"),self.addEventListener("message",e=>{e.data&&"SKIP_WAITING"===e.data.type&&self.skipWaiting()}),e.clientsClaim(),e.precacheAndRoute([{url:"self-heal.js",revision:"49bd63adb25a09341f8d2610e8bd3c76"},{url:"push-sw.js",revision:"e7ef44deca46c0539e6ff7bba5eb815e"},{url:"index.html",revision:"0233482ea1581cc335272d86ff150fde"},{url:"assets/workbox-window.prod.es5-BBnX5xw4.js",revision:null},{url:"assets/index-CXd-zI4t.css",revision:null},{url:"assets/index-CPu66mE4.js",revision:null},{url:"apple-touch-icon.png",revision:"1127bb396b4648add53dce3f22c92aee"},{url:"icon-192.png",revision:"c5e01ac58768627e18ee7b8b6a9239ef"},{url:"icon-512.png",revision:"a40638c55e310312457a621c9a0002c8"},{url:"icon-maskable-512.png",revision:"a9b0d962686287452216492cd2247499"},{url:"icon.svg",revision:"c1aee186821798733dd477e69a0ef243"},{url:"manifest.webmanifest",revision:"cf88fbc5755108a7fe0616fa160a8a15"}],{}),e.cleanupOutdatedCaches(),e.registerRoute(new e.NavigationRoute(e.createHandlerBoundToURL("/index.html"),{denylist:[/^\/api\//]}))});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "conductor-remote",
|
|
3
|
-
"version": "1.73.
|
|
3
|
+
"version": "1.73.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"packageManager": "yarn@4.15.0",
|
|
6
6
|
"description": "Phone control panel for local Conductor agents. Reads ride SQLite + git; prompts ride Conductor's own dispatch path.",
|