@securitydept/client 0.3.0-beta.1 → 0.3.0-beta.11

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.
Files changed (59) hide show
  1. package/README.md +6 -0
  2. package/dist/create-i5VyYgN6.mjs +989 -0
  3. package/dist/create-i5VyYgN6.mjs.map +1 -0
  4. package/dist/handle-DwMgqe7R.mjs +638 -0
  5. package/dist/handle-DwMgqe7R.mjs.map +1 -0
  6. package/dist/index-Bo1BtjZH.d.mts +132 -0
  7. package/dist/index-CFAJ969E.d.mts +674 -0
  8. package/dist/index-CbeZ3AfB.d.mts +1680 -0
  9. package/dist/index.d.mts +3 -353
  10. package/dist/index.mjs +1196 -401
  11. package/dist/index.mjs.map +1 -1
  12. package/dist/router-at5bTdJQ.mjs +245 -0
  13. package/dist/router-at5bTdJQ.mjs.map +1 -0
  14. package/dist/rx/index.d.mts +68 -0
  15. package/dist/rx/index.mjs +2 -0
  16. package/dist/rx-DM6Ouv-m.mjs +1119 -0
  17. package/dist/rx-DM6Ouv-m.mjs.map +1 -0
  18. package/dist/server/index.d.mts +20 -0
  19. package/dist/server/index.mjs +29 -0
  20. package/dist/server/index.mjs.map +1 -0
  21. package/dist/test/index.d.mts +101 -0
  22. package/dist/test/index.mjs +270 -0
  23. package/dist/test/index.mjs.map +1 -0
  24. package/dist/uri-string-BPNbIMgv.mjs +300 -0
  25. package/dist/uri-string-BPNbIMgv.mjs.map +1 -0
  26. package/dist/web/index.d.mts +82 -337
  27. package/dist/web/index.mjs +334 -337
  28. package/dist/web/index.mjs.map +1 -1
  29. package/dist/webext/index.d.mts +73 -0
  30. package/dist/webext/index.mjs +231 -0
  31. package/dist/webext/index.mjs.map +1 -0
  32. package/package.json +28 -21
  33. package/dist/auth-coordination/index.d.mts +0 -198
  34. package/dist/auth-coordination/index.mjs +0 -107
  35. package/dist/auth-coordination/index.mjs.map +0 -1
  36. package/dist/events/index.d.mts +0 -2
  37. package/dist/events/index.mjs +0 -2
  38. package/dist/events-BUlfsRfl.mjs +0 -127
  39. package/dist/events-BUlfsRfl.mjs.map +0 -1
  40. package/dist/fetch-transport-Bd5RyWj2.d.mts +0 -339
  41. package/dist/fetch-transport-DtnSRWAH.mjs +0 -631
  42. package/dist/fetch-transport-DtnSRWAH.mjs.map +0 -1
  43. package/dist/index-C_wgl6dW.d.mts +0 -102
  44. package/dist/index-DbYSFHDe.d.mts +0 -39
  45. package/dist/persistence/index.d.mts +0 -3
  46. package/dist/persistence/index.mjs +0 -2
  47. package/dist/persistence/web/index.d.mts +0 -16
  48. package/dist/persistence/web/index.mjs +0 -51
  49. package/dist/persistence/web/index.mjs.map +0 -1
  50. package/dist/persistence-CSB8770k.mjs +0 -108
  51. package/dist/persistence-CSB8770k.mjs.map +0 -1
  52. package/dist/planner-host-CPyGNyQV.d.mts +0 -190
  53. package/dist/planner-host-CV38bMSn.mjs +0 -195
  54. package/dist/planner-host-CV38bMSn.mjs.map +0 -1
  55. package/dist/types-C59fcM5W.d.mts +0 -52
  56. package/dist/types-DQc088ZP.d.mts +0 -32
  57. package/dist/web-router/index.d.mts +0 -259
  58. package/dist/web-router/index.mjs +0 -395
  59. package/dist/web-router/index.mjs.map +0 -1
