@g9tm/lynxcontrols-progress-overlay 1.4.0
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/README.md +57 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.jsx +2 -0
- package/dist/model.d.ts +188 -0
- package/dist/model.d.ts.map +1 -0
- package/dist/model.jsx +481 -0
- package/dist/model.jsx.map +1 -0
- package/dist/progress-overlay.css +156 -0
- package/dist/progress-overlay.css.map +1 -0
- package/dist/service.d.ts +66 -0
- package/dist/service.d.ts.map +1 -0
- package/dist/service.jsx +274 -0
- package/dist/service.jsx.map +1 -0
- package/package.json +32 -0
package/dist/model.jsx
ADDED
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
function _define_property(obj, key, value) {
|
|
2
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
3
|
+
value: value,
|
|
4
|
+
enumerable: true,
|
|
5
|
+
configurable: true,
|
|
6
|
+
writable: true
|
|
7
|
+
});
|
|
8
|
+
else obj[key] = value;
|
|
9
|
+
return obj;
|
|
10
|
+
}
|
|
11
|
+
const g9ProgressReport = Object.freeze({
|
|
12
|
+
at: (ratio, stage, detail)=>({
|
|
13
|
+
ratio,
|
|
14
|
+
stage: null != stage ? stage : null,
|
|
15
|
+
detail: null != detail ? detail : null
|
|
16
|
+
}),
|
|
17
|
+
indeterminate: (stage, detail)=>({
|
|
18
|
+
ratio: null,
|
|
19
|
+
stage: null != stage ? stage : null,
|
|
20
|
+
detail: null != detail ? detail : null
|
|
21
|
+
}),
|
|
22
|
+
clampedRatio: (report)=>null == report.ratio || Number.isNaN(report.ratio) ? null : Math.min(Math.max(report.ratio, 0), 1),
|
|
23
|
+
isIndeterminate: (report)=>null == report.ratio || Number.isNaN(report.ratio)
|
|
24
|
+
});
|
|
25
|
+
const defaultPlacement = Object.freeze({
|
|
26
|
+
position: 'bottom',
|
|
27
|
+
offset: 0
|
|
28
|
+
});
|
|
29
|
+
const g9ProgressOverlayPlacement = Object.freeze({
|
|
30
|
+
default: defaultPlacement,
|
|
31
|
+
normalize (placement) {
|
|
32
|
+
var _placement_offset;
|
|
33
|
+
if (!placement) return defaultPlacement;
|
|
34
|
+
const offset = Number(null != (_placement_offset = placement.offset) ? _placement_offset : 0);
|
|
35
|
+
return {
|
|
36
|
+
position: 'top' === placement.position ? 'top' : 'bottom',
|
|
37
|
+
offset: Number.isFinite(offset) ? Math.max(0, offset) : 0
|
|
38
|
+
};
|
|
39
|
+
},
|
|
40
|
+
equals (a, b) {
|
|
41
|
+
const x = g9ProgressOverlayPlacement.normalize(a);
|
|
42
|
+
const y = g9ProgressOverlayPlacement.normalize(b);
|
|
43
|
+
return x.position === y.position && x.offset === y.offset;
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
const g9ProgressQueuedCount = Object.freeze({
|
|
47
|
+
value: (count)=>Number.isFinite(count) ? Math.max(0, Math.trunc(count)) : 0,
|
|
48
|
+
hasQueue: (count)=>g9ProgressQueuedCount.value(count) > 0
|
|
49
|
+
});
|
|
50
|
+
const g9ProgressTimings = Object.freeze({
|
|
51
|
+
successTerminalMs: 2200,
|
|
52
|
+
cancelWatchdogMs: 5000,
|
|
53
|
+
reportMinIntervalMs: 100,
|
|
54
|
+
appearMs: 260,
|
|
55
|
+
disappearMs: 220,
|
|
56
|
+
insetGlideMs: 220
|
|
57
|
+
});
|
|
58
|
+
class G9ProgressSession {
|
|
59
|
+
get active() {
|
|
60
|
+
return !this.disposedValue && this.snapshot.mounted;
|
|
61
|
+
}
|
|
62
|
+
get leaseCount() {
|
|
63
|
+
return this.leases.length;
|
|
64
|
+
}
|
|
65
|
+
update(patch) {
|
|
66
|
+
this.snapshot = {
|
|
67
|
+
...this.snapshot,
|
|
68
|
+
...patch
|
|
69
|
+
};
|
|
70
|
+
for (const listener of Array.from(this.listeners))listener();
|
|
71
|
+
}
|
|
72
|
+
resetRunning(contextText) {
|
|
73
|
+
this.canceling = false;
|
|
74
|
+
this.terminal = 'none';
|
|
75
|
+
this.failureAcknowledged = false;
|
|
76
|
+
this.retryAction = null;
|
|
77
|
+
this.pendingReport = null;
|
|
78
|
+
this.stopTimer('watchdog');
|
|
79
|
+
this.update({
|
|
80
|
+
state: 'running',
|
|
81
|
+
minimized: false,
|
|
82
|
+
contextText,
|
|
83
|
+
ratio: null,
|
|
84
|
+
stage: null,
|
|
85
|
+
detail: null,
|
|
86
|
+
terminalTitle: null,
|
|
87
|
+
terminalSubtitle: null,
|
|
88
|
+
retryText: null,
|
|
89
|
+
canRetry: false,
|
|
90
|
+
countdownMs: 0,
|
|
91
|
+
leaving: false
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
stopTimer(which) {
|
|
95
|
+
const handle = this.timers[which];
|
|
96
|
+
if (null !== handle) this.config.clearTimer(handle);
|
|
97
|
+
this.timers[which] = null;
|
|
98
|
+
}
|
|
99
|
+
addLease(contextText) {
|
|
100
|
+
const lease = {
|
|
101
|
+
id: ++this.sequence,
|
|
102
|
+
contextText: null != contextText ? contextText : ''
|
|
103
|
+
};
|
|
104
|
+
if (this.disposedValue) return {
|
|
105
|
+
dispose: ()=>Promise.resolve(),
|
|
106
|
+
disposed: true
|
|
107
|
+
};
|
|
108
|
+
const wasEmpty = 0 === this.leases.length;
|
|
109
|
+
this.leases.push(lease);
|
|
110
|
+
if (this.canceling) {
|
|
111
|
+
this.canceling = false;
|
|
112
|
+
this.stopTimer('watchdog');
|
|
113
|
+
}
|
|
114
|
+
if (wasEmpty) {
|
|
115
|
+
const acks = this.ackWaiters;
|
|
116
|
+
this.ackWaiters = [];
|
|
117
|
+
this.resetRunning(lease.contextText);
|
|
118
|
+
if (!this.snapshot.mounted || this.snapshot.leaving) {
|
|
119
|
+
this.stopTimer('leave');
|
|
120
|
+
this.update({
|
|
121
|
+
mounted: true,
|
|
122
|
+
leaving: false
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
for (const ack of acks)ack();
|
|
126
|
+
}
|
|
127
|
+
let disposed = false;
|
|
128
|
+
const handle = {
|
|
129
|
+
dispose: ()=>{
|
|
130
|
+
if (disposed) return Promise.resolve();
|
|
131
|
+
disposed = true;
|
|
132
|
+
return this.release(lease);
|
|
133
|
+
},
|
|
134
|
+
get disposed () {
|
|
135
|
+
return disposed;
|
|
136
|
+
}
|
|
137
|
+
};
|
|
138
|
+
return handle;
|
|
139
|
+
}
|
|
140
|
+
release(lease) {
|
|
141
|
+
const index = this.leases.indexOf(lease);
|
|
142
|
+
if (index < 0) return Promise.resolve();
|
|
143
|
+
this.leases.splice(index, 1);
|
|
144
|
+
if (this.leases.length > 0) {
|
|
145
|
+
if (0 === index) this.resetRunning(this.leases[0].contextText);
|
|
146
|
+
return Promise.resolve();
|
|
147
|
+
}
|
|
148
|
+
return this.closeWhenSeen();
|
|
149
|
+
}
|
|
150
|
+
closeWhenSeen() {
|
|
151
|
+
return new Promise((resolve)=>{
|
|
152
|
+
const step = ()=>{
|
|
153
|
+
if (this.disposedValue) return resolve();
|
|
154
|
+
if (this.leases.length > 0) return resolve();
|
|
155
|
+
if (this.retryRunning) return void this.retryRunning.then(step, step);
|
|
156
|
+
if ('error' === this.terminal && !this.failureAcknowledged) return void this.ackWaiters.push(step);
|
|
157
|
+
const remaining = 'success' === this.terminal ? this.successUntil - this.config.now() : 0;
|
|
158
|
+
if (remaining > 0) {
|
|
159
|
+
this.update({
|
|
160
|
+
countdownMs: remaining
|
|
161
|
+
});
|
|
162
|
+
this.timers.wait = this.config.setTimer(()=>{
|
|
163
|
+
this.timers.wait = null;
|
|
164
|
+
this.successUntil = -1 / 0;
|
|
165
|
+
step();
|
|
166
|
+
}, remaining);
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
this.tearDown();
|
|
170
|
+
resolve();
|
|
171
|
+
};
|
|
172
|
+
step();
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
tearDown() {
|
|
176
|
+
const wasCanceling = this.canceling;
|
|
177
|
+
this.canceling = false;
|
|
178
|
+
this.stopTimer('watchdog');
|
|
179
|
+
this.stopTimer('report');
|
|
180
|
+
this.stopTimer('relocate');
|
|
181
|
+
this.settleMove();
|
|
182
|
+
this.pendingReport = null;
|
|
183
|
+
this.update({
|
|
184
|
+
leaving: true,
|
|
185
|
+
minimized: false,
|
|
186
|
+
relocating: null
|
|
187
|
+
});
|
|
188
|
+
this.timers.leave = this.config.setTimer(()=>{
|
|
189
|
+
this.timers.leave = null;
|
|
190
|
+
if (0 === this.leases.length) this.update({
|
|
191
|
+
mounted: false,
|
|
192
|
+
leaving: false
|
|
193
|
+
});
|
|
194
|
+
}, g9ProgressTimings.disappearMs);
|
|
195
|
+
if (wasCanceling) this.safe(()=>this.config.onCancelled());
|
|
196
|
+
}
|
|
197
|
+
report(report) {
|
|
198
|
+
if (this.disposedValue || !this.snapshot.mounted) return;
|
|
199
|
+
this.pendingReport = report;
|
|
200
|
+
if (null !== this.timers.report) return;
|
|
201
|
+
const since = this.config.now() - this.lastReportAt;
|
|
202
|
+
const delay = since >= g9ProgressTimings.reportMinIntervalMs ? 0 : g9ProgressTimings.reportMinIntervalMs - since;
|
|
203
|
+
if (delay <= 0) return void this.flushReport();
|
|
204
|
+
this.timers.report = this.config.setTimer(()=>{
|
|
205
|
+
this.timers.report = null;
|
|
206
|
+
this.flushReport();
|
|
207
|
+
}, delay);
|
|
208
|
+
}
|
|
209
|
+
flushReport() {
|
|
210
|
+
var _report_stage, _report_detail;
|
|
211
|
+
const report = this.pendingReport;
|
|
212
|
+
this.pendingReport = null;
|
|
213
|
+
this.lastReportAt = this.config.now();
|
|
214
|
+
if (!report || 'running' !== this.snapshot.state || g9ProgressReport.isIndeterminate(report)) return;
|
|
215
|
+
const stage = (null == (_report_stage = report.stage) ? void 0 : _report_stage.trim()) ? report.stage.trim() : this.snapshot.stage;
|
|
216
|
+
this.update({
|
|
217
|
+
ratio: g9ProgressReport.clampedRatio(report),
|
|
218
|
+
stage,
|
|
219
|
+
detail: (null == (_report_detail = report.detail) ? void 0 : _report_detail.trim()) ? report.detail.trim() : null
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
reportQueued(count) {
|
|
223
|
+
if (this.disposedValue || !this.snapshot.mounted) return;
|
|
224
|
+
this.update({
|
|
225
|
+
queued: g9ProgressQueuedCount.value(count)
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
cancel() {
|
|
229
|
+
if (this.disposedValue || 'running' !== this.snapshot.state || !this.snapshot.mounted) return;
|
|
230
|
+
this.canceling = true;
|
|
231
|
+
this.update({
|
|
232
|
+
state: 'canceling',
|
|
233
|
+
minimized: false,
|
|
234
|
+
queued: 0
|
|
235
|
+
});
|
|
236
|
+
this.safe(()=>this.config.onCancelRequested());
|
|
237
|
+
this.stopTimer('watchdog');
|
|
238
|
+
this.timers.watchdog = this.config.setTimer(()=>{
|
|
239
|
+
this.timers.watchdog = null;
|
|
240
|
+
if (this.canceling && !this.disposedValue) this.safe(()=>this.config.onCancelSlow());
|
|
241
|
+
}, g9ProgressTimings.cancelWatchdogMs);
|
|
242
|
+
}
|
|
243
|
+
setMinimized(minimized) {
|
|
244
|
+
if (this.disposedValue || !this.snapshot.mounted) return;
|
|
245
|
+
if (minimized && 'running' !== this.snapshot.state) return;
|
|
246
|
+
if (this.snapshot.minimized !== minimized) this.update({
|
|
247
|
+
minimized
|
|
248
|
+
});
|
|
249
|
+
}
|
|
250
|
+
refreshBottomInset(animate = true) {
|
|
251
|
+
if (this.disposedValue || !this.snapshot.mounted) return;
|
|
252
|
+
this.update({
|
|
253
|
+
insetVersion: this.snapshot.insetVersion + 1,
|
|
254
|
+
insetAnimated: animate
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
moveTo(placement, animate = true) {
|
|
258
|
+
const s = this.snapshot;
|
|
259
|
+
if (this.disposedValue || !s.mounted || s.leaving || s.minimized) return Promise.resolve();
|
|
260
|
+
const target = g9ProgressOverlayPlacement.normalize(placement);
|
|
261
|
+
if (null === s.relocating && g9ProgressOverlayPlacement.equals(target, s)) return Promise.resolve();
|
|
262
|
+
this.stopTimer('relocate');
|
|
263
|
+
this.settleMove();
|
|
264
|
+
if (target.position === s.position || !animate) {
|
|
265
|
+
this.update({
|
|
266
|
+
position: target.position,
|
|
267
|
+
offset: target.offset,
|
|
268
|
+
insetAnimated: animate,
|
|
269
|
+
relocating: null
|
|
270
|
+
});
|
|
271
|
+
if (!animate) return Promise.resolve();
|
|
272
|
+
return this.afterMove(g9ProgressTimings.insetGlideMs, ()=>void 0);
|
|
273
|
+
}
|
|
274
|
+
if ('out' !== s.relocating) this.update({
|
|
275
|
+
relocating: 'out'
|
|
276
|
+
});
|
|
277
|
+
return this.afterMove(g9ProgressTimings.disappearMs, ()=>{
|
|
278
|
+
this.update({
|
|
279
|
+
position: target.position,
|
|
280
|
+
offset: target.offset,
|
|
281
|
+
insetAnimated: false,
|
|
282
|
+
relocating: 'in'
|
|
283
|
+
});
|
|
284
|
+
return 16;
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
afterMove(ms, step) {
|
|
288
|
+
return new Promise((resolve)=>{
|
|
289
|
+
this.moveSettled = resolve;
|
|
290
|
+
this.timers.relocate = this.config.setTimer(()=>{
|
|
291
|
+
this.timers.relocate = null;
|
|
292
|
+
const next = step();
|
|
293
|
+
if (void 0 === next) return void this.settleMove();
|
|
294
|
+
this.timers.relocate = this.config.setTimer(()=>{
|
|
295
|
+
this.timers.relocate = null;
|
|
296
|
+
this.update({
|
|
297
|
+
relocating: null,
|
|
298
|
+
insetAnimated: true
|
|
299
|
+
});
|
|
300
|
+
this.settleMove();
|
|
301
|
+
}, next);
|
|
302
|
+
}, ms);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
305
|
+
settleMove() {
|
|
306
|
+
const settle = this.moveSettled;
|
|
307
|
+
this.moveSettled = null;
|
|
308
|
+
null == settle || settle();
|
|
309
|
+
}
|
|
310
|
+
showSuccess(message, subtitle) {
|
|
311
|
+
if (this.disposedValue || !this.snapshot.mounted) return;
|
|
312
|
+
this.terminal = 'success';
|
|
313
|
+
this.canceling = false;
|
|
314
|
+
this.stopTimer('watchdog');
|
|
315
|
+
this.successUntil = this.config.now() + g9ProgressTimings.successTerminalMs;
|
|
316
|
+
this.update({
|
|
317
|
+
state: 'success',
|
|
318
|
+
minimized: false,
|
|
319
|
+
terminalTitle: message,
|
|
320
|
+
terminalSubtitle: subtitle,
|
|
321
|
+
retryText: null,
|
|
322
|
+
canRetry: false,
|
|
323
|
+
countdownMs: g9ProgressTimings.successTerminalMs
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
showFailure(reason, retryText, retryAction) {
|
|
327
|
+
if (this.disposedValue || !this.snapshot.mounted) return;
|
|
328
|
+
this.terminal = 'error';
|
|
329
|
+
this.failureAcknowledged = false;
|
|
330
|
+
this.canceling = false;
|
|
331
|
+
this.stopTimer('watchdog');
|
|
332
|
+
this.retryAction = retryAction;
|
|
333
|
+
this.update({
|
|
334
|
+
state: 'error',
|
|
335
|
+
minimized: false,
|
|
336
|
+
terminalTitle: reason,
|
|
337
|
+
terminalSubtitle: null,
|
|
338
|
+
retryText,
|
|
339
|
+
canRetry: null !== retryAction,
|
|
340
|
+
countdownMs: 0
|
|
341
|
+
});
|
|
342
|
+
}
|
|
343
|
+
acknowledgeFailure() {
|
|
344
|
+
if ('error' !== this.terminal || this.failureAcknowledged) return;
|
|
345
|
+
this.failureAcknowledged = true;
|
|
346
|
+
const waiters = this.ackWaiters;
|
|
347
|
+
this.ackWaiters = [];
|
|
348
|
+
for (const waiter of waiters)waiter();
|
|
349
|
+
}
|
|
350
|
+
retry() {
|
|
351
|
+
if (this.retryRunning) return this.retryRunning;
|
|
352
|
+
const action = this.retryAction;
|
|
353
|
+
if ('error' !== this.terminal || !action) return Promise.resolve();
|
|
354
|
+
const contextText = this.snapshot.contextText;
|
|
355
|
+
const waiters = this.ackWaiters;
|
|
356
|
+
this.ackWaiters = [];
|
|
357
|
+
this.resetRunning(contextText);
|
|
358
|
+
const run = (async ()=>{
|
|
359
|
+
try {
|
|
360
|
+
await action();
|
|
361
|
+
} catch (error) {
|
|
362
|
+
this.safe(()=>this.config.onError(error));
|
|
363
|
+
} finally{
|
|
364
|
+
this.retryRunning = null;
|
|
365
|
+
}
|
|
366
|
+
})();
|
|
367
|
+
this.retryRunning = run;
|
|
368
|
+
for (const waiter of waiters)waiter();
|
|
369
|
+
return run;
|
|
370
|
+
}
|
|
371
|
+
dispose() {
|
|
372
|
+
if (this.disposedValue) return;
|
|
373
|
+
this.disposedValue = true;
|
|
374
|
+
for (const which of [
|
|
375
|
+
'watchdog',
|
|
376
|
+
'report',
|
|
377
|
+
'wait',
|
|
378
|
+
'leave',
|
|
379
|
+
'relocate'
|
|
380
|
+
])this.stopTimer(which);
|
|
381
|
+
this.settleMove();
|
|
382
|
+
const waiters = this.ackWaiters;
|
|
383
|
+
this.ackWaiters = [];
|
|
384
|
+
this.leases = [];
|
|
385
|
+
for (const waiter of waiters)waiter();
|
|
386
|
+
this.update({
|
|
387
|
+
mounted: false,
|
|
388
|
+
leaving: false,
|
|
389
|
+
relocating: null
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
get disposed() {
|
|
393
|
+
return this.disposedValue;
|
|
394
|
+
}
|
|
395
|
+
safe(run) {
|
|
396
|
+
try {
|
|
397
|
+
run();
|
|
398
|
+
} catch (error) {
|
|
399
|
+
try {
|
|
400
|
+
this.config.onError(error);
|
|
401
|
+
} catch {}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
constructor(config, placement, followsProvider = false){
|
|
405
|
+
_define_property(this, "config", void 0);
|
|
406
|
+
_define_property(this, "leases", void 0);
|
|
407
|
+
_define_property(this, "sequence", void 0);
|
|
408
|
+
_define_property(this, "snapshot", void 0);
|
|
409
|
+
_define_property(this, "listeners", void 0);
|
|
410
|
+
_define_property(this, "disposedValue", void 0);
|
|
411
|
+
_define_property(this, "canceling", void 0);
|
|
412
|
+
_define_property(this, "terminal", void 0);
|
|
413
|
+
_define_property(this, "failureAcknowledged", void 0);
|
|
414
|
+
_define_property(this, "successUntil", void 0);
|
|
415
|
+
_define_property(this, "ackWaiters", void 0);
|
|
416
|
+
_define_property(this, "retryRunning", void 0);
|
|
417
|
+
_define_property(this, "retryAction", void 0);
|
|
418
|
+
_define_property(this, "timers", void 0);
|
|
419
|
+
_define_property(this, "moveSettled", void 0);
|
|
420
|
+
_define_property(this, "followsProvider", void 0);
|
|
421
|
+
_define_property(this, "pendingReport", void 0);
|
|
422
|
+
_define_property(this, "lastReportAt", void 0);
|
|
423
|
+
_define_property(this, "subscribe", void 0);
|
|
424
|
+
_define_property(this, "getSnapshot", void 0);
|
|
425
|
+
this.config = config;
|
|
426
|
+
this.leases = [];
|
|
427
|
+
this.sequence = 0;
|
|
428
|
+
this.listeners = new Set();
|
|
429
|
+
this.disposedValue = false;
|
|
430
|
+
this.canceling = false;
|
|
431
|
+
this.terminal = 'none';
|
|
432
|
+
this.failureAcknowledged = false;
|
|
433
|
+
this.successUntil = 0;
|
|
434
|
+
this.ackWaiters = [];
|
|
435
|
+
this.retryRunning = null;
|
|
436
|
+
this.retryAction = null;
|
|
437
|
+
this.timers = {
|
|
438
|
+
watchdog: null,
|
|
439
|
+
report: null,
|
|
440
|
+
wait: null,
|
|
441
|
+
leave: null,
|
|
442
|
+
relocate: null
|
|
443
|
+
};
|
|
444
|
+
this.moveSettled = null;
|
|
445
|
+
this.pendingReport = null;
|
|
446
|
+
this.lastReportAt = -1 / 0;
|
|
447
|
+
this.subscribe = (listener)=>{
|
|
448
|
+
this.listeners.add(listener);
|
|
449
|
+
return ()=>this.listeners.delete(listener);
|
|
450
|
+
};
|
|
451
|
+
this.getSnapshot = ()=>this.snapshot;
|
|
452
|
+
const start = g9ProgressOverlayPlacement.normalize('string' == typeof placement ? {
|
|
453
|
+
position: placement
|
|
454
|
+
} : placement);
|
|
455
|
+
this.followsProvider = followsProvider;
|
|
456
|
+
this.snapshot = {
|
|
457
|
+
mounted: false,
|
|
458
|
+
leaving: false,
|
|
459
|
+
state: 'running',
|
|
460
|
+
minimized: false,
|
|
461
|
+
position: start.position,
|
|
462
|
+
offset: start.offset,
|
|
463
|
+
relocating: null,
|
|
464
|
+
contextText: '',
|
|
465
|
+
ratio: null,
|
|
466
|
+
stage: null,
|
|
467
|
+
detail: null,
|
|
468
|
+
queued: 0,
|
|
469
|
+
terminalTitle: null,
|
|
470
|
+
terminalSubtitle: null,
|
|
471
|
+
retryText: null,
|
|
472
|
+
canRetry: false,
|
|
473
|
+
countdownMs: 0,
|
|
474
|
+
insetVersion: 0,
|
|
475
|
+
insetAnimated: true
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
}
|
|
479
|
+
export { G9ProgressSession, g9ProgressOverlayPlacement, g9ProgressQueuedCount, g9ProgressReport, g9ProgressTimings };
|
|
480
|
+
|
|
481
|
+
//# sourceMappingURL=model.jsx.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model.jsx","sources":["../src/model.ts"],"sourcesContent":["/** One progress update (MAUI `G9ProgressReport`): `ratio` 0..1, or `null` for indeterminate. */\nexport interface G9ProgressReport {\n readonly ratio: number | null;\n /** Already-localized stage caption (shown as the context line). */\n readonly stage?: string | null;\n /** Optional secondary line (item, counter, endpoint); replaces the percent caption. */\n readonly detail?: string | null;\n}\n\n/** Report factories and derived values (MAUI `G9ProgressReport.At` / `.Indeterminate` / `ClampedRatio` / `IsIndeterminate`). */\nexport const g9ProgressReport = Object.freeze({\n at: (ratio: number, stage?: string | null, detail?: string | null): G9ProgressReport => ({\n ratio,\n stage: stage ?? null,\n detail: detail ?? null,\n }),\n indeterminate: (stage?: string | null, detail?: string | null): G9ProgressReport => ({\n ratio: null,\n stage: stage ?? null,\n detail: detail ?? null,\n }),\n clampedRatio: (report: G9ProgressReport): number | null =>\n report.ratio == null || Number.isNaN(report.ratio) ? null : Math.min(Math.max(report.ratio, 0), 1),\n isIndeterminate: (report: G9ProgressReport): boolean => report.ratio == null || Number.isNaN(report.ratio),\n});\n\n/** The overlay's state machine (MAUI `G9ProgressOverlayState`); minimized is an orthogonal flag. */\nexport type G9ProgressOverlayState = 'running' | 'canceling' | 'success' | 'error';\n/** Where the overlay is anchored (MAUI `G9ProgressOverlayPosition`). */\nexport type G9ProgressOverlayPosition = 'bottom' | 'top';\n\n/**\n * Where the overlay sits (MAUI 1.3.0 `G9ProgressOverlayPlacement`): the edge it anchors to, plus how far in from that\n * edge's safe-area inset. Returned by the service's `placementProvider`.\n */\nexport interface G9ProgressOverlayPlacement {\n readonly position: G9ProgressOverlayPosition;\n /**\n * Extra distance (px) from the anchored edge, on top of the inset and the overlay's own 14 px gap: below the top\n * inset for `'top'`, above the bottom inset for `'bottom'`. Use it to clear the host's own chrome (a search or\n * site-selector bar the overlay must not cover). Negative and non-finite values count as 0. Default 0.\n */\n readonly offset?: number;\n}\n\nconst defaultPlacement: Required<G9ProgressOverlayPlacement> = Object.freeze({ position: 'bottom', offset: 0 });\n\n/** Placement values (MAUI `G9ProgressOverlayPlacement.Default` and the record's value equality). */\nexport const g9ProgressOverlayPlacement = Object.freeze({\n /** Bottom edge, no extra offset (MAUI `G9ProgressOverlayPlacement.Default`). */\n default: defaultPlacement,\n /** The placement with `offset` made a non-negative number; `null`/`undefined` → the default. */\n normalize(placement: G9ProgressOverlayPlacement | null | undefined): Required<G9ProgressOverlayPlacement> {\n if (!placement) return defaultPlacement;\n const offset = Number(placement.offset ?? 0);\n return {\n position: placement.position === 'top' ? 'top' : 'bottom',\n offset: Number.isFinite(offset) ? Math.max(0, offset) : 0,\n };\n },\n /** Same edge and same (normalized) offset. */\n equals(a: G9ProgressOverlayPlacement | null | undefined, b: G9ProgressOverlayPlacement | null | undefined): boolean {\n const x = g9ProgressOverlayPlacement.normalize(a);\n const y = g9ProgressOverlayPlacement.normalize(b);\n return x.position === y.position && x.offset === y.offset;\n },\n});\n\n/** Queued operations behind the running one (MAUI `G9ProgressQueuedCount`). */\nexport const g9ProgressQueuedCount = Object.freeze({\n value: (count: number): number => (Number.isFinite(count) ? Math.max(0, Math.trunc(count)) : 0),\n hasQueue: (count: number): boolean => g9ProgressQueuedCount.value(count) > 0,\n});\n\n/** Timings fixed by the overlay (MAUI session constants; deliberately not options). */\nexport const g9ProgressTimings = Object.freeze({\n successTerminalMs: 2200,\n cancelWatchdogMs: 5000,\n reportMinIntervalMs: 100,\n appearMs: 260,\n disappearMs: 220,\n insetGlideMs: 220,\n});\n\n/** What the view renders. */\nexport interface G9ProgressSnapshot {\n readonly mounted: boolean;\n /** Leaving: the disappear motion runs, then `mounted` turns false. */\n readonly leaving: boolean;\n readonly state: G9ProgressOverlayState;\n readonly minimized: boolean;\n readonly position: G9ProgressOverlayPosition;\n /** Extra distance from the anchored edge (`G9ProgressOverlayPlacement.offset`, ≥ 0). */\n readonly offset: number;\n /**\n * An edge change in progress (`moveTo`): `'out'` fades out at the old edge, `'in'` is the frame at the new edge before\n * it fades in; `null` otherwise.\n */\n readonly relocating: 'out' | 'in' | null;\n readonly contextText: string;\n /** `null` until a determinate report arrives. */\n readonly ratio: number | null;\n readonly stage: string | null;\n readonly detail: string | null;\n readonly queued: number;\n /** Terminal texts. */\n readonly terminalTitle: string | null;\n readonly terminalSubtitle: string | null;\n readonly retryText: string | null;\n readonly canRetry: boolean;\n /** Success dwell countdown, ms (0 when none). */\n readonly countdownMs: number;\n /** Bumps when the bottom inset should be re-read; `insetAnimated` says whether to glide. */\n readonly insetVersion: number;\n readonly insetAnimated: boolean;\n}\n\n/** Injected dependencies of {@link G9ProgressSession}. */\nexport interface G9ProgressSessionConfig {\n setTimer(callback: () => void, ms: number): unknown;\n clearTimer(handle: unknown): void;\n now(): number;\n /** Broadcast to the app's cancel listeners (MAUI `CancelRequested`). */\n onCancelRequested(): void;\n /** The neutral \"cancelled\" toast after a cancelled run closes (never the error terminal). */\n onCancelled(): void;\n /** The watchdog notice when a step cannot be interrupted at once. */\n onCancelSlow(): void;\n /** A retry action failed or a callback threw: reported, never thrown into the UI loop. */\n onError(error: unknown): void;\n}\n\ninterface Lease {\n readonly id: number;\n readonly contextText: string;\n}\n\n/** A lease on the shared overlay (MAUI `G9ProgressOverlayHandle`); dispose settles once the overlay let go. */\nexport interface G9ProgressOverlayHandle {\n /** Releases the lease; the last one waits for the terminal state to be seen before the overlay closes. */\n dispose(): Promise<void>;\n readonly disposed: boolean;\n}\n\n/**\n * The shared overlay session (MAUI `G9ProgressOverlaySession`): leases keep one visual alive (the oldest is the\n * running operation, the rest are queued), reports are coalesced to ≤ 10 Hz, cancel is a broadcast and never an error,\n * a failure waits for the user (retry or close), a success dwells 2.2 s, and the overlay closes when the last lease is\n * released after its terminal state was seen. Timers are injected so the model is tested without a clock.\n */\nexport class G9ProgressSession {\n private leases: Lease[] = [];\n private sequence = 0;\n private snapshot: G9ProgressSnapshot;\n private readonly listeners = new Set<() => void>();\n private disposedValue = false;\n private canceling = false;\n private terminal: 'none' | 'success' | 'error' = 'none';\n private failureAcknowledged = false;\n private successUntil = 0;\n private ackWaiters: Array<() => void> = [];\n private retryRunning: Promise<void> | null = null;\n private retryAction: (() => Promise<void> | void) | null = null;\n private readonly timers: Record<'watchdog' | 'report' | 'wait' | 'leave' | 'relocate', unknown> = {\n watchdog: null,\n report: null,\n wait: null,\n leave: null,\n relocate: null,\n };\n private moveSettled: (() => void) | null = null;\n /** Whether the overlay follows the host's placement provider (shown without an explicit position, MAUI 1.3.0). */\n readonly followsProvider: boolean;\n private pendingReport: G9ProgressReport | null = null;\n private lastReportAt = Number.NEGATIVE_INFINITY;\n\n /**\n * @param placement - an edge (MAUI's explicit position) or a placement (edge + offset).\n * @param followsProvider - `true` when the placement came from the host's provider, so `moveTo` may move it later.\n */\n constructor(\n private readonly config: G9ProgressSessionConfig,\n placement: G9ProgressOverlayPosition | G9ProgressOverlayPlacement,\n followsProvider = false,\n ) {\n const start = g9ProgressOverlayPlacement.normalize(\n typeof placement === 'string' ? { position: placement } : placement,\n );\n this.followsProvider = followsProvider;\n this.snapshot = {\n mounted: false,\n leaving: false,\n state: 'running',\n minimized: false,\n position: start.position,\n offset: start.offset,\n relocating: null,\n contextText: '',\n ratio: null,\n stage: null,\n detail: null,\n queued: 0,\n terminalTitle: null,\n terminalSubtitle: null,\n retryText: null,\n canRetry: false,\n countdownMs: 0,\n insetVersion: 0,\n insetAnimated: true,\n };\n }\n\n // ── observation ──\n subscribe = (listener: () => void): (() => void) => {\n this.listeners.add(listener);\n return () => this.listeners.delete(listener);\n };\n\n getSnapshot = (): G9ProgressSnapshot => this.snapshot;\n\n get active(): boolean {\n return !this.disposedValue && this.snapshot.mounted;\n }\n\n get leaseCount(): number {\n return this.leases.length;\n }\n\n private update(patch: Partial<G9ProgressSnapshot>): void {\n this.snapshot = { ...this.snapshot, ...patch };\n for (const listener of Array.from(this.listeners)) listener();\n }\n\n private resetRunning(contextText: string): void {\n this.canceling = false;\n this.terminal = 'none';\n this.failureAcknowledged = false;\n this.retryAction = null;\n this.pendingReport = null;\n this.stopTimer('watchdog');\n this.update({\n state: 'running',\n minimized: false,\n contextText,\n ratio: null,\n stage: null,\n detail: null,\n terminalTitle: null,\n terminalSubtitle: null,\n retryText: null,\n canRetry: false,\n countdownMs: 0,\n leaving: false,\n });\n }\n\n private stopTimer(which: 'watchdog' | 'report' | 'wait' | 'leave' | 'relocate'): void {\n const handle = this.timers[which];\n if (handle !== null) this.config.clearTimer(handle);\n this.timers[which] = null;\n }\n\n // ── leases ──\n /** Adds a lease (MAUI `AddLease`): the first mounts the view; one arriving on a terminal overlay resets it. */\n addLease(contextText: string): G9ProgressOverlayHandle {\n const lease: Lease = { id: ++this.sequence, contextText: contextText ?? '' };\n if (this.disposedValue) return { dispose: () => Promise.resolve(), disposed: true };\n const wasEmpty = this.leases.length === 0;\n this.leases.push(lease);\n if (this.canceling) {\n this.canceling = false;\n this.stopTimer('watchdog');\n }\n if (wasEmpty) {\n const acks = this.ackWaiters;\n this.ackWaiters = [];\n this.resetRunning(lease.contextText);\n if (!this.snapshot.mounted || this.snapshot.leaving) {\n this.stopTimer('leave');\n this.update({ mounted: true, leaving: false });\n }\n for (const ack of acks) ack();\n }\n let disposed = false;\n const handle: G9ProgressOverlayHandle = {\n dispose: () => {\n if (disposed) return Promise.resolve();\n disposed = true;\n return this.release(lease);\n },\n get disposed() {\n return disposed;\n },\n };\n return handle;\n }\n\n private release(lease: Lease): Promise<void> {\n const index = this.leases.indexOf(lease);\n if (index < 0) return Promise.resolve();\n this.leases.splice(index, 1);\n if (this.leases.length > 0) {\n if (index === 0) this.resetRunning((this.leases[0] as Lease).contextText);\n return Promise.resolve();\n }\n return this.closeWhenSeen();\n }\n\n /** Waits for the terminal state to be seen, then tears down — unless a new lease took the overlay meanwhile. */\n private closeWhenSeen(): Promise<void> {\n return new Promise<void>((resolve) => {\n const step = () => {\n if (this.disposedValue) return resolve();\n if (this.leases.length > 0) return resolve();\n if (this.retryRunning) {\n void this.retryRunning.then(step, step);\n return;\n }\n if (this.terminal === 'error' && !this.failureAcknowledged) {\n this.ackWaiters.push(step);\n return;\n }\n const remaining = this.terminal === 'success' ? this.successUntil - this.config.now() : 0;\n if (remaining > 0) {\n this.update({ countdownMs: remaining });\n this.timers.wait = this.config.setTimer(() => {\n this.timers.wait = null;\n // The dwell has been seen (counted on the timer, so a paused clock cannot extend it).\n this.successUntil = Number.NEGATIVE_INFINITY;\n step();\n }, remaining);\n return;\n }\n this.tearDown();\n resolve();\n };\n step();\n });\n }\n\n private tearDown(): void {\n const wasCanceling = this.canceling;\n this.canceling = false;\n this.stopTimer('watchdog');\n this.stopTimer('report');\n this.stopTimer('relocate');\n this.settleMove();\n this.pendingReport = null;\n this.update({ leaving: true, minimized: false, relocating: null });\n this.timers.leave = this.config.setTimer(() => {\n this.timers.leave = null;\n if (this.leases.length === 0) this.update({ mounted: false, leaving: false });\n }, g9ProgressTimings.disappearMs);\n if (wasCanceling) this.safe(() => this.config.onCancelled());\n }\n\n // ── progress in ──\n /** Coalesced to ≤ 10 Hz (MAUI `ReportMinIntervalMs`); ignored when canceling, terminal or indeterminate. */\n report(report: G9ProgressReport): void {\n if (this.disposedValue || !this.snapshot.mounted) return;\n this.pendingReport = report;\n if (this.timers.report !== null) return;\n const since = this.config.now() - this.lastReportAt;\n const delay = since >= g9ProgressTimings.reportMinIntervalMs ? 0 : g9ProgressTimings.reportMinIntervalMs - since;\n if (delay <= 0) {\n this.flushReport();\n return;\n }\n this.timers.report = this.config.setTimer(() => {\n this.timers.report = null;\n this.flushReport();\n }, delay);\n }\n\n private flushReport(): void {\n const report = this.pendingReport;\n this.pendingReport = null;\n this.lastReportAt = this.config.now();\n if (!report || this.snapshot.state !== 'running' || g9ProgressReport.isIndeterminate(report)) return;\n const stage = report.stage?.trim() ? report.stage.trim() : this.snapshot.stage;\n this.update({\n ratio: g9ProgressReport.clampedRatio(report),\n stage,\n detail: report.detail?.trim() ? report.detail.trim() : null,\n });\n }\n\n /** The \"+N waiting\" badge (MAUI `ReportQueued`). */\n reportQueued(count: number): void {\n if (this.disposedValue || !this.snapshot.mounted) return;\n this.update({ queued: g9ProgressQueuedCount.value(count) });\n }\n\n // ── user actions ──\n /** The cancel tap: instant Canceling state, a broadcast, and the 5 s watchdog notice. */\n cancel(): void {\n if (this.disposedValue || this.snapshot.state !== 'running' || !this.snapshot.mounted) return;\n this.canceling = true;\n this.update({ state: 'canceling', minimized: false, queued: 0 });\n this.safe(() => this.config.onCancelRequested());\n this.stopTimer('watchdog');\n this.timers.watchdog = this.config.setTimer(() => {\n this.timers.watchdog = null;\n if (this.canceling && !this.disposedValue) this.safe(() => this.config.onCancelSlow());\n }, g9ProgressTimings.cancelWatchdogMs);\n }\n\n /** Minimize to the bubble (running only) or restore. A terminal state always forces the full card. */\n setMinimized(minimized: boolean): void {\n if (this.disposedValue || !this.snapshot.mounted) return;\n if (minimized && this.snapshot.state !== 'running') return;\n if (this.snapshot.minimized !== minimized) this.update({ minimized });\n }\n\n /** Re-anchor after the page's bottom inset changed (MAUI `RefreshBottomInsetAsync`). */\n refreshBottomInset(animate = true): void {\n if (this.disposedValue || !this.snapshot.mounted) return;\n this.update({ insetVersion: this.snapshot.insetVersion + 1, insetAnimated: animate });\n }\n\n /**\n * Moves a mounted overlay to `placement` (MAUI 1.3.0 session `RefreshPlacementAsync`). The same edge with another\n * offset glides like an inset change (220 ms; a jump when `animate` is false). An edge change cannot glide (the anchor\n * flips between the layer's top and bottom, and a translation across the screen would sweep the card over everything):\n * it fades out at the old edge and in at the new one with the disappear and appear motions, or jumps when `animate` is\n * false. Nothing moves while minimized (the bubble stays where the user dragged it), unmounted or leaving, or when the\n * placement is unchanged. A newer move supersedes a running one; a teardown cancels it. Resolves when the overlay\n * stands at its spot, or when the move was superseded or cancelled.\n */\n moveTo(placement: G9ProgressOverlayPlacement, animate = true): Promise<void> {\n const s = this.snapshot;\n if (this.disposedValue || !s.mounted || s.leaving || s.minimized) return Promise.resolve();\n const target = g9ProgressOverlayPlacement.normalize(placement);\n if (s.relocating === null && g9ProgressOverlayPlacement.equals(target, s)) return Promise.resolve();\n this.stopTimer('relocate');\n this.settleMove();\n if (target.position === s.position || !animate) {\n // Same edge: carry the difference and glide. Not animated: take the new spot at once.\n this.update({ position: target.position, offset: target.offset, insetAnimated: animate, relocating: null });\n if (!animate) return Promise.resolve();\n return this.afterMove(g9ProgressTimings.insetGlideMs, () => undefined);\n }\n if (s.relocating !== 'out') this.update({ relocating: 'out' });\n return this.afterMove(g9ProgressTimings.disappearMs, () => {\n // At the new edge, still hidden, without a glide of the anchor; the next frame fades it in.\n this.update({ position: target.position, offset: target.offset, insetAnimated: false, relocating: 'in' });\n return 16;\n });\n }\n\n /** Runs `step` after `ms`; a returned number schedules the final step (shown again) that much later. */\n private afterMove(ms: number, step: () => number | undefined): Promise<void> {\n return new Promise<void>((resolve) => {\n this.moveSettled = resolve;\n this.timers.relocate = this.config.setTimer(() => {\n this.timers.relocate = null;\n const next = step();\n if (next === undefined) {\n this.settleMove();\n return;\n }\n this.timers.relocate = this.config.setTimer(() => {\n this.timers.relocate = null;\n this.update({ relocating: null, insetAnimated: true });\n this.settleMove();\n }, next);\n }, ms);\n });\n }\n\n private settleMove(): void {\n const settle = this.moveSettled;\n this.moveSettled = null;\n settle?.();\n }\n\n // ── terminal states ──\n showSuccess(message: string | null, subtitle: string | null): void {\n if (this.disposedValue || !this.snapshot.mounted) return;\n this.terminal = 'success';\n this.canceling = false;\n this.stopTimer('watchdog');\n this.successUntil = this.config.now() + g9ProgressTimings.successTerminalMs;\n this.update({\n state: 'success',\n minimized: false,\n terminalTitle: message,\n terminalSubtitle: subtitle,\n retryText: null,\n canRetry: false,\n countdownMs: g9ProgressTimings.successTerminalMs,\n });\n }\n\n showFailure(reason: string | null, retryText: string | null, retryAction: (() => Promise<void> | void) | null): void {\n if (this.disposedValue || !this.snapshot.mounted) return;\n this.terminal = 'error';\n this.failureAcknowledged = false;\n this.canceling = false;\n this.stopTimer('watchdog');\n this.retryAction = retryAction;\n this.update({\n state: 'error',\n minimized: false,\n terminalTitle: reason,\n terminalSubtitle: null,\n retryText,\n canRetry: retryAction !== null,\n countdownMs: 0,\n });\n }\n\n /** The close tap on a failure: lets the last lease's dispose finish. */\n acknowledgeFailure(): void {\n if (this.terminal !== 'error' || this.failureAcknowledged) return;\n this.failureAcknowledged = true;\n const waiters = this.ackWaiters;\n this.ackWaiters = [];\n for (const waiter of waiters) waiter();\n }\n\n /** The retry tap: resets to running and runs the retry once (a second tap while it runs joins it). */\n retry(): Promise<void> {\n if (this.retryRunning) return this.retryRunning;\n const action = this.retryAction;\n if (this.terminal !== 'error' || !action) return Promise.resolve();\n const contextText = this.snapshot.contextText;\n const waiters = this.ackWaiters;\n this.ackWaiters = [];\n this.resetRunning(contextText);\n const run = (async () => {\n try {\n await action();\n } catch (error) {\n this.safe(() => this.config.onError(error));\n } finally {\n this.retryRunning = null;\n }\n })();\n this.retryRunning = run;\n for (const waiter of waiters) waiter();\n return run;\n }\n\n /** The host went away: every pending wait settles, nothing runs afterwards. */\n dispose(): void {\n if (this.disposedValue) return;\n this.disposedValue = true;\n for (const which of ['watchdog', 'report', 'wait', 'leave', 'relocate'] as const) this.stopTimer(which);\n this.settleMove();\n const waiters = this.ackWaiters;\n this.ackWaiters = [];\n this.leases = [];\n for (const waiter of waiters) waiter();\n this.update({ mounted: false, leaving: false, relocating: null });\n }\n\n get disposed(): boolean {\n return this.disposedValue;\n }\n\n /** App callbacks never take the overlay down (MAUI: every handler is exception-guarded). */\n private safe(run: () => void): void {\n try {\n run();\n } catch (error) {\n try {\n this.config.onError(error);\n } catch {\n // A failing error reporter must not take the overlay down either.\n }\n }\n }\n}\n"],"names":["g9ProgressReport","Object","ratio","stage","detail","report","Number","Math","defaultPlacement","g9ProgressOverlayPlacement","placement","_placement_offset","offset","a","b","x","y","g9ProgressQueuedCount","count","g9ProgressTimings","G9ProgressSession","patch","listener","Array","contextText","which","handle","lease","Promise","wasEmpty","acks","ack","disposed","index","resolve","step","remaining","wasCanceling","since","delay","_report_stage","_report_detail","minimized","animate","s","target","undefined","ms","next","settle","message","subtitle","reason","retryText","retryAction","waiters","waiter","action","run","error","config","followsProvider","Set","start"],"mappings":"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"}
|