jiren 1.3.0 → 1.3.1

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.
@@ -183,7 +183,7 @@ export class JirenClient<
183
183
  if (cacheConfig?.enabled) {
184
184
  const cached = self.cache.get(baseUrl, options?.path, options);
185
185
  if (cached) {
186
- return cached as any;
186
+ return self.rehydrateResponse(cached);
187
187
  }
188
188
  }
189
189
 
@@ -538,18 +538,6 @@ export class JirenClient<
538
538
  // Handle GZIP compression
539
539
  const contentEncoding = headersProxy["content-encoding"]?.toLowerCase();
540
540
 
541
- // DEBUG LOGS
542
- if (len > 0) {
543
- console.log(`[Jiren] Body len: ${len}, Encoding: ${contentEncoding}`);
544
- if (buffer.length > 2) {
545
- console.log(
546
- `[Jiren] Bytes: 0x${buffer[0]?.toString(
547
- 16
548
- )} 0x${buffer[1]?.toString(16)} 0x${buffer[2]?.toString(16)}`
549
- );
550
- }
551
- }
552
-
553
541
  if (
554
542
  contentEncoding === "gzip" ||
555
543
  (buffer.length > 2 && buffer[0] === 0x1f && buffer[1] === 0x8b)
@@ -564,13 +552,22 @@ export class JirenClient<
564
552
  }
565
553
  }
566
554
 
555
+ // Convert to base64 for caching persistence
556
+ let base64Data = "";
557
+ try {
558
+ base64Data = buffer.toString("base64");
559
+ } catch (e) {
560
+ // Should not happen
561
+ }
562
+
567
563
  let bodyUsed = false;
568
564
  const consumeBody = () => {
569
565
  bodyUsed = true;
570
566
  };
571
567
 
572
- const bodyObj: JirenResponseBody<T> = {
568
+ const bodyObj: JirenResponseBody<T> & { _raw?: string } = {
573
569
  bodyUsed: false,
570
+ _raw: base64Data,
574
571
  arrayBuffer: async () => {
575
572
  consumeBody();
576
573
  return buffer.buffer.slice(
@@ -610,6 +607,63 @@ export class JirenClient<
610
607
  lib.symbols.zclient_response_free(respPtr);
611
608
  }
612
609
  }
610
+
611
+ /**
612
+ * Rehydrates a cached response object by restoring the body interface methods.
613
+ * This is necessary because JSON serialization strips functions.
614
+ */
615
+ private rehydrateResponse(cached: any): JirenResponse {
616
+ // If it already has methods, return as is
617
+ if (typeof cached.body.text === "function") return cached;
618
+
619
+ // Retrieve raw data
620
+ const rawData = cached.body._raw;
621
+ let buffer: Buffer;
622
+
623
+ if (rawData) {
624
+ buffer = Buffer.from(rawData, "base64");
625
+ } else {
626
+ buffer = Buffer.from("");
627
+ }
628
+
629
+ let bodyUsed = cached.body.bodyUsed || false;
630
+ const consumeBody = () => {
631
+ bodyUsed = true;
632
+ };
633
+
634
+ const bodyObj: JirenResponseBody = {
635
+ _raw: rawData, // Keep it for re-caching if needed
636
+ bodyUsed,
637
+ arrayBuffer: async () => {
638
+ consumeBody();
639
+ return buffer.buffer.slice(
640
+ buffer.byteOffset,
641
+ buffer.byteOffset + buffer.byteLength
642
+ ) as ArrayBuffer;
643
+ },
644
+ blob: async () => {
645
+ consumeBody();
646
+ return new Blob([buffer as any]);
647
+ },
648
+ text: async () => {
649
+ consumeBody();
650
+ return buffer.toString("utf-8");
651
+ },
652
+ json: async <R = any>(): Promise<R> => {
653
+ consumeBody();
654
+ return JSON.parse(buffer.toString("utf-8"));
655
+ },
656
+ } as any;
657
+
658
+ Object.defineProperty(bodyObj, "bodyUsed", {
659
+ get: () => bodyUsed,
660
+ });
661
+
662
+ return {
663
+ ...cached,
664
+ body: bodyObj,
665
+ };
666
+ }
613
667
  }
614
668
 
615
669
  class NativeHeaders {
@@ -220,7 +220,7 @@ export class JirenClient<
220
220
  // Try to get from cache
221
221
  const cached = self.cache.get(baseUrl, options?.path, options);
222
222
  if (cached) {
223
- return cached as any;
223
+ return self.rehydrateResponse(cached);
224
224
  }
225
225
  }
226
226
 
@@ -699,6 +699,14 @@ export class JirenClient<
699
699
  buffer = toArrayBuffer(bodyPtr, 0, len).slice(0);
700
700
  }
