@rpcbase/client 0.447.0 → 0.449.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/dist/index.js CHANGED
@@ -264,6 +264,17 @@ const toastContentStyles = `
264
264
  overscroll-behavior: contain;
265
265
  scrollbar-width: thin;
266
266
  }
267
+
268
+ @media (hover: hover) and (pointer: fine) {
269
+ [data-sonner-toaster][data-x-position="right"] [data-sonner-toast][data-front="true"]:not([data-mounted="true"]),
270
+ [data-sonner-toaster][data-x-position="right"] [data-sonner-toast][data-front="true"][data-removed="true"][data-swipe-out="false"] {
271
+ --y: translateX(calc(100% + 24px)) !important;
272
+ }
273
+
274
+ [data-sonner-toaster][data-x-position="right"] [data-sonner-toast][data-front="true"][data-mounted="true"][data-removed="false"] {
275
+ --y: translateX(0) !important;
276
+ }
277
+ }
267
278
  `;
268
279
  const MountedLazyToaster = (props) => {
269
280
  const $ = c(3);
@@ -286,7 +297,7 @@ const MountedLazyToaster = (props) => {
286
297
  return t1;
287
298
  };
288
299
  const ActiveToaster = () => {
289
- const $ = c(9);
300
+ const $ = c(10);
290
301
  const isCoarsePointer = useMediaQuery("(hover: none) and (pointer: coarse)");
291
302
  let t0;
292
303
  if ($[0] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
@@ -304,29 +315,30 @@ const ActiveToaster = () => {
304
315
  t1 = $[1];
305
316
  }
306
317
  const t2 = !isCoarsePointer;
307
- let t3;
318
+ const t3 = isCoarsePointer ? "bottom-center" : "top-right";
319
+ let t4;
308
320
  if ($[2] !== isCoarsePointer) {
309
- t3 = isCoarsePointer ? void 0 : [];
321
+ t4 = isCoarsePointer ? void 0 : [];
310
322
  $[2] = isCoarsePointer;
311
- $[3] = t3;
323
+ $[3] = t4;
312
324
  } else {
313
- t3 = $[3];
325
+ t4 = $[3];
314
326
  }
315
- let t4;
327
+ let t5;
316
328
  if ($[4] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
317
- t4 = {
329
+ t5 = {
318
330
  pointerEvents: "auto",
319
331
  "--toast-close-button-start": "unset",
320
332
  "--toast-close-button-end": "0",
321
333
  "--toast-close-button-transform": "translate(35%, -35%)"
322
334
  };
323
- $[4] = t4;
335
+ $[4] = t5;
324
336
  } else {
325
- t4 = $[4];
337
+ t5 = $[4];
326
338
  }
327
- let t5;
339
+ let t6;
328
340
  if ($[5] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
329
- t5 = {
341
+ t6 = {
330
342
  classNames: {
331
343
  content: toastContentClassName
332
344
  },
@@ -335,23 +347,24 @@ const ActiveToaster = () => {
335
347
  userSelect: "text"
336
348
  }
337
349
  };
338
- $[5] = t5;
350
+ $[5] = t6;
339
351
  } else {
340
- t5 = $[5];
352
+ t6 = $[5];
341
353
  }
342
- let t6;
343
- if ($[6] !== t2 || $[7] !== t3) {
344
- t6 = /* @__PURE__ */ jsxs(Fragment, { children: [
354
+ let t7;
355
+ if ($[6] !== t2 || $[7] !== t3 || $[8] !== t4) {
356
+ t7 = /* @__PURE__ */ jsxs(Fragment, { children: [
345
357
  t1,
346
- /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(MountedLazyToaster, { closeButton: t2, theme: "dark", position: "bottom-center", swipeDirections: t3, style: t4, toastOptions: t5 }) })
358
+ /* @__PURE__ */ jsx(Suspense, { fallback: null, children: /* @__PURE__ */ jsx(MountedLazyToaster, { closeButton: t2, theme: "dark", position: t3, swipeDirections: t4, style: t5, toastOptions: t6 }) })
347
359
  ] });
348
360
  $[6] = t2;
349
361
  $[7] = t3;
350
- $[8] = t6;
362
+ $[8] = t4;
363
+ $[9] = t7;
351
364
  } else {
352
- t6 = $[8];
365
+ t7 = $[9];
353
366
  }
354
- return t6;
367
+ return t7;
355
368
  };
356
369
  const Toaster = () => {
357
370
  const $ = c(2);
@@ -2331,12 +2344,182 @@ const ACTIVE_TAB_HEARTBEAT_MS = 5e3;
2331
2344
  const ACTIVE_TAB_TTL_MS = 15e3;
2332
2345
  const DELIVERY_TTL_MS = 10 * 60 * 1e3;
2333
2346
  const FALLBACK_DELIVERY_LOCK_TTL_MS = 2e3;
2347
+ const ACTIVE_TAB_NATIVE_GRACE_MS = 350;
2334
2348
  const TAB_STATE_KEY_PREFIX = "rb:notifications:tab:";
2335
2349
  const DELIVERY_KEY_PREFIX = "rb:notifications:delivery:";
2336
2350
  const DELIVERY_LOCK_PREFIX = "rb-notifications-delivery:";
2337
2351
  const FALLBACK_DELIVERY_LOCK_KEY_PREFIX = "rb:notifications:delivery-lock:";
2338
2352
  const NOTIFICATION_TAB_ID = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`;
2339
2353
  const DEFAULT_NOTIFICATION_APP_NAME = "default";
2354
+ const notificationToastClassName = "rpcbase-notification-toast";
2355
+ const notificationToastContentClassName = "rpcbase-notification-toast-content";
2356
+ const notificationToastTitleClassName = "rpcbase-notification-toast-title";
2357
+ const notificationToastDescriptionClassName = "rpcbase-notification-toast-description";
2358
+ const notificationToastIconDotClassName = "rpcbase-notification-toast-icon-dot";
2359
+ const notificationToastCloseButtonClassName = "rpcbase-notification-toast-close";
2360
+ const notificationToastStyles = `
2361
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] {
2362
+ width: min(var(--width), calc(100vw - 32px));
2363
+ align-items: flex-start;
2364
+ gap: 10px;
2365
+ padding: 14px 15px;
2366
+ border-color: rgb(226 232 240 / 0.95);
2367
+ border-radius: 10px;
2368
+ background: rgb(255 255 255 / 0.96);
2369
+ color: rgb(15 23 42);
2370
+ box-shadow: 0 18px 38px rgb(15 23 42 / 0.16), 0 2px 8px rgb(15 23 42 / 0.08);
2371
+ backdrop-filter: blur(12px);
2372
+ }
2373
+
2374
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastContentClassName} {
2375
+ gap: 3px;
2376
+ padding-right: 8px;
2377
+ }
2378
+
2379
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastTitleClassName} {
2380
+ color: inherit;
2381
+ font-size: 13px;
2382
+ font-weight: 650;
2383
+ line-height: 1.35;
2384
+ letter-spacing: 0;
2385
+ }
2386
+
2387
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastDescriptionClassName} {
2388
+ color: rgb(71 85 105);
2389
+ font-size: 12.5px;
2390
+ line-height: 1.4;
2391
+ }
2392
+
2393
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] [data-icon] {
2394
+ position: relative;
2395
+ isolation: isolate;
2396
+ margin-top: 4px;
2397
+ margin-left: 0;
2398
+ margin-right: 2px;
2399
+ width: 18px;
2400
+ height: 18px;
2401
+ justify-content: center;
2402
+ align-items: center;
2403
+ overflow: visible;
2404
+ }
2405
+
2406
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] [data-icon]::before {
2407
+ content: "";
2408
+ position: absolute;
2409
+ inset: 5px;
2410
+ z-index: 0;
2411
+ border: 1px solid rgb(37 99 235 / 0.36);
2412
+ border-radius: 999px;
2413
+ opacity: 0;
2414
+ transform: scale(0.9);
2415
+ animation: rpcbase-notification-pulse 1700ms cubic-bezier(0.2, 0, 0.2, 1) infinite;
2416
+ will-change: transform, opacity;
2417
+ }
2418
+
2419
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastIconDotClassName} {
2420
+ position: relative;
2421
+ z-index: 1;
2422
+ display: block;
2423
+ width: 7px;
2424
+ height: 7px;
2425
+ border-radius: 999px;
2426
+ background: rgb(37 99 235);
2427
+ box-shadow: 0 0 0 1px rgb(255 255 255 / 0.9);
2428
+ }
2429
+
2430
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastCloseButtonClassName}[data-close-button] {
2431
+ background: rgb(255 255 255);
2432
+ border-color: rgb(203 213 225);
2433
+ color: rgb(71 85 105);
2434
+ }
2435
+
2436
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastCloseButtonClassName}[data-close-button]:hover {
2437
+ background: rgb(248 250 252);
2438
+ border-color: rgb(148 163 184);
2439
+ color: rgb(30 41 59);
2440
+ }
2441
+
2442
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastCloseButtonClassName}[data-close-button]:focus-visible {
2443
+ background: rgb(248 250 252);
2444
+ border-color: rgb(37 99 235 / 0.5);
2445
+ color: rgb(30 41 59);
2446
+ box-shadow: 0 0 0 3px rgb(37 99 235 / 0.16);
2447
+ }
2448
+
2449
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] {
2450
+ border-color: rgb(51 65 85 / 0.9);
2451
+ background: rgb(2 6 23 / 0.96);
2452
+ color: rgb(248 250 252);
2453
+ box-shadow: 0 18px 38px rgb(0 0 0 / 0.36), 0 2px 8px rgb(0 0 0 / 0.24);
2454
+ }
2455
+
2456
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastDescriptionClassName} {
2457
+ color: rgb(203 213 225);
2458
+ }
2459
+
2460
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] [data-icon]::before {
2461
+ border-color: rgb(96 165 250 / 0.4);
2462
+ }
2463
+
2464
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastIconDotClassName} {
2465
+ background: rgb(96 165 250);
2466
+ box-shadow: 0 0 0 1px rgb(15 23 42 / 0.9);
2467
+ }
2468
+
2469
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastCloseButtonClassName}[data-close-button] {
2470
+ background: rgb(15 23 42);
2471
+ border-color: rgb(51 65 85);
2472
+ color: rgb(226 232 240);
2473
+ }
2474
+
2475
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastCloseButtonClassName}[data-close-button]:hover {
2476
+ background: rgb(30 41 59);
2477
+ border-color: rgb(71 85 105);
2478
+ color: rgb(248 250 252);
2479
+ }
2480
+
2481
+ .dark .${notificationToastClassName}[data-sonner-toast][data-styled="true"] .${notificationToastCloseButtonClassName}[data-close-button]:focus-visible {
2482
+ background: rgb(30 41 59);
2483
+ border-color: rgb(96 165 250 / 0.55);
2484
+ color: rgb(248 250 252);
2485
+ box-shadow: 0 0 0 3px rgb(96 165 250 / 0.18);
2486
+ }
2487
+
2488
+ @keyframes rpcbase-notification-pulse {
2489
+ 0% {
2490
+ opacity: 0;
2491
+ transform: scale(0.9);
2492
+ }
2493
+
2494
+ 20% {
2495
+ opacity: 0.55;
2496
+ }
2497
+
2498
+ 80%,
2499
+ 100% {
2500
+ opacity: 0;
2501
+ transform: scale(2.65);
2502
+ }
2503
+ }
2504
+
2505
+ @media (prefers-reduced-motion: reduce) {
2506
+ .${notificationToastClassName}[data-sonner-toast][data-styled="true"] [data-icon]::before {
2507
+ animation: none;
2508
+ opacity: 0.32;
2509
+ transform: scale(2.2);
2510
+ }
2511
+ }
2512
+ `;
2513
+ const notificationToastOptions = {
2514
+ icon: /* @__PURE__ */ jsx("span", { className: notificationToastIconDotClassName, "aria-hidden": "true" }),
2515
+ classNames: {
2516
+ toast: notificationToastClassName,
2517
+ content: notificationToastContentClassName,
2518
+ title: notificationToastTitleClassName,
2519
+ description: notificationToastDescriptionClassName,
2520
+ closeButton: notificationToastCloseButtonClassName
2521
+ }
2522
+ };
2340
2523
  const NotificationsRealtimeContext = createContext(null);
2341
2524
  const toIso = (value) => {
2342
2525
  if (value instanceof Date) return value.toISOString();
@@ -2495,6 +2678,18 @@ const hasActiveNotificationTab = (userId, appName) => {
2495
2678
  }
2496
2679
  return false;
2497
2680
  };
2681
+ const hasRecentNotificationDelivery = (userId, appName, mode, notificationId) => {
2682
+ const storage = getLocalStorage();
2683
+ if (!storage) return false;
2684
+ try {
2685
+ const record = parseJsonRecord(storage.getItem(getDeliveryKey(userId, appName, mode, notificationId)));
2686
+ const deliveredAt = typeof record?.deliveredAt === "number" ? record.deliveredAt : 0;
2687
+ return deliveredAt > 0 && Date.now() - deliveredAt < DELIVERY_TTL_MS;
2688
+ } catch {
2689
+ return false;
2690
+ }
2691
+ };
2692
+ const filterNotificationsWithoutDelivery = (items, userId, appName, mode) => items.filter((item) => !hasRecentNotificationDelivery(userId, appName, mode, item.id));
2498
2693
  const claimNotificationDeliveriesFromStorage = (items, userId, appName, mode) => {
2499
2694
  const storage = getLocalStorage();
2500
2695
  if (!storage) return items;
@@ -2574,10 +2769,7 @@ const withFallbackDeliveryLock = (userId, appName, callback, fallback) => {
2574
2769
  };
2575
2770
  const claimNotificationDeliveries = async (items, userId, appName, mode) => {
2576
2771
  if (items.length === 0) return [];
2577
- const claim = () => {
2578
- if (mode === "native" && hasActiveNotificationTab(userId, appName)) return [];
2579
- return claimNotificationDeliveriesFromStorage(items, userId, appName, mode);
2580
- };
2772
+ const claim = () => claimNotificationDeliveriesFromStorage(items, userId, appName, mode);
2581
2773
  const locks = getLockManager();
2582
2774
  if (!locks) return withFallbackDeliveryLock(userId, appName, claim, []);
2583
2775
  try {
@@ -2596,12 +2788,14 @@ const claimNotificationDeliveries = async (items, userId, appName, mode) => {
2596
2788
  const showInAppNotifications = (items) => {
2597
2789
  if (items.length > 3) {
2598
2790
  toast(`${items.length} new notifications`, {
2791
+ ...notificationToastOptions,
2599
2792
  description: "Open the notifications drawer to view them."
2600
2793
  });
2601
2794
  return;
2602
2795
  }
2603
2796
  for (const item of items) {
2604
2797
  toast(item.title, {
2798
+ ...notificationToastOptions,
2605
2799
  description: item.body
2606
2800
  });
2607
2801
  }
@@ -2670,11 +2864,17 @@ const showNotificationsForCurrentFocusState = async (items, userId, appName) =>
2670
2864
  return [];
2671
2865
  }
2672
2866
  if (!canShowNativeNotification()) return items;
2673
- const claimed = await claimNotificationDeliveries(items, userId, appName, "native");
2867
+ let nativeItems = items;
2868
+ if (hasActiveNotificationTab(userId, appName)) {
2869
+ await new Promise((resolve) => window.setTimeout(resolve, ACTIVE_TAB_NATIVE_GRACE_MS));
2870
+ nativeItems = filterNotificationsWithoutDelivery(items, userId, appName, "in-app");
2871
+ if (nativeItems.length === 0) return [];
2872
+ }
2873
+ const claimed = await claimNotificationDeliveries(nativeItems, userId, appName, "native");
2674
2874
  if (claimed.length > 0) {
2675
2875
  showNativeNotifications(claimed);
2676
2876
  }
2677
- return items;
2877
+ return nativeItems;
2678
2878
  };
2679
2879
  const flushPendingInAppToasts = (pendingInAppToastItems, userId, appName) => {
2680
2880
  if (!isDocumentActive()) return;
@@ -2694,7 +2894,7 @@ const queuePendingInAppToasts = (pendingInAppToastItems, items, userId, appName)
2694
2894
  flushPendingInAppToasts(pendingInAppToastItems, userId, appName);
2695
2895
  };
2696
2896
  function NotificationsRealtimeProvider(t0) {
2697
- const $ = c(63);
2897
+ const $ = c(64);
2698
2898
  const {
2699
2899
  userId,
2700
2900
  appName,
@@ -3078,15 +3278,25 @@ function NotificationsRealtimeProvider(t0) {
3078
3278
  const value = t25;
3079
3279
  const t26 = canUseRts ? value : null;
3080
3280
  let t27;
3081
- if ($[60] !== children || $[61] !== t26) {
3082
- t27 = /* @__PURE__ */ jsx(NotificationsRealtimeContext.Provider, { value: t26, children });
3083
- $[60] = children;
3084
- $[61] = t26;
3085
- $[62] = t27;
3281
+ if ($[60] === /* @__PURE__ */ Symbol.for("react.memo_cache_sentinel")) {
3282
+ t27 = /* @__PURE__ */ jsx("style", { children: notificationToastStyles });
3283
+ $[60] = t27;
3284
+ } else {
3285
+ t27 = $[60];
3286
+ }
3287
+ let t28;
3288
+ if ($[61] !== children || $[62] !== t26) {
3289
+ t28 = /* @__PURE__ */ jsxs(NotificationsRealtimeContext.Provider, { value: t26, children: [
3290
+ t27,
3291
+ children
3292
+ ] });
3293
+ $[61] = children;
3294
+ $[62] = t26;
3295
+ $[63] = t28;
3086
3296
  } else {
3087
- t27 = $[62];
3297
+ t28 = $[63];
3088
3298
  }
3089
- return t27;
3299
+ return t28;
3090
3300
  }
3091
3301
  function _temp5(n_2) {
3092
3302
  return n_2.id;