@robotical/webapp-types 3.25.24 → 3.25.25

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.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "marty-web-app",
3
- "version": "3.25.24",
3
+ "version": "3.25.25",
4
4
  "private": true,
5
5
  "engines": {
6
6
  "node": ">=20"
@@ -1,5 +1,7 @@
1
1
  import { type AppUpdateSnapshot } from "../../types/communication-between-apps/wrapper-communication";
2
2
  type UpdateListener = (snapshot: AppUpdateSnapshot) => void;
3
+ export declare const UPDATE_REQUEST_TIMEOUT_MS = 20000;
4
+ export declare const UPDATE_CHECK_STALE_MS = 30000;
3
5
  export declare const isAppUpdateSnapshot: (value: unknown) => value is AppUpdateSnapshot;
4
6
  export declare const publishPhoneAppUpdateState: (value: unknown) => void;
5
7
  export declare const subscribeToPhoneAppUpdates: (listener: UpdateListener) => () => void;
@@ -50,6 +50,10 @@ import isPhoneApp from "./is-phone-app";
50
50
  import { useEffect, useState } from "react";
51
51
  var listeners = new Set();
52
52
  var latestSnapshot = null;
53
+ export var UPDATE_REQUEST_TIMEOUT_MS = 20000;
54
+ export var UPDATE_CHECK_STALE_MS = 30000;
55
+ var readyRequest = null;
56
+ var checkRequest = null;
53
57
  var isNativeUpdate = function (value) {
54
58
  if (!value || typeof value !== "object") {
55
59
  return false;
@@ -97,13 +101,44 @@ export var subscribeToPhoneAppUpdates = function (listener) {
97
101
  listeners.delete(listener);
98
102
  };
99
103
  };
104
+ var useCheckingDeadline = function (kind, status) {
105
+ useEffect(function () {
106
+ if (status !== 'checking') {
107
+ return;
108
+ }
109
+ var deadline = Date.now() + UPDATE_CHECK_STALE_MS;
110
+ var expire = function () {
111
+ var _a;
112
+ var _b;
113
+ if (Date.now() < deadline || ((_b = latestSnapshot === null || latestSnapshot === void 0 ? void 0 : latestSnapshot.checks) === null || _b === void 0 ? void 0 : _b[kind]) !== 'checking') {
114
+ return;
115
+ }
116
+ publishPhoneAppUpdateState(__assign(__assign({}, latestSnapshot), { checks: __assign(__assign({}, latestSnapshot.checks), (_a = {}, _a[kind] = 'unknown', _a)) }));
117
+ };
118
+ var timer = setTimeout(expire, UPDATE_CHECK_STALE_MS);
119
+ // WebView timers can pause in the background. Check elapsed time on return.
120
+ var onVisible = function () { if (!document.hidden) {
121
+ expire();
122
+ } };
123
+ document.addEventListener('visibilitychange', onVisible);
124
+ window.addEventListener('pageshow', expire);
125
+ return function () {
126
+ clearTimeout(timer);
127
+ document.removeEventListener('visibilitychange', onVisible);
128
+ window.removeEventListener('pageshow', expire);
129
+ };
130
+ }, [kind, status]);
131
+ };
100
132
  export var usePhoneAppUpdates = function () {
101
- var _a = useState(latestSnapshot), snapshot = _a[0], setSnapshot = _a[1];
133
+ var _a, _b;
134
+ var _c = useState(latestSnapshot), snapshot = _c[0], setSnapshot = _c[1];
102
135
  useEffect(function () { return subscribeToPhoneAppUpdates(setSnapshot); }, []);
136
+ useCheckingDeadline('native', (_a = snapshot === null || snapshot === void 0 ? void 0 : snapshot.checks) === null || _a === void 0 ? void 0 : _a.native);
137
+ useCheckingDeadline('web', (_b = snapshot === null || snapshot === void 0 ? void 0 : snapshot.checks) === null || _b === void 0 ? void 0 : _b.web);
103
138
  return snapshot;
104
139
  };
105
140
  var requestUpdateState = function (message) { return __awaiter(void 0, void 0, void 0, function () {
106
- var snapshot, _a;
141
+ var timer, snapshot, _a;
107
142
  return __generator(this, function (_b) {
108
143
  switch (_b.label) {
109
144
  case 0:
@@ -112,8 +147,11 @@ var requestUpdateState = function (message) { return __awaiter(void 0, void 0, v
112
147
  }
113
148
  _b.label = 1;
114
149
  case 1:
115
- _b.trys.push([1, 3, , 4]);
116
- return [4 /*yield*/, window.wrapperCommunicator.sendMessageAndWait(message, {})];
150
+ _b.trys.push([1, 3, 4, 5]);
151
+ return [4 /*yield*/, Promise.race([
152
+ window.wrapperCommunicator.sendMessageAndWait(message, {}),
153
+ new Promise(function (resolve) { timer = setTimeout(function () { return resolve(null); }, UPDATE_REQUEST_TIMEOUT_MS); }),
154
+ ])];
117
155
  case 2:
118
156
  snapshot = _b.sent();
119
157
  if (!isAppUpdateSnapshot(snapshot)) {
@@ -124,30 +162,47 @@ var requestUpdateState = function (message) { return __awaiter(void 0, void 0, v
124
162
  case 3:
125
163
  _a = _b.sent();
126
164
  return [2 /*return*/, null];
127
- case 4: return [2 /*return*/];
165
+ case 4:
166
+ clearTimeout(timer);
167
+ return [7 /*endfinally*/];
168
+ case 5: return [2 /*return*/];
128
169
  }
129
170
  });
130
171
  }); };
131
172
  export var announcePhoneAppUpdateUiReady = function () {
132
- return requestUpdateState(AppSentMessage.UPDATE_UI_READY);
173
+ if (!readyRequest) {
174
+ readyRequest = requestUpdateState(AppSentMessage.UPDATE_UI_READY).finally(function () { readyRequest = null; });
175
+ }
176
+ return readyRequest;
133
177
  };
134
178
  export var getPhoneAppUpdateState = function () {
135
179
  return requestUpdateState(AppSentMessage.UPDATE_GET_STATE);
136
180
  };
137
- export var checkPhoneAppUpdates = function () { return __awaiter(void 0, void 0, void 0, function () {
138
- var supportsChecks, result, _a, native, web;
139
- return __generator(this, function (_b) {
140
- switch (_b.label) {
181
+ var performUpdateCheck = function () { return __awaiter(void 0, void 0, void 0, function () {
182
+ var _a, supportsChecks, result, _b, native, web;
183
+ return __generator(this, function (_c) {
184
+ switch (_c.label) {
141
185
  case 0:
186
+ _a = !latestSnapshot;
187
+ if (!_a) return [3 /*break*/, 2];
188
+ return [4 /*yield*/, announcePhoneAppUpdateUiReady()];
189
+ case 1:
190
+ _a = !(_c.sent());
191
+ _c.label = 2;
192
+ case 2:
193
+ // A lost cold-start reply must not permanently remove access to update checks.
194
+ if (_a) {
195
+ return [2 /*return*/, null];
196
+ }
142
197
  supportsChecks = Boolean(latestSnapshot === null || latestSnapshot === void 0 ? void 0 : latestSnapshot.checks);
143
198
  if (latestSnapshot && supportsChecks) {
144
199
  publishPhoneAppUpdateState(__assign(__assign({}, latestSnapshot), { checks: { native: "checking", web: "checking" } }));
145
200
  }
146
201
  return [4 /*yield*/, requestUpdateState(supportsChecks ? AppSentMessage.UPDATE_CHECK_NOW : AppSentMessage.UPDATE_GET_STATE)];
147
- case 1:
148
- result = _b.sent();
202
+ case 3:
203
+ result = _c.sent();
149
204
  if (!result && (latestSnapshot === null || latestSnapshot === void 0 ? void 0 : latestSnapshot.checks)) {
150
- _a = latestSnapshot.checks, native = _a.native, web = _a.web;
205
+ _b = latestSnapshot.checks, native = _b.native, web = _b.web;
151
206
  publishPhoneAppUpdateState(__assign(__assign({}, latestSnapshot), { checks: {
152
207
  native: native === "checking" ? "unknown" : native,
153
208
  web: web === "checking" ? "unknown" : web,
@@ -157,6 +212,12 @@ export var checkPhoneAppUpdates = function () { return __awaiter(void 0, void 0,
157
212
  }
158
213
  });
159
214
  }); };
215
+ export var checkPhoneAppUpdates = function () {
216
+ if (!checkRequest) {
217
+ checkRequest = performUpdateCheck().finally(function () { checkRequest = null; });
218
+ }
219
+ return checkRequest;
220
+ };
160
221
  export var applyPhoneWebUpdate = function () { return __awaiter(void 0, void 0, void 0, function () {
161
222
  var response, _a;
162
223
  return __generator(this, function (_b) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@robotical/webapp-types",
3
- "version": "3.25.24",
3
+ "version": "3.25.25",
4
4
  "description": "Type definitions for the Application Manager",
5
5
  "main": "dist/application-manager.d.ts",
6
6
  "types": "dist/application-manager.d.ts",