@emeryld/rrroutes-client 2.1.0 → 2.1.2

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.cjs CHANGED
@@ -35,7 +35,9 @@ __export(index_exports, {
35
35
  buildRoomPayloadSchema: () => buildRoomPayloadSchema,
36
36
  buildSocketProvider: () => buildSocketProvider,
37
37
  createRouteClient: () => createRouteClient,
38
- defaultFetcher: () => defaultFetcher
38
+ defaultFetcher: () => defaultFetcher,
39
+ useSocketClient: () => useSocketClient,
40
+ useSocketConnection: () => useSocketConnection
39
41
  });
40
42
  module.exports = __toCommonJS(index_exports);
41
43
 
@@ -473,7 +475,6 @@ var buildRoomPayloadSchema = (metaSchema) => import_zod.z.object({
473
475
 
474
476
  // src/sockets/socket.client.context.tsx
475
477
  var React = __toESM(require("react"), 1);
476
- var import_socket = require("socket.io-client");
477
478
  var import_jsx_runtime = require("react/jsx-runtime");
478
479
  var SocketCtx = React.createContext(null);
479
480
  function dbg(dbgOpts, e) {
@@ -481,16 +482,31 @@ function dbg(dbgOpts, e) {
481
482
  if (!dbgOpts[e.type]) return;
482
483
  dbgOpts.logger(e);
483
484
  }
485
+ function isProbablySocket(value) {
486
+ if (!value || typeof value !== "object") return false;
487
+ const anyVal = value;
488
+ const ctorName = anyVal.constructor?.name;
489
+ if (ctorName === "Socket") return true;
490
+ return ("connected" in anyVal || "recovered" in anyVal) && typeof anyVal.on === "function" && typeof anyVal.emit === "function";
491
+ }
492
+ function describeSocketLike(value) {
493
+ if (!value) return null;
494
+ const id = value.id ?? "unknown";
495
+ const connected = value.connected ?? false;
496
+ const recovered = typeof value.recovered === "boolean" ? ` recovered=${value.recovered}` : "";
497
+ return `[Socket id=${id} connected=${connected}${recovered}]`;
498
+ }
484
499
  function safeDescribeHookValue(value) {
485
500
  if (value == null) return value;
486
501
  const valueType = typeof value;
487
- if (valueType === "string" || valueType === "number" || valueType === "boolean") return value;
502
+ if (valueType === "string" || valueType === "number" || valueType === "boolean") {
503
+ return value;
504
+ }
488
505
  if (valueType === "bigint" || valueType === "symbol") return String(value);
489
506
  if (valueType === "function") return `[function ${value.name || "anonymous"}]`;
490
507
  if (Array.isArray(value)) return `[array length=${value.length}]`;
491
- if (value instanceof import_socket.Socket) {
492
- const socket = value;
493
- return `[Socket id=${socket.id ?? "unknown"} connected=${socket.connected ?? false}]`;
508
+ if (isProbablySocket(value)) {
509
+ return describeSocketLike(value);
494
510
  }
495
511
  const ctorName = value.constructor?.name ?? "object";
496
512
  const keys = Object.keys(value);
@@ -498,20 +514,56 @@ function safeDescribeHookValue(value) {
498
514
  const suffix = keys.length > 4 ? ",\u2026" : "";
499
515
  return `[${ctorName} keys=${keyPreview}${suffix}]`;
500
516
  }
517
+ function summarizeEvents(events) {
518
+ if (!events || typeof events !== "object") return safeDescribeHookValue(events);
519
+ const keys = Object.keys(events);
520
+ if (!keys.length) return "[events empty]";
521
+ const preview = keys.slice(0, 4).join(",");
522
+ const suffix = keys.length > 4 ? ",\u2026" : "";
523
+ return `[events count=${keys.length} keys=${preview}${suffix}]`;
524
+ }
525
+ function summarizeBaseOptions(options) {
526
+ if (!options || typeof options !== "object") return safeDescribeHookValue(options);
527
+ const obj = options;
528
+ const keys = Object.keys(obj);
529
+ if (!keys.length) return "[baseOptions empty]";
530
+ const preview = keys.slice(0, 4).join(",");
531
+ const suffix = keys.length > 4 ? ",\u2026" : "";
532
+ const hasDebug = "debug" in obj;
533
+ return `[baseOptions keys=${preview}${suffix} debug=${hasDebug}]`;
534
+ }
535
+ function summarizeMeta(meta, label) {
536
+ if (meta == null) return null;
537
+ if (typeof meta !== "object") return safeDescribeHookValue(meta);
538
+ const keys = Object.keys(meta);
539
+ if (!keys.length) return `[${label} empty]`;
540
+ const preview = keys.slice(0, 4).join(",");
541
+ const suffix = keys.length > 4 ? ",\u2026" : "";
542
+ return `[${label} keys=${preview}${suffix}]`;
543
+ }
501
544
  function createHookDebugEvent(prev, next, hook) {
502
545
  const reason = prev ? "change" : "init";
503
546
  const changed = Object.keys(next).reduce((acc, dependency) => {
504
547
  const prevValue = prev ? prev[dependency] : void 0;
505
548
  const nextValue = next[dependency];
506
549
  if (!prev || !Object.is(prevValue, nextValue)) {
507
- acc.push({ dependency, previous: safeDescribeHookValue(prevValue), next: safeDescribeHookValue(nextValue) });
550
+ acc.push({
551
+ dependency,
552
+ previous: safeDescribeHookValue(prevValue),
553
+ next: safeDescribeHookValue(nextValue)
554
+ });
508
555
  }
509
556
  return acc;
510
557
  }, []);
511
558
  if (!changed.length) return null;
512
559
  return { type: "hook", hook, reason, changes: changed };
513
560
  }
514
- function trackHookTrigger({ ref, hook, providerDebug, snapshot }) {
561
+ function trackHookTrigger({
562
+ ref,
563
+ hook,
564
+ providerDebug,
565
+ snapshot
566
+ }) {
515
567
  const prev = ref.current;
516
568
  ref.current = snapshot;
517
569
  if (!providerDebug?.logger || !providerDebug?.hook) return;
@@ -526,6 +578,7 @@ function buildSocketProvider(args) {
526
578
  {
527
579
  events,
528
580
  baseOptions,
581
+ providerDebug: baseOptions.debug,
529
582
  ...props
530
583
  }
531
584
  ),
@@ -547,7 +600,9 @@ function SocketProvider(props) {
547
600
  ref: resolveEffectDebugRef,
548
601
  hook: "resolve_effect",
549
602
  providerDebug: providerDebugRef.current,
550
- snapshot: { resolvedSocket }
603
+ snapshot: {
604
+ resolvedSocket: describeSocketLike(resolvedSocket)
605
+ }
551
606
  });
552
607
  if (!("getSocket" in props)) return;
553
608
  let cancelled = false;
@@ -559,7 +614,7 @@ function SocketProvider(props) {
559
614
  return;
560
615
  }
561
616
  if (!s) {
562
- dbg(providerDebugRef.current, { type: "resolve", phase: "missing" });
617
+ dbg(providerDebugRef.current, { type: "resolve", phase: "socketMissing" });
563
618
  return;
564
619
  }
565
620
  setResolvedSocket(s);
@@ -577,7 +632,11 @@ function SocketProvider(props) {
577
632
  ref: clientMemoDebugRef,
578
633
  hook: "client_memo",
579
634
  providerDebug: providerDebugRef.current,
580
- snapshot: { events, baseOptions, socket }
635
+ snapshot: {
636
+ events: summarizeEvents(events),
637
+ baseOptions: summarizeBaseOptions(baseOptions),
638
+ socket: describeSocketLike(socket)
639
+ }
581
640
  });
582
641
  const client = React.useMemo(() => {
583
642
  if (!socket) {
@@ -593,7 +652,10 @@ function SocketProvider(props) {
593
652
  ref: destroyEffectDebugRef,
594
653
  hook: "destroy_effect",
595
654
  providerDebug: providerDebugRef.current,
596
- snapshot: { client, destroyLeaveMeta }
655
+ snapshot: {
656
+ hasClient: !!client,
657
+ destroyLeaveMeta: summarizeMeta(destroyLeaveMeta, "destroyLeaveMeta")
658
+ }
597
659
  });
598
660
  return () => {
599
661
  if (client) {
@@ -658,23 +720,20 @@ var SocketClient = class {
658
720
  this.dbg({
659
721
  type: "lifecycle",
660
722
  phase: "init",
661
- socketId: this.socket.id,
662
- details: {
663
- heartbeatIntervalMs: this.hb.intervalMs,
664
- heartbeatTimeoutMs: this.hb.timeoutMs,
665
- environment: this.environment
666
- }
723
+ heartbeatIntervalMs: this.hb.intervalMs,
724
+ heartbeatTimeoutMs: this.hb.timeoutMs,
725
+ environment: this.environment
667
726
  });
668
727
  this.logSocketConfigSnapshot("constructor");
669
728
  }
670
729
  this.onConnect = () => {
671
730
  if (!this.socket) {
672
- this.dbg({ type: "connection", phase: "connect", err: "Socket is null" });
731
+ this.dbg({ type: "connection", phase: "connect_event", err: "Socket is null" });
673
732
  throw new Error("Socket is null in onConnect handler");
674
733
  }
675
734
  this.dbg({
676
735
  type: "connection",
677
- phase: "connect",
736
+ phase: "connect_event",
678
737
  id: this.socket.id,
679
738
  details: {
680
739
  nsp: this.getNamespace(this.socket)
@@ -688,12 +747,12 @@ var SocketClient = class {
688
747
  };
689
748
  this.onReconnect = (attempt) => {
690
749
  if (!this.socket) {
691
- this.dbg({ type: "connection", phase: "reconnect", err: "Socket is null" });
750
+ this.dbg({ type: "connection", phase: "reconnect_event", err: "Socket is null" });
692
751
  throw new Error("Socket is null in onReconnect handler");
693
752
  }
694
753
  this.dbg({
695
754
  type: "connection",
696
- phase: "reconnect",
755
+ phase: "reconnect_event",
697
756
  attempt,
698
757
  id: this.socket.id,
699
758
  details: {
@@ -709,12 +768,12 @@ var SocketClient = class {
709
768
  };
710
769
  this.onDisconnect = (reason) => {
711
770
  if (!this.socket) {
712
- this.dbg({ type: "connection", phase: "disconnect", err: "Socket is null" });
771
+ this.dbg({ type: "connection", phase: "disconnect_event", err: "Socket is null" });
713
772
  throw new Error("Socket is null in onDisconnect handler");
714
773
  }
715
774
  this.dbg({
716
775
  type: "connection",
717
- phase: "disconnect",
776
+ phase: "disconnect_event",
718
777
  reason: String(reason),
719
778
  details: {
720
779
  roomsTracked: this.roomCounts.size
@@ -729,12 +788,12 @@ var SocketClient = class {
729
788
  };
730
789
  this.onConnectError = (err) => {
731
790
  if (!this.socket) {
732
- this.dbg({ type: "connection", phase: "connect_error", err: "Socket is null" });
791
+ this.dbg({ type: "connection", phase: "connect_error_event", err: "Socket is null" });
733
792
  throw new Error("Socket is null in onConnectError handler");
734
793
  }
735
794
  this.dbg({
736
795
  type: "connection",
737
- phase: "connect_error",
796
+ phase: "connect_error_event",
738
797
  err: String(err),
739
798
  details: this.getVerboseDetails({ rawError: err })
740
799
  });
@@ -883,7 +942,7 @@ var SocketClient = class {
883
942
  * call it yourself from any sysHandler to change when heartbeats start.
884
943
  */
885
944
  startHeartbeat() {
886
- this.stopHeartbeat();
945
+ this.stopHeartbeat("stop_before_start");
887
946
  if (!this.socket) {
888
947
  this.dbg({
889
948
  type: "heartbeat",
@@ -944,7 +1003,7 @@ var SocketClient = class {
944
1003
  * This is called by the default 'sys:disconnect' handler, but you can also
945
1004
  * call it yourself from any sysHandler to fully control heartbeat lifecycle.
946
1005
  */
947
- stopHeartbeat() {
1006
+ stopHeartbeat(reason) {
948
1007
  const hadTimer = Boolean(this.hbTimer);
949
1008
  if (this.hbTimer) {
950
1009
  clearInterval(this.hbTimer);
@@ -953,9 +1012,8 @@ var SocketClient = class {
953
1012
  this.dbg({
954
1013
  type: "heartbeat",
955
1014
  phase: "stop",
956
- details: {
957
- hadTimer
958
- }
1015
+ reason,
1016
+ hadTimer
959
1017
  });
960
1018
  }
961
1019
  emit(event, payload, metadata) {
@@ -1149,7 +1207,7 @@ var SocketClient = class {
1149
1207
  * Call when disposing the client instance.
1150
1208
  */
1151
1209
  destroy(leaveMeta) {
1152
- this.stopHeartbeat();
1210
+ this.stopHeartbeat("destroy");
1153
1211
  const socket = this.socket;
1154
1212
  this.dbg({
1155
1213
  type: "lifecycle",
@@ -1200,7 +1258,7 @@ var SocketClient = class {
1200
1258
  });
1201
1259
  return;
1202
1260
  }
1203
- this.stopHeartbeat();
1261
+ this.stopHeartbeat("disconnect");
1204
1262
  this.socket.disconnect();
1205
1263
  this.dbg({
1206
1264
  type: "connection",
@@ -1239,6 +1297,8 @@ var SocketClient = class {
1239
1297
  buildRoomPayloadSchema,
1240
1298
  buildSocketProvider,
1241
1299
  createRouteClient,
1242
- defaultFetcher
1300
+ defaultFetcher,
1301
+ useSocketClient,
1302
+ useSocketConnection
1243
1303
  });
1244
1304
  //# sourceMappingURL=index.cjs.map