@@ -0,0 +1,638 @@
1
+ import { A as RxEventSubject, D as RxStateSignal, F as SYMBOL_DISPOSE, G as ErrorPresentationTone, H as ClientError, K as UserRecovery, U as ClientErrorKind, h as createAsyncSchedulerWithTimestampProvider } from "./rx-DM6Ouv-m.mjs";
2
+ import { V as validateWithSchemaSync } from "./create-i5VyYgN6.mjs";
3
+ import { BehaviorSubject, ReplaySubject, Subject, catchError, delayWhen, distinctUntilChanged, exhaustMap, filter, from, map, merge, of, shareReplay, take, takeUntil, timeout, timer } from "rxjs";
4
+ import { type } from "arktype";
5
+ //#region src/span/attributes.ts
6
+ const SpanSharedAttributeName = {
7
+ ClientName: "client.name",
8
+ ClientId: "client.id",
9
+ OperationName: "operation.name"
10
+ };
11
+ //#endregion
12
+ //#region src/errors/presentation-descriptor.ts
13
+ const DEFAULT_RECOVERY_LABELS = {
14
+ [UserRecovery.None]: "",
15
+ [UserRecovery.Retry]: "Try again",
16
+ [UserRecovery.RestartFlow]: "Restart flow",
17
+ [UserRecovery.Reauthenticate]: "Sign in again",
18
+ [UserRecovery.ContactSupport]: "Contact support"
19
+ };
20
+ const formatClientErrorContext = (context) => {
21
+ let clientName;
22
+ let clientId;
23
+ let operationName;
24
+ for (const frame of context) {
25
+ const frameClientName = frame.attributes[SpanSharedAttributeName.ClientName];
26
+ const frameClientId = frame.attributes[SpanSharedAttributeName.ClientId];
27
+ const frameOperationName = frame.attributes[SpanSharedAttributeName.OperationName];
28
+ if (typeof frameClientName === "string") clientName = frameClientName;
29
+ if (typeof frameClientId === "string") clientId = frameClientId;
30
+ if (typeof frameOperationName === "string") operationName = frameOperationName;
31
+ }
32
+ return [clientName ?? clientId, operationName].filter((value) => Boolean(value)).join(" · ") || void 0;
33
+ };
34
+ function readErrorPresentationDescriptor(error, options = {}) {
35
+ if (!(error instanceof ClientError)) return {
36
+ code: null,
37
+ title: options.fallbackTitle ?? "Operation failed",
38
+ description: options.fallbackDescription ?? "An unexpected error prevented the operation from completing.",
39
+ recovery: UserRecovery.None,
40
+ tone: ErrorPresentationTone.Danger,
41
+ primaryAction: null
42
+ };
43
+ const clientError = error;
44
+ const code = clientError.presentation?.code ?? clientError.code;
45
+ const codePresentation = code ? options.codePresentations?.[code] : void 0;
46
+ const recovery = clientError.presentation?.recovery ?? codePresentation?.recovery ?? clientError.recovery;
47
+ const generic = readGenericPresentation(clientError.kind);
48
+ const descriptor = {
49
+ code,
50
+ title: codePresentation?.title ?? generic.title,
51
+ description: clientError.presentation?.message ?? codePresentation?.description ?? generic.description,
52
+ recovery,
53
+ tone: codePresentation?.tone ?? readClientErrorTone(clientError.kind, recovery),
54
+ primaryAction: readPrimaryAction(recovery, options)
55
+ };
56
+ if (!clientError.spanContext || options.contextFormatter === null) return descriptor;
57
+ const contextLabel = (options.contextFormatter ?? formatClientErrorContext)(clientError.spanContext);
58
+ return contextLabel ? {
59
+ ...descriptor,
60
+ title: `${contextLabel}: ${descriptor.title}`
61
+ } : descriptor;
62
+ }
63
+ function readGenericPresentation(kind) {
64
+ switch (kind) {
65
+ case ClientErrorKind.Unauthenticated: return {
66
+ title: "Authentication required",
67
+ description: "Sign in again to continue."
68
+ };
69
+ case ClientErrorKind.Unauthorized: return {
70
+ title: "Access denied",
71
+ description: "You do not have permission to complete this operation."
72
+ };
73
+ case ClientErrorKind.Cancelled: return {
74
+ title: "Operation cancelled",
75
+ description: "The operation was cancelled before it completed."
76
+ };
77
+ case ClientErrorKind.Timeout: return {
78
+ title: "Request timed out",
79
+ description: "The operation did not complete in time."
80
+ };
81
+ case ClientErrorKind.Configuration: return {
82
+ title: "Configuration error",
83
+ description: "The client is not configured to complete this operation."
84
+ };
85
+ case ClientErrorKind.Storage: return {
86
+ title: "Storage failed",
87
+ description: "The client could not access required stored data."
88
+ };
89
+ case ClientErrorKind.Transport: return {
90
+ title: "Network request failed",
91
+ description: "The client could not reach the service."
92
+ };
93
+ case ClientErrorKind.Server: return {
94
+ title: "Server request failed",
95
+ description: "The service could not complete the request."
96
+ };
97
+ case ClientErrorKind.Protocol: return {
98
+ title: "Invalid response",
99
+ description: "The service response did not satisfy the expected protocol."
100
+ };
101
+ case ClientErrorKind.Authorization: return {
102
+ title: "Authorization failed",
103
+ description: "The authorization flow could not be completed."
104
+ };
105
+ default: return {
106
+ title: "Operation failed",
107
+ description: "The operation could not be completed."
108
+ };
109
+ }
110
+ }
111
+ function readClientErrorTone(kind, recovery) {
112
+ if (kind === ClientErrorKind.Cancelled) return ErrorPresentationTone.Neutral;
113
+ if (kind === ClientErrorKind.Unauthenticated || kind === ClientErrorKind.Timeout || kind === ClientErrorKind.Transport || kind === ClientErrorKind.Server || recovery === UserRecovery.Retry || recovery === UserRecovery.RestartFlow || recovery === UserRecovery.Reauthenticate) return ErrorPresentationTone.Warning;
114
+ return ErrorPresentationTone.Danger;
115
+ }
116
+ function readPrimaryAction(recovery, options) {
117
+ if (recovery === UserRecovery.None) return null;
118
+ const label = options.recoveryLabels?.[recovery] ?? DEFAULT_RECOVERY_LABELS[recovery];
119
+ if (!label) return null;
120
+ return {
121
+ recovery,
122
+ label,
123
+ href: options.recoveryLinks?.[recovery] ?? null
124
+ };
125
+ }
126
+ //#endregion
127
+ //#region src/signals/signal.ts
128
+ /**
129
+ * Minimal writable signal implementation.
130
+ * `set()` always publishes a write. Equality-based value-version suppression is
131
+ * handled by the underlying Rx signal for computed dependency validation.
132
+ */
133
+ function createSignal(initial, options) {
134
+ return RxStateSignal.fromInitialValue(initial, options);
135
+ }
136
+ /**
137
+ * Create a read-only view of a writable signal.
138
+ */
139
+ function readonlySignal(signal) {
140
+ return signal;
141
+ }
142
+ //#endregion
143
+ //#region src/popup/errors.ts
144
+ const PopupErrorCode = {
145
+ Blocked: "popup.blocked",
146
+ Closed: "popup.closed_by_user"
147
+ };
148
+ function readPopupErrorPresentationDescriptor(error, options = {}) {
149
+ return readErrorPresentationDescriptor(error, {
150
+ ...options,
151
+ codePresentations: {
152
+ [PopupErrorCode.Blocked]: {
153
+ title: "Popup was blocked",
154
+ description: "The browser blocked the popup window. Allow popups for this site, then try again.",
155
+ recovery: UserRecovery.Retry,
156
+ tone: ErrorPresentationTone.Warning
157
+ },
158
+ [PopupErrorCode.Closed]: {
159
+ title: "Popup was closed",
160
+ description: "The popup window was closed before the operation completed. Start the flow again.",
161
+ recovery: UserRecovery.RestartFlow,
162
+ tone: ErrorPresentationTone.Warning
163
+ },
164
+ ...options.codePresentations
165
+ }
166
+ });
167
+ }
168
+ //#endregion
169
+ //#region src/protocol/json-rpc/types.ts
170
+ const JsonRpcIdSchema = type("string | number");
171
+ const JsonRpcErrorPayloadSchema = type({
172
+ code: "number",
173
+ message: "string",
174
+ data: "unknown?"
175
+ });
176
+ const JsonRpcRequestMessageSchema = type({
177
+ jsonrpc: "\"2.0\"",
178
+ id: JsonRpcIdSchema,
179
+ method: "string",
180
+ params: "unknown?"
181
+ });
182
+ const JsonRpcNotificationMessageSchema = type({
183
+ jsonrpc: "\"2.0\"",
184
+ method: "string",
185
+ params: "unknown?"
186
+ });
187
+ const JsonRpcSuccessResponseMessageSchema = type({
188
+ jsonrpc: "\"2.0\"",
189
+ id: JsonRpcIdSchema,
190
+ result: "unknown"
191
+ });
192
+ const JsonRpcErrorResponseMessageSchema = type({
193
+ jsonrpc: "\"2.0\"",
194
+ id: JsonRpcIdSchema,
195
+ error: JsonRpcErrorPayloadSchema
196
+ });
197
+ const JsonRpcMessageSchema = JsonRpcRequestMessageSchema.or(JsonRpcNotificationMessageSchema).or(JsonRpcSuccessResponseMessageSchema).or(JsonRpcErrorResponseMessageSchema);
198
+ //#endregion
199
+ //#region src/protocol/json-rpc/create.ts
200
+ function createJsonRpcClient(options) {
201
+ return new JsonRpcClient(options);
202
+ }
203
+ function createJsonRpcServer(options) {
204
+ return new JsonRpcServer(options);
205
+ }
206
+ function createJsonRpcServerAndClient(options) {
207
+ return new JsonRpcServerAndClient(options);
208
+ }
209
+ var JsonRpcClient = class {
210
+ options;
211
+ onNotification;
212
+ notificationSubject = new RxEventSubject();
213
+ pendingRequests = /* @__PURE__ */ new Map();
214
+ disposed = false;
215
+ nextRequestId = 1;
216
+ constructor(options) {
217
+ this.options = options;
218
+ this.onNotification = this.notificationSubject;
219
+ }
220
+ request(method, params, requestOptions = {}) {
221
+ if (this.disposed) return Promise.reject(createJsonRpcDisposedError("client"));
222
+ const id = this.nextRequestId++;
223
+ const timeoutMs = requestOptions.timeoutMs ?? this.options.defaultRequestTimeoutMs;
224
+ return new Promise((resolve, reject) => {
225
+ const pendingRequest = {
226
+ method,
227
+ reject,
228
+ resolve
229
+ };
230
+ if (timeoutMs !== void 0) pendingRequest.timeoutHandle = this.options.time.setTimeout(() => {
231
+ this.pendingRequests.delete(id);
232
+ reject(/* @__PURE__ */ new Error(`JSON-RPC request timed out for ${method}.`));
233
+ }, timeoutMs);
234
+ this.pendingRequests.set(id, pendingRequest);
235
+ try {
236
+ this.options.send({
237
+ jsonrpc: "2.0",
238
+ id,
239
+ method,
240
+ params
241
+ });
242
+ } catch (error) {
243
+ this.clearPendingRequest(id);
244
+ reject(error);
245
+ }
246
+ });
247
+ }
248
+ notify(method, params) {
249
+ if (this.disposed) return;
250
+ this.options.send({
251
+ jsonrpc: "2.0",
252
+ method,
253
+ params
254
+ });
255
+ }
256
+ receive(message) {
257
+ if (this.disposed) return;
258
+ for (const parsedMessage of parseIncomingMessages(message)) {
259
+ if (isJsonRpcResponseMessage(parsedMessage)) {
260
+ this.resolvePendingRequest(parsedMessage);
261
+ continue;
262
+ }
263
+ if (isJsonRpcNotificationMessage(parsedMessage)) this.notificationSubject.next({
264
+ method: parsedMessage.method,
265
+ params: parsedMessage.params
266
+ });
267
+ }
268
+ }
269
+ rejectAllPendingRequests(reason) {
270
+ for (const [id, pendingRequest] of this.pendingRequests) {
271
+ this.clearPendingRequest(id);
272
+ pendingRequest.reject(reason);
273
+ }
274
+ }
275
+ dispose() {
276
+ if (this.disposed) return;
277
+ this.disposed = true;
278
+ this.rejectAllPendingRequests(/* @__PURE__ */ new Error("JSON-RPC client disposed."));
279
+ this.notificationSubject.complete();
280
+ }
281
+ [SYMBOL_DISPOSE]() {
282
+ this.dispose();
283
+ }
284
+ resolvePendingRequest(message) {
285
+ const pendingRequest = this.pendingRequests.get(message.id);
286
+ if (!pendingRequest) return;
287
+ this.clearPendingRequest(message.id);
288
+ if ("error" in message) {
289
+ pendingRequest.reject(/* @__PURE__ */ new Error(`JSON-RPC request failed for ${pendingRequest.method}: ${message.error.message}`));
290
+ return;
291
+ }
292
+ pendingRequest.resolve(message.result);
293
+ }
294
+ clearPendingRequest(id) {
295
+ const pendingRequest = this.pendingRequests.get(id);
296
+ if (!pendingRequest) return;
297
+ if (pendingRequest.timeoutHandle !== void 0) this.options.time.clearTimeout(pendingRequest.timeoutHandle);
298
+ this.pendingRequests.delete(id);
299
+ }
300
+ };
301
+ var JsonRpcServer = class {
302
+ options;
303
+ onRequest;
304
+ onNotification;
305
+ requestSubject = new RxEventSubject();
306
+ notificationSubject = new RxEventSubject();
307
+ disposed = false;
308
+ constructor(options) {
309
+ this.options = options;
310
+ this.onRequest = this.requestSubject;
311
+ this.onNotification = this.notificationSubject;
312
+ }
313
+ notify(method, params) {
314
+ if (this.disposed) return;
315
+ this.options.send({
316
+ jsonrpc: "2.0",
317
+ method,
318
+ params
319
+ });
320
+ }
321
+ receive(message) {
322
+ if (this.disposed) return;
323
+ for (const parsedMessage of parseIncomingMessages(message)) {
324
+ if (isJsonRpcRequestMessage(parsedMessage)) {
325
+ this.requestSubject.next({
326
+ id: parsedMessage.id,
327
+ method: parsedMessage.method,
328
+ params: parsedMessage.params
329
+ });
330
+ continue;
331
+ }
332
+ if (isJsonRpcNotificationMessage(parsedMessage)) this.notificationSubject.next({
333
+ method: parsedMessage.method,
334
+ params: parsedMessage.params
335
+ });
336
+ }
337
+ }
338
+ respondSuccess(id, result) {
339
+ if (this.disposed) return;
340
+ this.options.send({
341
+ jsonrpc: "2.0",
342
+ id,
343
+ result
344
+ });
345
+ }
346
+ respondError(id, error) {
347
+ if (this.disposed) return;
348
+ this.options.send({
349
+ jsonrpc: "2.0",
350
+ id,
351
+ error
352
+ });
353
+ }
354
+ dispose() {
355
+ if (this.disposed) return;
356
+ this.disposed = true;
357
+ this.requestSubject.complete();
358
+ this.notificationSubject.complete();
359
+ }
360
+ [SYMBOL_DISPOSE]() {
361
+ this.dispose();
362
+ }
363
+ };
364
+ var JsonRpcServerAndClient = class {
365
+ onNotification;
366
+ onRequest;
367
+ client;
368
+ server;
369
+ disposed = false;
370
+ constructor(options) {
371
+ this.client = new JsonRpcClient(options);
372
+ this.server = new JsonRpcServer(options);
373
+ this.onNotification = this.server.onNotification;
374
+ this.onRequest = this.server.onRequest;
375
+ }
376
+ request(method, params, options) {
377
+ return this.client.request(method, params, options);
378
+ }
379
+ notify(method, params) {
380
+ this.client.notify(method, params);
381
+ }
382
+ receive(message) {
383
+ for (const parsedMessage of parseIncomingMessages(message)) {
384
+ if (isJsonRpcResponseMessage(parsedMessage)) {
385
+ this.client.receive(parsedMessage);
386
+ continue;
387
+ }
388
+ this.server.receive(parsedMessage);
389
+ }
390
+ }
391
+ rejectAllPendingRequests(reason) {
392
+ this.client.rejectAllPendingRequests(reason);
393
+ }
394
+ respondSuccess(id, result) {
395
+ this.server.respondSuccess(id, result);
396
+ }
397
+ respondError(id, error) {
398
+ this.server.respondError(id, error);
399
+ }
400
+ dispose() {
401
+ if (this.disposed) return;
402
+ this.disposed = true;
403
+ this.client.dispose();
404
+ this.server.dispose();
405
+ }
406
+ [SYMBOL_DISPOSE]() {
407
+ this.dispose();
408
+ }
409
+ };
410
+ function parseIncomingMessages(message) {
411
+ if (!Array.isArray(message)) return parseJsonRpcMessage(message);
412
+ const parsedMessages = [];
413
+ for (const entry of message) parsedMessages.push(...parseJsonRpcMessage(entry));
414
+ return parsedMessages;
415
+ }
416
+ function parseJsonRpcMessage(message) {
417
+ const result = validateWithSchemaSync(JsonRpcMessageSchema, message);
418
+ return result.success ? [result.value] : [];
419
+ }
420
+ function isJsonRpcRequestMessage(message) {
421
+ return "method" in message && "id" in message;
422
+ }
423
+ function isJsonRpcResponseMessage(message) {
424
+ return "id" in message && !("method" in message);
425
+ }
426
+ function isJsonRpcNotificationMessage(message) {
427
+ return "method" in message && !("id" in message);
428
+ }
429
+ function createJsonRpcDisposedError(role) {
430
+ return /* @__PURE__ */ new Error(`JSON-RPC ${role} disposed.`);
431
+ }
432
+ //#endregion
433
+ //#region src/popup/session.ts
434
+ const PopupSessionControlMethod = {
435
+ Ready: "securitydept.popup.session.ready",
436
+ Ping: "securitydept.popup.session.ping",
437
+ Pong: "securitydept.popup.session.pong"
438
+ };
439
+ const DEFAULT_READY_TIMEOUT_MS = 1e4;
440
+ const DEFAULT_HEARTBEAT_INTERVAL_MS = 5e3;
441
+ const DEFAULT_HEARTBEAT_TIMEOUT_MS = 15e3;
442
+ var PopupClientSession = class {
443
+ failure = createSignal(null);
444
+ isActive = createSignal(false);
445
+ init$ = new ReplaySubject();
446
+ destroyed = createSignal(false);
447
+ destroyed$ = from(this.destroyed).pipe(distinctUntilChanged(), filter(Boolean), shareReplay(1));
448
+ constructor(options) {
449
+ const timestampScheduler = createAsyncSchedulerWithTimestampProvider(options.time);
450
+ const ready$ = new Subject();
451
+ const pong$ = new Subject();
452
+ const closed$ = from(options.closedStream).pipe(filter(Boolean));
453
+ const ping$ = merge(ready$.pipe(filter(Boolean)), pong$.pipe(filter(Boolean))).pipe(delayWhen(() => timer(options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS, timestampScheduler)));
454
+ from(this.init$).pipe(exhaustMap(() => from(options.jsonRpc.onNotification).pipe(filter(function isReadyNotification(event) {
455
+ return event.method === PopupSessionControlMethod.Ready;
456
+ }), take(1), timeout({
457
+ each: options.readyTimeoutMs ?? DEFAULT_READY_TIMEOUT_MS,
458
+ scheduler: timestampScheduler
459
+ }), map(() => true), catchError(() => of(false)))), takeUntil(this.destroyed$)).subscribe(ready$);
460
+ ping$.pipe(exhaustMap(() => from(options.jsonRpc.onNotification).pipe(filter(function isPongNotification(event) {
461
+ return event.method === PopupSessionControlMethod.Pong;
462
+ }), take(1), timeout({
463
+ first: options.heartbeatTimeoutMs ?? DEFAULT_HEARTBEAT_TIMEOUT_MS,
464
+ scheduler: timestampScheduler
465
+ }), map(() => true), catchError(() => of(false)))), takeUntil(this.destroyed$)).subscribe(pong$);
466
+ merge(closed$.pipe(map(() => new ClientError({
467
+ kind: ClientErrorKind.Authorization,
468
+ code: PopupErrorCode.Closed,
469
+ message: "Popup window was closed before completing the login flow.",
470
+ recovery: UserRecovery.RestartFlow,
471
+ source: "popup"
472
+ }))), ready$.pipe(map((success) => !success ? new ClientError({
473
+ kind: ClientErrorKind.Protocol,
474
+ message: "Did not receive ready notification from popup within the expected time.",
475
+ recovery: UserRecovery.RestartFlow,
476
+ source: "popup"
477
+ }) : null)), pong$.pipe(map((success) => !success ? new ClientError({
478
+ kind: ClientErrorKind.Protocol,
479
+ message: "Did not receive pong notification from popup within the expected time.",
480
+ recovery: UserRecovery.RestartFlow,
481
+ source: "popup"
482
+ }) : null))).pipe(takeUntil(this.destroyed$), shareReplay({
483
+ bufferSize: 1,
484
+ refCount: false
485
+ })).subscribe((error) => this.failure.set(error));
486
+ merge(closed$.pipe(map(() => false)), ready$.pipe(map(Boolean)), pong$.pipe(map(Boolean))).pipe(takeUntil(this.destroyed$)).subscribe((nextIsActive) => {
487
+ this.isActive.set(nextIsActive);
488
+ });
489
+ }
490
+ init() {
491
+ this.init$.next(true);
492
+ }
493
+ dispose() {
494
+ this.destroyed.set(true);
495
+ }
496
+ [SYMBOL_DISPOSE]() {
497
+ this.dispose();
498
+ }
499
+ };
500
+ var PopupServerSession = class {
501
+ init$ = new ReplaySubject();
502
+ destroyed$$ = new BehaviorSubject(false);
503
+ destroyed$ = this.destroyed$$.pipe(distinctUntilChanged(), filter(Boolean), shareReplay(1));
504
+ constructor(options) {
505
+ const ready$ = from(this.init$);
506
+ const pong$ = from(options.jsonRpc.onNotification).pipe(filter(function isPing(event) {
507
+ return event.method === PopupSessionControlMethod.Ping;
508
+ }));
509
+ merge(ready$.pipe(map(function createReadyNotify() {
510
+ return { method: PopupSessionControlMethod.Ready };
511
+ })), pong$.pipe(map(function createPongNotify() {
512
+ return { method: PopupSessionControlMethod.Pong };
513
+ }))).pipe(takeUntil(this.destroyed$)).subscribe((event) => {
514
+ options.jsonRpc.notify(event.method, event.params);
515
+ });
516
+ }
517
+ init() {
518
+ this.init$.next(true);
519
+ }
520
+ dispose() {
521
+ this.destroyed$$.next(true);
522
+ }
523
+ [SYMBOL_DISPOSE]() {
524
+ this.dispose();
525
+ }
526
+ };
527
+ //#endregion
528
+ //#region src/popup/handle.ts
529
+ /**
530
+ * popup opener
531
+ */
532
+ var PopupClientWindowHandle = class {
533
+ messaging;
534
+ disposed = false;
535
+ jsonRpc;
536
+ session;
537
+ incomingSubscription;
538
+ closePopup;
539
+ constructor(options) {
540
+ this.messaging = options.messaging;
541
+ this.closePopup = options.close;
542
+ this.jsonRpc = createJsonRpcClient({
543
+ send: (message) => {
544
+ options.messaging.outgoing.next(message);
545
+ },
546
+ time: options.time
547
+ });
548
+ this.session = new PopupClientSession({
549
+ jsonRpc: this.jsonRpc,
550
+ time: options.time,
551
+ closedStream: options.closedStream
552
+ });
553
+ this.incomingSubscription = options.messaging.incoming.subscribe({ next: (message) => {
554
+ this.jsonRpc.receive(message);
555
+ } });
556
+ this.session.init();
557
+ }
558
+ get onNotification() {
559
+ return this.jsonRpc.onNotification;
560
+ }
561
+ get failure() {
562
+ return this.session.failure;
563
+ }
564
+ get isActive() {
565
+ return this.session.isActive;
566
+ }
567
+ async notify(method, params) {
568
+ this.jsonRpc.notify(method, params);
569
+ }
570
+ request(method, params, options) {
571
+ return this.jsonRpc.request(method, params, options);
572
+ }
573
+ close() {
574
+ this.closePopup();
575
+ }
576
+ dispose() {
577
+ if (this.disposed) return;
578
+ this.disposed = true;
579
+ this.session.dispose();
580
+ this.jsonRpc.dispose();
581
+ this.incomingSubscription.unsubscribe();
582
+ this.messaging.outgoing.complete();
583
+ }
584
+ [SYMBOL_DISPOSE]() {
585
+ this.dispose();
586
+ }
587
+ };
588
+ /**
589
+ * popup target
590
+ */
591
+ var PopupServerWindowHandle = class {
592
+ messaging;
593
+ disposed = false;
594
+ jsonRpc;
595
+ session;
596
+ incomingSubscription;
597
+ closePopup;
598
+ constructor(options) {
599
+ this.messaging = options.messaging;
600
+ this.closePopup = options.close;
601
+ this.jsonRpc = createJsonRpcServer({ send: (message) => {
602
+ options.messaging.outgoing.next(message);
603
+ } });
604
+ this.session = new PopupServerSession({ jsonRpc: this.jsonRpc });
605
+ this.incomingSubscription = options.messaging.incoming.subscribe({ next: (message) => {
606
+ this.jsonRpc.receive(message);
607
+ } });
608
+ this.session.init();
609
+ }
610
+ get onNotification() {
611
+ return this.jsonRpc.onNotification;
612
+ }
613
+ get onRequest() {
614
+ return this.jsonRpc.onRequest;
615
+ }
616
+ notify(method, params) {
617
+ this.jsonRpc.notify(method, params);
618
+ return Promise.resolve();
619
+ }
620
+ close() {
621
+ this.closePopup();
622
+ }
623
+ dispose() {
624
+ if (this.disposed) return;
625
+ this.disposed = true;
626
+ this.session.dispose();
627
+ this.jsonRpc.dispose();
628
+ this.incomingSubscription.unsubscribe();
629
+ this.messaging.outgoing.complete();
630
+ }
631
+ [SYMBOL_DISPOSE]() {
632
+ this.dispose();
633
+ }
634
+ };
635
+ //#endregion
636
+ export { createJsonRpcServerAndClient as a, createSignal as c, readErrorPresentationDescriptor as d, SpanSharedAttributeName as f, createJsonRpcServer as i, readonlySignal as l, PopupServerWindowHandle as n, PopupErrorCode as o, createJsonRpcClient as r, readPopupErrorPresentationDescriptor as s, PopupClientWindowHandle as t, formatClientErrorContext as u };
637
+
638
+ //# sourceMappingURL=handle-DwMgqe7R.mjs.map