701
701
 
702
+ // Convert to base64 for caching persistence
703
+ let base64Data = "";
704
+ try {
705
+ base64Data = Buffer.from(buffer).toString("base64");
706
+ } catch (e) {
707
+ // Should not happen for valid buffer
708
+ }
709
+
702
710
  let bodyUsed = false;
703
711
  const consumeBody = () => {
704
712
  if (bodyUsed) {
@@ -706,8 +714,9 @@ export class JirenClient<
706
714
  bodyUsed = true;
707
715
  };
708
716
 
709
- const bodyObj: JirenResponseBody<T> = {
717
+ const bodyObj: JirenResponseBody<T> & { _raw?: string } = {
710
718
  bodyUsed: false,
719
+ _raw: base64Data,
711
720
  arrayBuffer: async () => {
712
721
  consumeBody();
713
722
  if (Buffer.isBuffer(buffer)) {
@@ -782,6 +791,64 @@ export class JirenClient<
782
791
 
783
792
  return { headers, serializedBody };
784
793
  }
794
+
795
+ /**
796
+ * Rehydrates a cached response object by restoring the body interface methods.
797
+ * This is necessary because JSON serialization strips functions.
798
+ */
799
+ private rehydrateResponse(cached: any): JirenResponse {
800
+ // If it already has methods, return as is
801
+ if (typeof cached.body.text === "function") return cached;
802
+
803
+ // Retrieve raw data
804
+ const rawData = cached.body._raw;
805
+ let buffer: Buffer;
806
+
807
+ if (rawData) {
808
+ buffer = Buffer.from(rawData, "base64");
809
+ } else {
810
+ buffer = Buffer.from("");
811
+ }
812
+
813
+ let bodyUsed = cached.body.bodyUsed || false;
814
+ const consumeBody = () => {
815
+ bodyUsed = true;
816
+ };
817
+
818
+ const bodyObj: JirenResponseBody = {
819
+ _raw: rawData, // Keep it for re-caching if needed
820
+ bodyUsed,
821
+ arrayBuffer: async () => {
822
+ consumeBody();
823
+ return buffer.buffer.slice(
824
+ buffer.byteOffset,
825
+ buffer.byteOffset + buffer.byteLength
826
+ ) as ArrayBuffer;
827
+ },
828
+ blob: async () => {
829
+ consumeBody();
830
+ return new Blob([buffer]);
831
+ },
832
+ text: async () => {
833
+ consumeBody();
834
+ return new TextDecoder().decode(buffer);
835
+ },
836
+ json: async <R = any>(): Promise<R> => {
837
+ consumeBody();
838
+ const text = new TextDecoder().decode(buffer);
839
+ return JSON.parse(text);
840
+ },
841
+ } as any;
842
+
843
+ Object.defineProperty(bodyObj, "bodyUsed", {
844
+ get: () => bodyUsed,
845
+ });
846
+
847
+ return {
848
+ ...cached,
849
+ body: bodyObj,
850
+ };
851
+ }
785
852
  }
786
853
 
787
854
  class NativeHeaders {