@mintplayer/ng-spark 22.31.0 → 22.33.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 +101 -1
- package/fesm2022/mintplayer-ng-spark-attribute-description.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-account.mjs +18 -18
- package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs +16 -8
- package/fesm2022/mintplayer-ng-spark-auth-auth-bar.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-auth-confirm-email.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-core.mjs +6 -6
- package/fesm2022/mintplayer-ng-spark-auth-external-login.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-forgot-password.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-login.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-pipes.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-register.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-reset-password.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-sign-in.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-auth-two-factor.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-client-operations.mjs +24 -24
- package/fesm2022/mintplayer-ng-spark-column-filter.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-contributions.mjs +9 -9
- package/fesm2022/mintplayer-ng-spark-grid.mjs +220 -49
- package/fesm2022/mintplayer-ng-spark-grid.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-history.mjs +9 -9
- package/fesm2022/mintplayer-ng-spark-icon.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-identity-provider-connected-applications.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-identity-provider-core.mjs +9 -9
- package/fesm2022/mintplayer-ng-spark-identity-provider-developers.mjs +6 -6
- package/fesm2022/mintplayer-ng-spark-identity-provider-management.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-models.mjs +44 -1
- package/fesm2022/mintplayer-ng-spark-models.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-moderation.mjs +21 -21
- package/fesm2022/mintplayer-ng-spark-notifications.mjs +687 -0
- package/fesm2022/mintplayer-ng-spark-notifications.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs +179 -0
- package/fesm2022/mintplayer-ng-spark-organizations-accept.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-organizations.mjs +202 -0
- package/fesm2022/mintplayer-ng-spark-organizations.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-pipes.mjs +125 -85
- package/fesm2022/mintplayer-ng-spark-pipes.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-create.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs +90 -26
- package/fesm2022/mintplayer-ng-spark-po-detail.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs +84 -12
- package/fesm2022/mintplayer-ng-spark-po-edit.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-po-form.mjs +9 -9
- package/fesm2022/mintplayer-ng-spark-pwa.mjs +74 -6
- package/fesm2022/mintplayer-ng-spark-pwa.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-query-list.mjs +10 -109
- package/fesm2022/mintplayer-ng-spark-query-list.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-renderers.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-retry-action-modal.mjs +3 -3
- package/fesm2022/mintplayer-ng-spark-score-renderers.mjs +801 -0
- package/fesm2022/mintplayer-ng-spark-score-renderers.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-services.mjs +424 -72
- package/fesm2022/mintplayer-ng-spark-services.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-share-page.mjs +334 -0
- package/fesm2022/mintplayer-ng-spark-share-page.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-share.mjs +10 -0
- package/fesm2022/mintplayer-ng-spark-share.mjs.map +1 -0
- package/fesm2022/mintplayer-ng-spark-shell.mjs +38 -36
- package/fesm2022/mintplayer-ng-spark-shell.mjs.map +1 -1
- package/fesm2022/mintplayer-ng-spark-soft-delete.mjs +9 -9
- package/package.json +25 -1
- package/types/mintplayer-ng-spark-grid.d.ts +77 -26
- package/types/mintplayer-ng-spark-models.d.ts +150 -17
- package/types/mintplayer-ng-spark-notifications.d.ts +188 -0
- package/types/mintplayer-ng-spark-organizations-accept.d.ts +40 -0
- package/types/mintplayer-ng-spark-organizations.d.ts +72 -0
- package/types/mintplayer-ng-spark-pipes.d.ts +10 -0
- package/types/mintplayer-ng-spark-po-detail.d.ts +26 -0
- package/types/mintplayer-ng-spark-po-edit.d.ts +37 -0
- package/types/mintplayer-ng-spark-pwa.d.ts +48 -2
- package/types/mintplayer-ng-spark-query-list.d.ts +8 -23
- package/types/mintplayer-ng-spark-score-renderers.d.ts +340 -0
- package/types/mintplayer-ng-spark-services.d.ts +146 -6
- package/types/mintplayer-ng-spark-share-page.d.ts +67 -0
- package/types/mintplayer-ng-spark-share.d.ts +26 -0
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import * as i0 from "@angular/core";
|
|
2
|
-
import { Injectable, NgZone, PLATFORM_ID, inject, signal } from "@angular/core";
|
|
2
|
+
import { DestroyRef, Injectable, Injector, NgZone, PLATFORM_ID, assertInInjectionContext, effect, inject, signal, untracked } from "@angular/core";
|
|
3
3
|
import { DOCUMENT, isPlatformBrowser } from "@angular/common";
|
|
4
4
|
import { HttpClient, withInterceptors } from "@angular/common/http";
|
|
5
|
-
import { Observable, firstValueFrom } from "rxjs";
|
|
6
|
-
import { SPARK_RETRY_CANCEL, currentLanguage, filterQueryActions } from "@mintplayer/ng-spark/models";
|
|
5
|
+
import { BehaviorSubject, Observable, firstValueFrom, isObservable, of } from "rxjs";
|
|
6
|
+
import { LIVE_CLOSE_MESSAGE_TOO_LARGE, LIVE_CLOSE_REAUTHENTICATE, LIVE_CLOSE_TOO_MANY_SOCKETS, SPARK_RETRY_CANCEL, applyLivePoPatch, applyLiveQueryPatch, currentLanguage, filterQueryActions } from "@mintplayer/ng-spark/models";
|
|
7
7
|
import { SPARK_CONFIG } from "@mintplayer/ng-spark";
|
|
8
8
|
import { SparkClientMethodRegistry, SparkClientOperationDispatcher } from "@mintplayer/ng-spark/client-operations";
|
|
9
9
|
import { DomSanitizer } from "@angular/platform-browser";
|
|
@@ -24,7 +24,7 @@ var RetryActionService = class RetryActionService {
|
|
|
24
24
|
}
|
|
25
25
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
26
26
|
minVersion: "12.0.0",
|
|
27
|
-
version: "22.2.
|
|
27
|
+
version: "22.2.2",
|
|
28
28
|
ngImport: i0,
|
|
29
29
|
type: RetryActionService,
|
|
30
30
|
deps: [],
|
|
@@ -32,7 +32,7 @@ var RetryActionService = class RetryActionService {
|
|
|
32
32
|
});
|
|
33
33
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
34
34
|
minVersion: "12.0.0",
|
|
35
|
-
version: "22.2.
|
|
35
|
+
version: "22.2.2",
|
|
36
36
|
ngImport: i0,
|
|
37
37
|
type: RetryActionService,
|
|
38
38
|
providedIn: "root"
|
|
@@ -40,7 +40,7 @@ var RetryActionService = class RetryActionService {
|
|
|
40
40
|
};
|
|
41
41
|
i0.ɵɵngDeclareClassMetadata({
|
|
42
42
|
minVersion: "12.0.0",
|
|
43
|
-
version: "22.2.
|
|
43
|
+
version: "22.2.2",
|
|
44
44
|
ngImport: i0,
|
|
45
45
|
type: RetryActionService,
|
|
46
46
|
decorators: [{
|
|
@@ -90,13 +90,13 @@ var SparkLanguageService = class SparkLanguageService {
|
|
|
90
90
|
if (!ts) return "";
|
|
91
91
|
return ts[this.currentLang()] ?? ts["en"] ?? Object.values(ts)[0] ?? "";
|
|
92
92
|
}
|
|
93
|
-
t(key) {
|
|
93
|
+
t(key, fallback) {
|
|
94
94
|
const ts = this.translationsMap()[key];
|
|
95
|
-
return this.resolve(ts) || key;
|
|
95
|
+
return this.resolve(ts) || fallback || key;
|
|
96
96
|
}
|
|
97
97
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
98
98
|
minVersion: "12.0.0",
|
|
99
|
-
version: "22.2.
|
|
99
|
+
version: "22.2.2",
|
|
100
100
|
ngImport: i0,
|
|
101
101
|
type: SparkLanguageService,
|
|
102
102
|
deps: [],
|
|
@@ -104,7 +104,7 @@ var SparkLanguageService = class SparkLanguageService {
|
|
|
104
104
|
});
|
|
105
105
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
106
106
|
minVersion: "12.0.0",
|
|
107
|
-
version: "22.2.
|
|
107
|
+
version: "22.2.2",
|
|
108
108
|
ngImport: i0,
|
|
109
109
|
type: SparkLanguageService,
|
|
110
110
|
providedIn: "root"
|
|
@@ -112,7 +112,7 @@ var SparkLanguageService = class SparkLanguageService {
|
|
|
112
112
|
};
|
|
113
113
|
i0.ɵɵngDeclareClassMetadata({
|
|
114
114
|
minVersion: "12.0.0",
|
|
115
|
-
version: "22.2.
|
|
115
|
+
version: "22.2.2",
|
|
116
116
|
ngImport: i0,
|
|
117
117
|
type: SparkLanguageService,
|
|
118
118
|
decorators: [{
|
|
@@ -121,86 +121,392 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
121
121
|
}],
|
|
122
122
|
ctorParameters: () => []
|
|
123
123
|
});
|
|
124
|
-
|
|
124
|
+
const BASE_DELAY_MS = 1e3;
|
|
125
|
+
const MAX_DELAY_MS = 3e4;
|
|
126
|
+
const REAUTH_LOOP_MS = 5e3;
|
|
127
|
+
const OPEN = 1;
|
|
128
|
+
var SparkLiveService = class SparkLiveService {
|
|
125
129
|
config = inject(SPARK_CONFIG, { optional: true });
|
|
126
130
|
baseUrl = this.config?.baseUrl ?? "/spark";
|
|
127
131
|
ngZone = inject(NgZone);
|
|
128
|
-
|
|
132
|
+
entries = /* @__PURE__ */ new Map();
|
|
133
|
+
bySub = /* @__PURE__ */ new Map();
|
|
134
|
+
nextSub = 0;
|
|
135
|
+
socket = null;
|
|
136
|
+
reconnectTimer = null;
|
|
137
|
+
attempt = 0;
|
|
138
|
+
lastReauthAt = 0;
|
|
139
|
+
watchPersistentObject(objectTypeId, id, options) {
|
|
140
|
+
const request = {
|
|
141
|
+
objectTypeId,
|
|
142
|
+
id,
|
|
143
|
+
deleted: options?.deleted ?? null
|
|
144
|
+
};
|
|
145
|
+
return new Observable((subscriber) => {
|
|
146
|
+
const watcher = {
|
|
147
|
+
next: (event) => subscriber.next(event),
|
|
148
|
+
complete: () => subscriber.complete()
|
|
149
|
+
};
|
|
150
|
+
const entry = this.attach("po", request, watcher);
|
|
151
|
+
return () => this.detach(entry, watcher);
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
watchQuery(request) {
|
|
155
|
+
const requests = isObservable(request) ? request : of(request);
|
|
129
156
|
return new Observable((subscriber) => {
|
|
130
|
-
let
|
|
131
|
-
let
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
ws = new WebSocket(url);
|
|
140
|
-
ws.onopen = () => {
|
|
141
|
-
retryCount = 0;
|
|
142
|
-
};
|
|
143
|
-
ws.onmessage = (event) => {
|
|
144
|
-
try {
|
|
145
|
-
const message = JSON.parse(event.data);
|
|
146
|
-
this.ngZone.run(() => subscriber.next(message));
|
|
147
|
-
} catch {}
|
|
148
|
-
};
|
|
149
|
-
ws.onerror = () => {};
|
|
150
|
-
ws.onclose = (event) => {
|
|
151
|
-
if (closed) return;
|
|
152
|
-
if (event.code === 1e3) {
|
|
153
|
-
this.ngZone.run(() => subscriber.complete());
|
|
154
|
-
return;
|
|
155
|
-
}
|
|
156
|
-
if (retryCount < maxRetries) {
|
|
157
|
-
const delay = Math.min(1e3 * Math.pow(2, retryCount), maxDelay);
|
|
158
|
-
retryCount++;
|
|
159
|
-
retryTimeout = setTimeout(() => connect(), delay);
|
|
160
|
-
} else this.ngZone.run(() => subscriber.error(/* @__PURE__ */ new Error("WebSocket connection failed after maximum retries")));
|
|
161
|
-
};
|
|
157
|
+
let entry = null;
|
|
158
|
+
let ended = false;
|
|
159
|
+
const watcher = {
|
|
160
|
+
next: (event) => subscriber.next(event),
|
|
161
|
+
complete: () => {
|
|
162
|
+
ended = true;
|
|
163
|
+
entry = null;
|
|
164
|
+
subscriber.complete();
|
|
165
|
+
}
|
|
162
166
|
};
|
|
163
|
-
|
|
167
|
+
const requestSubscription = requests.subscribe((next) => {
|
|
168
|
+
if (ended) return;
|
|
169
|
+
if (!next) {
|
|
170
|
+
if (entry) this.detach(entry, watcher);
|
|
171
|
+
entry = null;
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const key = keyOf("query", next);
|
|
175
|
+
if (entry?.key === key) return;
|
|
176
|
+
if (entry && entry.watchers.size === 1 && !this.entries.has(key)) {
|
|
177
|
+
this.update(entry, key, next);
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
if (entry) this.detach(entry, watcher);
|
|
181
|
+
entry = this.attach("query", next, watcher);
|
|
182
|
+
});
|
|
164
183
|
return () => {
|
|
165
|
-
|
|
166
|
-
if (
|
|
167
|
-
|
|
184
|
+
requestSubscription.unsubscribe();
|
|
185
|
+
if (entry) this.detach(entry, watcher);
|
|
186
|
+
entry = null;
|
|
168
187
|
};
|
|
169
188
|
});
|
|
170
189
|
}
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
const
|
|
190
|
+
livePersistentObject(type, id, options) {
|
|
191
|
+
if (!options?.injector) assertInInjectionContext(this.livePersistentObject);
|
|
192
|
+
const injector = options?.injector ?? inject(Injector);
|
|
193
|
+
const value = signal(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
|
|
194
|
+
effect((onCleanup) => {
|
|
195
|
+
const objectTypeId = type();
|
|
196
|
+
const objectId = id();
|
|
197
|
+
untracked(() => value.set(null));
|
|
198
|
+
if (!objectTypeId || !objectId) return;
|
|
199
|
+
const subscription = this.watchPersistentObject(objectTypeId, objectId).subscribe((event) => {
|
|
200
|
+
if (event.type === "po") value.set(event.po);
|
|
201
|
+
else if (event.type === "gone") value.set("gone");
|
|
202
|
+
else value.set(null);
|
|
203
|
+
});
|
|
204
|
+
onCleanup(() => subscription.unsubscribe());
|
|
205
|
+
}, { injector });
|
|
206
|
+
return value.asReadonly();
|
|
207
|
+
}
|
|
208
|
+
liveQuery(request, options) {
|
|
209
|
+
if (!options?.injector) assertInInjectionContext(this.liveQuery);
|
|
210
|
+
const injector = options?.injector ?? inject(Injector);
|
|
211
|
+
const value = signal(null, ...ngDevMode ? [{ debugName: "value" }] : /* istanbul ignore next */ []);
|
|
212
|
+
const requests = new BehaviorSubject(null);
|
|
213
|
+
const subscription = this.watchQuery(requests).subscribe((event) => {
|
|
214
|
+
value.set(event.type === "result" ? event.result : null);
|
|
215
|
+
});
|
|
216
|
+
effect(() => {
|
|
217
|
+
const next = request();
|
|
218
|
+
untracked(() => requests.next(next));
|
|
219
|
+
}, { injector });
|
|
220
|
+
injector.get(DestroyRef).onDestroy(() => {
|
|
221
|
+
subscription.unsubscribe();
|
|
222
|
+
requests.complete();
|
|
223
|
+
});
|
|
224
|
+
return value.asReadonly();
|
|
225
|
+
}
|
|
226
|
+
attach(kind, request, watcher) {
|
|
227
|
+
const key = keyOf(kind, request);
|
|
228
|
+
let entry = this.entries.get(key);
|
|
229
|
+
if (entry) {
|
|
230
|
+
entry.watchers.add(watcher);
|
|
231
|
+
if (entry.state) watcher.next(kind === "po" ? {
|
|
232
|
+
type: "po",
|
|
233
|
+
po: entry.state
|
|
234
|
+
} : {
|
|
235
|
+
type: "result",
|
|
236
|
+
result: entry.state
|
|
237
|
+
});
|
|
238
|
+
return entry;
|
|
239
|
+
}
|
|
240
|
+
entry = {
|
|
241
|
+
key,
|
|
242
|
+
sub: `s${++this.nextSub}`,
|
|
243
|
+
kind,
|
|
244
|
+
request: clean(request),
|
|
245
|
+
watchers: /* @__PURE__ */ new Set([watcher]),
|
|
246
|
+
state: null
|
|
247
|
+
};
|
|
248
|
+
this.entries.set(key, entry);
|
|
249
|
+
this.bySub.set(entry.sub, entry);
|
|
250
|
+
if (this.isOpen()) this.sendSubscribe(entry);
|
|
251
|
+
else this.ensureSocket();
|
|
252
|
+
return entry;
|
|
253
|
+
}
|
|
254
|
+
update(entry, key, request) {
|
|
255
|
+
this.entries.delete(entry.key);
|
|
256
|
+
entry.key = key;
|
|
257
|
+
entry.request = clean(request);
|
|
258
|
+
this.entries.set(key, entry);
|
|
259
|
+
if (this.isOpen()) this.send({
|
|
260
|
+
op: "update",
|
|
261
|
+
sub: entry.sub,
|
|
262
|
+
query: entry.request
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
detach(entry, watcher) {
|
|
266
|
+
if (!entry.watchers.delete(watcher)) return;
|
|
267
|
+
if (entry.watchers.size > 0 || this.entries.get(entry.key) !== entry) return;
|
|
268
|
+
this.forget(entry);
|
|
269
|
+
if (this.isOpen()) this.send({
|
|
270
|
+
op: "unsubscribe",
|
|
271
|
+
sub: entry.sub
|
|
272
|
+
});
|
|
273
|
+
this.closeIfIdle();
|
|
274
|
+
}
|
|
275
|
+
forget(entry) {
|
|
276
|
+
if (this.entries.get(entry.key) === entry) this.entries.delete(entry.key);
|
|
277
|
+
this.bySub.delete(entry.sub);
|
|
278
|
+
}
|
|
279
|
+
end(entry, event) {
|
|
280
|
+
this.forget(entry);
|
|
281
|
+
const watchers = [...entry.watchers];
|
|
282
|
+
entry.watchers.clear();
|
|
283
|
+
this.emit(() => {
|
|
284
|
+
for (const watcher of watchers) {
|
|
285
|
+
watcher.next(event);
|
|
286
|
+
watcher.complete();
|
|
287
|
+
}
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
failAll(code, message) {
|
|
291
|
+
const event = {
|
|
292
|
+
type: "error",
|
|
293
|
+
code,
|
|
294
|
+
message
|
|
295
|
+
};
|
|
296
|
+
for (const entry of [...this.entries.values()]) this.end(entry, event);
|
|
297
|
+
this.closeSocket();
|
|
298
|
+
}
|
|
299
|
+
isOpen() {
|
|
300
|
+
return this.socket !== null && this.socket.readyState === OPEN;
|
|
301
|
+
}
|
|
302
|
+
ensureSocket() {
|
|
303
|
+
if (this.socket || this.reconnectTimer) return;
|
|
304
|
+
this.open();
|
|
305
|
+
}
|
|
306
|
+
open() {
|
|
307
|
+
this.ngZone.runOutsideAngular(() => {
|
|
308
|
+
const socket = new WebSocket(this.buildWebSocketUrl());
|
|
309
|
+
this.socket = socket;
|
|
310
|
+
socket.onopen = () => {
|
|
311
|
+
if (this.socket !== socket) return;
|
|
312
|
+
for (const entry of this.entries.values()) this.sendSubscribe(entry);
|
|
313
|
+
};
|
|
314
|
+
socket.onmessage = (event) => {
|
|
315
|
+
if (this.socket !== socket) return;
|
|
316
|
+
this.onFrame(event.data);
|
|
317
|
+
};
|
|
318
|
+
socket.onerror = () => {};
|
|
319
|
+
socket.onclose = (event) => {
|
|
320
|
+
if (this.socket !== socket) return;
|
|
321
|
+
this.socket = null;
|
|
322
|
+
this.onClose(event.code);
|
|
323
|
+
};
|
|
324
|
+
});
|
|
325
|
+
}
|
|
326
|
+
onClose(code) {
|
|
327
|
+
if (this.entries.size === 0) return;
|
|
328
|
+
for (const entry of this.entries.values()) entry.state = null;
|
|
329
|
+
if (code === LIVE_CLOSE_TOO_MANY_SOCKETS) {
|
|
330
|
+
this.failAll("tooManySockets", "Too many live connections are open for this user.");
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
if (code === LIVE_CLOSE_MESSAGE_TOO_LARGE) {
|
|
334
|
+
this.failAll("messageTooLarge", "A live request was too large.");
|
|
335
|
+
return;
|
|
336
|
+
}
|
|
337
|
+
if (code === LIVE_CLOSE_REAUTHENTICATE) {
|
|
338
|
+
const now = Date.now();
|
|
339
|
+
if (this.lastReauthAt && now - this.lastReauthAt < REAUTH_LOOP_MS) {
|
|
340
|
+
this.lastReauthAt = 0;
|
|
341
|
+
this.failAll("unauthenticated", "The live connection was refused: sign in again.");
|
|
342
|
+
return;
|
|
343
|
+
}
|
|
344
|
+
this.lastReauthAt = now;
|
|
345
|
+
this.open();
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
const delay = Math.min(BASE_DELAY_MS * Math.pow(2, this.attempt), MAX_DELAY_MS) * (.5 + Math.random() / 2);
|
|
349
|
+
this.attempt++;
|
|
350
|
+
this.ngZone.runOutsideAngular(() => {
|
|
351
|
+
this.reconnectTimer = setTimeout(() => {
|
|
352
|
+
this.reconnectTimer = null;
|
|
353
|
+
if (this.entries.size > 0) this.open();
|
|
354
|
+
}, delay);
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
closeIfIdle() {
|
|
358
|
+
if (this.entries.size > 0) return;
|
|
359
|
+
Promise.resolve().then(() => {
|
|
360
|
+
if (this.entries.size === 0) this.closeSocket();
|
|
361
|
+
});
|
|
362
|
+
}
|
|
363
|
+
closeSocket() {
|
|
364
|
+
if (this.reconnectTimer) {
|
|
365
|
+
clearTimeout(this.reconnectTimer);
|
|
366
|
+
this.reconnectTimer = null;
|
|
367
|
+
}
|
|
368
|
+
const socket = this.socket;
|
|
369
|
+
this.socket = null;
|
|
370
|
+
this.attempt = 0;
|
|
371
|
+
if (socket && socket.readyState <= OPEN) socket.close(1e3, "No live subscriptions");
|
|
372
|
+
}
|
|
373
|
+
sendSubscribe(entry) {
|
|
374
|
+
this.send(entry.kind === "po" ? {
|
|
375
|
+
op: "subscribe",
|
|
376
|
+
sub: entry.sub,
|
|
377
|
+
po: entry.request
|
|
378
|
+
} : {
|
|
379
|
+
op: "subscribe",
|
|
380
|
+
sub: entry.sub,
|
|
381
|
+
query: entry.request
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
send(op) {
|
|
385
|
+
this.socket?.send(JSON.stringify(op));
|
|
386
|
+
}
|
|
387
|
+
onFrame(data) {
|
|
388
|
+
let frame;
|
|
389
|
+
try {
|
|
390
|
+
frame = JSON.parse(String(data));
|
|
391
|
+
} catch {
|
|
392
|
+
return;
|
|
393
|
+
}
|
|
394
|
+
if (!frame || typeof frame !== "object") return;
|
|
395
|
+
this.attempt = 0;
|
|
396
|
+
if (frame.type === "ping") return;
|
|
397
|
+
if (frame.type === "error" && !frame.sub) {
|
|
398
|
+
console.warn(`[spark] live: ${frame.code}: ${frame.message}`);
|
|
399
|
+
return;
|
|
400
|
+
}
|
|
401
|
+
const entry = this.bySub.get(frame.sub);
|
|
402
|
+
if (!entry) return;
|
|
403
|
+
switch (frame.type) {
|
|
404
|
+
case "po":
|
|
405
|
+
entry.state = frame.po;
|
|
406
|
+
this.broadcast(entry, {
|
|
407
|
+
type: "po",
|
|
408
|
+
po: frame.po
|
|
409
|
+
});
|
|
410
|
+
break;
|
|
411
|
+
case "poPatch":
|
|
412
|
+
if (!entry.state) return;
|
|
413
|
+
entry.state = applyLivePoPatch(entry.state, frame.patch);
|
|
414
|
+
this.broadcast(entry, {
|
|
415
|
+
type: "po",
|
|
416
|
+
po: entry.state
|
|
417
|
+
});
|
|
418
|
+
break;
|
|
419
|
+
case "gone":
|
|
420
|
+
this.end(entry, { type: "gone" });
|
|
421
|
+
this.closeIfIdle();
|
|
422
|
+
break;
|
|
423
|
+
case "result":
|
|
424
|
+
entry.state = frame.result;
|
|
425
|
+
this.broadcast(entry, {
|
|
426
|
+
type: "result",
|
|
427
|
+
result: frame.result
|
|
428
|
+
});
|
|
429
|
+
break;
|
|
430
|
+
case "patch":
|
|
431
|
+
if (!entry.state) return;
|
|
432
|
+
entry.state = applyLiveQueryPatch(entry.state, frame.patch);
|
|
433
|
+
this.broadcast(entry, {
|
|
434
|
+
type: "result",
|
|
435
|
+
result: entry.state
|
|
436
|
+
});
|
|
437
|
+
break;
|
|
438
|
+
case "error":
|
|
439
|
+
this.end(entry, {
|
|
440
|
+
type: "error",
|
|
441
|
+
code: frame.code,
|
|
442
|
+
message: frame.message
|
|
443
|
+
});
|
|
444
|
+
this.closeIfIdle();
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
broadcast(entry, event) {
|
|
448
|
+
const watchers = [...entry.watchers];
|
|
449
|
+
this.emit(() => {
|
|
450
|
+
for (const watcher of watchers) watcher.next(event);
|
|
451
|
+
});
|
|
452
|
+
}
|
|
453
|
+
emit(fn) {
|
|
454
|
+
this.ngZone.run(fn);
|
|
455
|
+
}
|
|
456
|
+
buildWebSocketUrl() {
|
|
457
|
+
const path = `${this.baseUrl}/live`;
|
|
174
458
|
if (this.baseUrl.startsWith("http://")) return path.replace(/^http:\/\//, "ws://");
|
|
175
459
|
if (this.baseUrl.startsWith("https://")) return path.replace(/^https:\/\//, "wss://");
|
|
176
460
|
return `${window.location.protocol === "https:" ? "wss:" : "ws:"}//${window.location.host}${path}`;
|
|
177
461
|
}
|
|
178
462
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
179
463
|
minVersion: "12.0.0",
|
|
180
|
-
version: "22.2.
|
|
464
|
+
version: "22.2.2",
|
|
181
465
|
ngImport: i0,
|
|
182
|
-
type:
|
|
466
|
+
type: SparkLiveService,
|
|
183
467
|
deps: [],
|
|
184
468
|
target: i0.ɵɵFactoryTarget.Injectable
|
|
185
469
|
});
|
|
186
470
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
187
471
|
minVersion: "12.0.0",
|
|
188
|
-
version: "22.2.
|
|
472
|
+
version: "22.2.2",
|
|
189
473
|
ngImport: i0,
|
|
190
|
-
type:
|
|
474
|
+
type: SparkLiveService,
|
|
191
475
|
providedIn: "root"
|
|
192
476
|
});
|
|
193
477
|
};
|
|
194
478
|
i0.ɵɵngDeclareClassMetadata({
|
|
195
479
|
minVersion: "12.0.0",
|
|
196
|
-
version: "22.2.
|
|
480
|
+
version: "22.2.2",
|
|
197
481
|
ngImport: i0,
|
|
198
|
-
type:
|
|
482
|
+
type: SparkLiveService,
|
|
199
483
|
decorators: [{
|
|
200
484
|
type: Injectable,
|
|
201
485
|
args: [{ providedIn: "root" }]
|
|
202
486
|
}]
|
|
203
487
|
});
|
|
488
|
+
function clean(request) {
|
|
489
|
+
return JSON.parse(canonicalJson(request));
|
|
490
|
+
}
|
|
491
|
+
function keyOf(kind, request) {
|
|
492
|
+
return `${kind}:${canonicalJson(request)}`;
|
|
493
|
+
}
|
|
494
|
+
function canonicalJson(value) {
|
|
495
|
+
return JSON.stringify(normalize(value));
|
|
496
|
+
}
|
|
497
|
+
function normalize(value) {
|
|
498
|
+
if (Array.isArray(value)) return value.map(normalize);
|
|
499
|
+
if (value && typeof value === "object") {
|
|
500
|
+
const result = {};
|
|
501
|
+
for (const key of Object.keys(value).sort()) {
|
|
502
|
+
const field = value[key];
|
|
503
|
+
if (field === null || field === void 0) continue;
|
|
504
|
+
result[key] = normalize(field);
|
|
505
|
+
}
|
|
506
|
+
return result;
|
|
507
|
+
}
|
|
508
|
+
return value;
|
|
509
|
+
}
|
|
204
510
|
var SparkService = class SparkService {
|
|
205
511
|
config = inject(SPARK_CONFIG, { optional: true });
|
|
206
512
|
baseUrl = this.config?.baseUrl ?? "/spark";
|
|
@@ -423,7 +729,7 @@ var SparkService = class SparkService {
|
|
|
423
729
|
}
|
|
424
730
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
425
731
|
minVersion: "12.0.0",
|
|
426
|
-
version: "22.2.
|
|
732
|
+
version: "22.2.2",
|
|
427
733
|
ngImport: i0,
|
|
428
734
|
type: SparkService,
|
|
429
735
|
deps: [],
|
|
@@ -431,7 +737,7 @@ var SparkService = class SparkService {
|
|
|
431
737
|
});
|
|
432
738
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
433
739
|
minVersion: "12.0.0",
|
|
434
|
-
version: "22.2.
|
|
740
|
+
version: "22.2.2",
|
|
435
741
|
ngImport: i0,
|
|
436
742
|
type: SparkService,
|
|
437
743
|
providedIn: "root"
|
|
@@ -439,7 +745,7 @@ var SparkService = class SparkService {
|
|
|
439
745
|
};
|
|
440
746
|
i0.ɵɵngDeclareClassMetadata({
|
|
441
747
|
minVersion: "12.0.0",
|
|
442
|
-
version: "22.2.
|
|
748
|
+
version: "22.2.2",
|
|
443
749
|
ngImport: i0,
|
|
444
750
|
type: SparkService,
|
|
445
751
|
decorators: [{
|
|
@@ -449,6 +755,8 @@ i0.ɵɵngDeclareClassMetadata({
|
|
|
449
755
|
});
|
|
450
756
|
const SPARK_BUILT_IN_ICONS = {
|
|
451
757
|
"three-dots-vertical": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-three-dots-vertical\" viewBox=\"0 0 16 16\"><path d=\"M9.5 13a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0m0-5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0\"/></svg>",
|
|
758
|
+
"bell": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-bell\" viewBox=\"0 0 16 16\"><path d=\"M8 16a2 2 0 0 0 2-2H6a2 2 0 0 0 2 2M8 1.918l-.797.161A4 4 0 0 0 4 6c0 .628-.134 2.197-.459 3.742-.16.767-.376 1.566-.663 2.258h10.244c-.287-.692-.502-1.49-.663-2.258C12.134 8.197 12 6.628 12 6a4 4 0 0 0-3.203-3.92zM14.22 12c.223.447.481.801.78 1H1c.299-.199.557-.553.78-1C2.68 10.2 3 6.88 3 6c0-2.42 1.72-4.44 4.005-4.901a1 1 0 1 1 1.99 0A5 5 0 0 1 13 6c0 .88.32 4.2 1.22 6\"/></svg>",
|
|
759
|
+
"share": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-share\" viewBox=\"0 0 16 16\"><path d=\"M13.5 1a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3M11 2.5a2.5 2.5 0 1 1 .603 1.628l-6.718 3.12a2.5 2.5 0 0 1 0 1.504l6.718 3.12a2.5 2.5 0 1 1-.488.876l-6.718-3.12a2.5 2.5 0 1 1 0-3.256l6.718-3.12A2.5 2.5 0 0 1 11 2.5m-8.5 4a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3m11 5.5a1.5 1.5 0 1 0 0 3 1.5 1.5 0 0 0 0-3\"/></svg>",
|
|
452
760
|
"x-circle": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-x-circle\" viewBox=\"0 0 16 16\"><path d=\"M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14m0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16\"/><path d=\"M4.646 4.646a.5.5 0 0 1 .708 0L8 7.293l2.646-2.647a.5.5 0 0 1 .708.708L8.707 8l2.647 2.646a.5.5 0 0 1-.708.708L8 8.707l-2.646 2.647a.5.5 0 0 1-.708-.708L7.293 8 4.646 5.354a.5.5 0 0 1 0-.708\"/></svg>",
|
|
453
761
|
"arrow-left": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-arrow-left\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M15 8a.5.5 0 0 0-.5-.5H2.707l3.147-3.146a.5.5 0 1 0-.708-.708l-4 4a.5.5 0 0 0 0 .708l4 4a.5.5 0 0 0 .708-.708L2.707 8.5H14.5A.5.5 0 0 0 15 8\"/></svg>",
|
|
454
762
|
"pencil": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-pencil\" viewBox=\"0 0 16 16\"><path d=\"M12.146.146a.5.5 0 0 1 .708 0l3 3a.5.5 0 0 1 0 .708l-10 10a.5.5 0 0 1-.168.11l-5 2a.5.5 0 0 1-.65-.65l2-5a.5.5 0 0 1 .11-.168zM11.207 2.5 13.5 4.793 14.793 3.5 12.5 1.207zm1.586 3L10.5 3.207 4 9.707V10h.5a.5.5 0 0 1 .5.5v.5h.5a.5.5 0 0 1 .5.5v.5h.293zm-9.761 5.175-.106.106-1.528 3.821 3.821-1.528.106-.106A.5.5 0 0 1 5 12.5V12h-.5a.5.5 0 0 1-.5-.5V11h-.5a.5.5 0 0 1-.468-.325\"/></svg>",
|
|
@@ -456,7 +764,9 @@ const SPARK_BUILT_IN_ICONS = {
|
|
|
456
764
|
"plus-lg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-plus-lg\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M8 2a.5.5 0 0 1 .5.5v5h5a.5.5 0 0 1 0 1h-5v5a.5.5 0 0 1-1 0v-5h-5a.5.5 0 0 1 0-1h5v-5A.5.5 0 0 1 8 2\"/></svg>",
|
|
457
765
|
"search": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-search\" viewBox=\"0 0 16 16\"><path d=\"M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001q.044.06.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1 1 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0\"/></svg>",
|
|
458
766
|
"trash": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-trash\" viewBox=\"0 0 16 16\"><path d=\"M5.5 5.5A.5.5 0 0 1 6 6v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m2.5 0a.5.5 0 0 1 .5.5v6a.5.5 0 0 1-1 0V6a.5.5 0 0 1 .5-.5m3 .5a.5.5 0 0 0-1 0v6a.5.5 0 0 0 1 0z\"/><path d=\"M14.5 3a1 1 0 0 1-1 1H13v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V4h-.5a1 1 0 0 1-1-1V2a1 1 0 0 1 1-1H6a1 1 0 0 1 1-1h2a1 1 0 0 1 1 1h3.5a1 1 0 0 1 1 1zM4.118 4 4 4.059V13a1 1 0 0 0 1 1h6a1 1 0 0 0 1-1V4.059L11.882 4zM2.5 3h11V2h-11z\"/></svg>",
|
|
459
|
-
"x-lg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z\"/></svg>"
|
|
767
|
+
"x-lg": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-x-lg\" viewBox=\"0 0 16 16\"><path d=\"M2.146 2.854a.5.5 0 1 1 .708-.708L8 7.293l5.146-5.147a.5.5 0 0 1 .708.708L8.707 8l5.147 5.146a.5.5 0 0 1-.708.708L8 8.707l-5.146 5.147a.5.5 0 0 1-.708-.708L7.293 8z\"/></svg>",
|
|
768
|
+
"person": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-person\" viewBox=\"0 0 16 16\"><path d=\"M8 8a3 3 0 1 0 0-6 3 3 0 0 0 0 6m2-3a2 2 0 1 1-4 0 2 2 0 0 1 4 0m4 8c0 1-1 1-1 1H3s-1 0-1-1 1-4 6-4 6 3 6 4m-1-.004c-.001-.246-.154-.986-.832-1.664C11.516 10.68 10.289 10 8 10s-3.516.68-4.168 1.332c-.678.678-.83 1.418-.832 1.664z\"/></svg>",
|
|
769
|
+
"box-arrow-right": "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"16\" height=\"16\" fill=\"currentColor\" class=\"bi bi-box-arrow-right\" viewBox=\"0 0 16 16\"><path fill-rule=\"evenodd\" d=\"M10 12.5a.5.5 0 0 1-.5.5h-8a.5.5 0 0 1-.5-.5v-9a.5.5 0 0 1 .5-.5h8a.5.5 0 0 1 .5.5v2a.5.5 0 0 0 1 0v-2A1.5 1.5 0 0 0 9.5 2h-8A1.5 1.5 0 0 0 0 3.5v9A1.5 1.5 0 0 0 1.5 14h8a1.5 1.5 0 0 0 1.5-1.5v-2a.5.5 0 0 0-1 0z\"/><path fill-rule=\"evenodd\" d=\"M15.854 8.354a.5.5 0 0 0 0-.708l-3-3a.5.5 0 0 0-.708.708L14.293 7.5H5.5a.5.5 0 0 0 0 1h8.793l-2.147 2.146a.5.5 0 0 0 .708.708z\"/></svg>"
|
|
460
770
|
};
|
|
461
771
|
var SparkIconRegistry = class SparkIconRegistry {
|
|
462
772
|
sanitizer = inject(DomSanitizer);
|
|
@@ -475,7 +785,7 @@ var SparkIconRegistry = class SparkIconRegistry {
|
|
|
475
785
|
}
|
|
476
786
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
477
787
|
minVersion: "12.0.0",
|
|
478
|
-
version: "22.2.
|
|
788
|
+
version: "22.2.2",
|
|
479
789
|
ngImport: i0,
|
|
480
790
|
type: SparkIconRegistry,
|
|
481
791
|
deps: [],
|
|
@@ -483,7 +793,7 @@ var SparkIconRegistry = class SparkIconRegistry {
|
|
|
483
793
|
});
|
|
484
794
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
485
795
|
minVersion: "12.0.0",
|
|
486
|
-
version: "22.2.
|
|
796
|
+
version: "22.2.2",
|
|
487
797
|
ngImport: i0,
|
|
488
798
|
type: SparkIconRegistry,
|
|
489
799
|
providedIn: "root"
|
|
@@ -491,7 +801,7 @@ var SparkIconRegistry = class SparkIconRegistry {
|
|
|
491
801
|
};
|
|
492
802
|
i0.ɵɵngDeclareClassMetadata({
|
|
493
803
|
minVersion: "12.0.0",
|
|
494
|
-
version: "22.2.
|
|
804
|
+
version: "22.2.2",
|
|
495
805
|
ngImport: i0,
|
|
496
806
|
type: SparkIconRegistry,
|
|
497
807
|
decorators: [{
|
|
@@ -523,7 +833,7 @@ var SparkQueryActionsService = class SparkQueryActionsService {
|
|
|
523
833
|
}
|
|
524
834
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
525
835
|
minVersion: "12.0.0",
|
|
526
|
-
version: "22.2.
|
|
836
|
+
version: "22.2.2",
|
|
527
837
|
ngImport: i0,
|
|
528
838
|
type: SparkQueryActionsService,
|
|
529
839
|
deps: [],
|
|
@@ -531,7 +841,7 @@ var SparkQueryActionsService = class SparkQueryActionsService {
|
|
|
531
841
|
});
|
|
532
842
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
533
843
|
minVersion: "12.0.0",
|
|
534
|
-
version: "22.2.
|
|
844
|
+
version: "22.2.2",
|
|
535
845
|
ngImport: i0,
|
|
536
846
|
type: SparkQueryActionsService,
|
|
537
847
|
providedIn: "root"
|
|
@@ -539,7 +849,7 @@ var SparkQueryActionsService = class SparkQueryActionsService {
|
|
|
539
849
|
};
|
|
540
850
|
i0.ɵɵngDeclareClassMetadata({
|
|
541
851
|
minVersion: "12.0.0",
|
|
542
|
-
version: "22.2.
|
|
852
|
+
version: "22.2.2",
|
|
543
853
|
ngImport: i0,
|
|
544
854
|
type: SparkQueryActionsService,
|
|
545
855
|
decorators: [{
|
|
@@ -632,7 +942,7 @@ var SparkReturnNavigationService = class SparkReturnNavigationService {
|
|
|
632
942
|
}
|
|
633
943
|
static ɵfac = i0.ɵɵngDeclareFactory({
|
|
634
944
|
minVersion: "12.0.0",
|
|
635
|
-
version: "22.2.
|
|
945
|
+
version: "22.2.2",
|
|
636
946
|
ngImport: i0,
|
|
637
947
|
type: SparkReturnNavigationService,
|
|
638
948
|
deps: [],
|
|
@@ -640,7 +950,7 @@ var SparkReturnNavigationService = class SparkReturnNavigationService {
|
|
|
640
950
|
});
|
|
641
951
|
static ɵprov = i0.ɵɵngDeclareInjectable({
|
|
642
952
|
minVersion: "12.0.0",
|
|
643
|
-
version: "22.2.
|
|
953
|
+
version: "22.2.2",
|
|
644
954
|
ngImport: i0,
|
|
645
955
|
type: SparkReturnNavigationService,
|
|
646
956
|
providedIn: "root"
|
|
@@ -648,7 +958,7 @@ var SparkReturnNavigationService = class SparkReturnNavigationService {
|
|
|
648
958
|
};
|
|
649
959
|
i0.ɵɵngDeclareClassMetadata({
|
|
650
960
|
minVersion: "12.0.0",
|
|
651
|
-
version: "22.2.
|
|
961
|
+
version: "22.2.2",
|
|
652
962
|
ngImport: i0,
|
|
653
963
|
type: SparkReturnNavigationService,
|
|
654
964
|
decorators: [{
|
|
@@ -673,6 +983,48 @@ function sparkDatatableLabels(lang) {
|
|
|
673
983
|
resetColumn: lang.t("common.resetColumn")
|
|
674
984
|
};
|
|
675
985
|
}
|
|
676
|
-
|
|
986
|
+
function sparkRetryAfterSeconds(e) {
|
|
987
|
+
const err = e;
|
|
988
|
+
if (err?.status !== 429) return null;
|
|
989
|
+
const body = err.error;
|
|
990
|
+
const fromBody = typeof body === "object" && body ? body.result?.retryAfterSeconds ?? body.retryAfterSeconds : void 0;
|
|
991
|
+
if (typeof fromBody === "number" && Number.isFinite(fromBody) && fromBody >= 0) return Math.ceil(fromBody);
|
|
992
|
+
const header = err.headers?.get?.("Retry-After");
|
|
993
|
+
if (header && /^\d+$/.test(header.trim())) return Number(header.trim());
|
|
994
|
+
return null;
|
|
995
|
+
}
|
|
996
|
+
function formatSparkWait(seconds, lang) {
|
|
997
|
+
const s = Math.max(0, Math.ceil(seconds));
|
|
998
|
+
const say = (unit, n) => lang.t(`spark.wait.${unit}${n === 1 ? "" : "s"}`, n === 1 ? `1 ${unit}` : `{0} ${unit}s`).replace("{0}", String(n));
|
|
999
|
+
if (s < 60) return lang.t("spark.wait.fewSeconds", "a few seconds");
|
|
1000
|
+
if (s < 3600) return say("minute", Math.ceil(s / 60));
|
|
1001
|
+
if (s < 172800) return say("hour", Math.max(1, Math.round(s / 3600)));
|
|
1002
|
+
return say("day", Math.round(s / 86400));
|
|
1003
|
+
}
|
|
1004
|
+
function describeSparkError(e, lang, fallback) {
|
|
1005
|
+
const body = e?.error;
|
|
1006
|
+
let message = null;
|
|
1007
|
+
if (typeof body === "object" && body) {
|
|
1008
|
+
const first = body.result?.errors?.[0]?.errorMessage;
|
|
1009
|
+
if (typeof first === "string" && first) message = first;
|
|
1010
|
+
else if (first && typeof first === "object") message = lang.resolve(first) || null;
|
|
1011
|
+
if (!message && typeof body.result?.error === "string" && body.result.error) message = body.result.error;
|
|
1012
|
+
if (!message && typeof body.error === "string" && body.error) message = body.error;
|
|
1013
|
+
}
|
|
1014
|
+
message ??= fallback;
|
|
1015
|
+
const wait = sparkRetryAfterSeconds(e);
|
|
1016
|
+
if (wait === null) return message;
|
|
1017
|
+
const tryAgain = lang.t("spark.tryAgainIn", "Try again in {0}.").replace("{0}", formatSparkWait(wait, lang));
|
|
1018
|
+
return `${message.trim()} ${tryAgain}`;
|
|
1019
|
+
}
|
|
1020
|
+
const sparkLanguageInterceptor = (req, next) => {
|
|
1021
|
+
const language = currentLanguage();
|
|
1022
|
+
if (!language) return next(req);
|
|
1023
|
+
return next(req.clone({ setHeaders: { "Accept-Language": language } }));
|
|
1024
|
+
};
|
|
1025
|
+
function withSparkLanguage() {
|
|
1026
|
+
return [withInterceptors([sparkLanguageInterceptor])];
|
|
1027
|
+
}
|
|
1028
|
+
export { RetryActionService, SPARK_RETURN_URL_STATE_KEY, SPARK_TIMEZONE_COOKIE, SPARK_TIMEZONE_HEADER, SparkIconRegistry, SparkLanguageService, SparkLiveService, SparkQueryActionsService, SparkReturnNavigationService, SparkService, canonicalJson, createSparkTimezoneInterceptor, describeSparkError, formatSparkWait, resolveBrowserTimeZone, sparkDatatableLabels, sparkLanguageInterceptor, sparkRetryAfterSeconds, sparkTimezoneInterceptor, withSparkLanguage, withSparkTimezone };
|
|
677
1029
|
|
|
678
1030
|
//# sourceMappingURL=mintplayer-ng-spark-services.mjs.map
|