@burn0/burn0 0.2.6 → 0.2.7

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.
@@ -446,6 +446,7 @@ import fs from "fs";
446
446
  import path from "path";
447
447
  var BURN0_DIR = ".burn0";
448
448
  var LEDGER_FILE = "costs.jsonl";
449
+ var SYNC_MARKER_FILE = "last-sync.txt";
449
450
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
450
451
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
451
452
  var LocalLedger = class {
@@ -469,6 +470,24 @@ var LocalLedger = class {
469
470
  return [];
470
471
  }
471
472
  }
473
+ readUnsynced() {
474
+ const all = this.read();
475
+ const lastSync = this.getLastSyncTime();
476
+ if (!lastSync) return all;
477
+ return all.filter((e) => new Date(e.timestamp).getTime() > lastSync);
478
+ }
479
+ markSynced() {
480
+ this.ensureDir();
481
+ fs.writeFileSync(path.join(this.dirPath, SYNC_MARKER_FILE), (/* @__PURE__ */ new Date()).toISOString());
482
+ }
483
+ getLastSyncTime() {
484
+ try {
485
+ const ts = fs.readFileSync(path.join(this.dirPath, SYNC_MARKER_FILE), "utf-8").trim();
486
+ return new Date(ts).getTime();
487
+ } catch {
488
+ return null;
489
+ }
490
+ }
472
491
  ensureDir() {
473
492
  if (!fs.existsSync(this.dirPath)) fs.mkdirSync(this.dirPath, { recursive: true });
474
493
  }
@@ -782,13 +801,21 @@ try {
782
801
  var ticker = createTicker({ todayCost, todayCalls, perServiceCosts });
783
802
  var batch = null;
784
803
  var lateInitDone = false;
804
+ var failedEvents = [];
785
805
  function createBatch(key) {
786
806
  return new BatchBuffer({
787
807
  sizeThreshold: 50,
788
808
  timeThresholdMs: 1e4,
789
809
  maxSize: 500,
790
810
  onFlush: (events) => {
791
- shipEvents(events, key, BURN0_API_URL, originalFetch2).catch(() => {
811
+ const toShip = failedEvents.length > 0 ? [...failedEvents, ...events] : events;
812
+ failedEvents = [];
813
+ shipEvents(toShip, key, BURN0_API_URL, originalFetch2).then((ok) => {
814
+ if (!ok) {
815
+ failedEvents = toShip.slice(-500);
816
+ }
817
+ }).catch(() => {
818
+ failedEvents = toShip.slice(-500);
792
819
  });
793
820
  }
794
821
  });
@@ -828,6 +855,28 @@ function lateInit(event) {
828
855
  batch.add(e);
829
856
  }
830
857
  pendingEvents.length = 0;
858
+ syncLedger(lateKey);
859
+ }
860
+ function syncLedger(key) {
861
+ try {
862
+ const unsynced = ledger.readUnsynced();
863
+ if (unsynced.length === 0) {
864
+ ledger.markSynced();
865
+ return;
866
+ }
867
+ const promises = [];
868
+ for (let i = 0; i < unsynced.length; i += 500) {
869
+ const chunk = unsynced.slice(i, i + 500);
870
+ promises.push(shipEvents(chunk, key, BURN0_API_URL, originalFetch2));
871
+ }
872
+ Promise.all(promises).then((results) => {
873
+ if (results.every(Boolean)) {
874
+ ledger.markSynced();
875
+ }
876
+ }).catch(() => {
877
+ });
878
+ } catch {
879
+ }
831
880
  }
832
881
  var shouldWriteLedger = mode !== "test-disabled" && mode !== "prod-local";
833
882
  var dispatch = createDispatcher(mode, {
@@ -870,4 +919,4 @@ export {
870
919
  startSpan,
871
920
  restore
872
921
  };
873
- //# sourceMappingURL=chunk-PPEPVHNM.mjs.map
922
+ //# sourceMappingURL=chunk-UI6QVWA4.mjs.map
package/dist/cli/index.js CHANGED
@@ -18350,7 +18350,7 @@ var init_connect = __esm({
18350
18350
  });
18351
18351
 
18352
18352
  // src/transport/local.ts
18353
- var import_node_fs6, import_node_path7, BURN0_DIR, LEDGER_FILE, MAX_FILE_SIZE, MAX_AGE_MS, LocalLedger;
18353
+ var import_node_fs6, import_node_path7, BURN0_DIR, LEDGER_FILE, SYNC_MARKER_FILE, MAX_FILE_SIZE, MAX_AGE_MS, LocalLedger;
18354
18354
  var init_local = __esm({
18355
18355
  "src/transport/local.ts"() {
18356
18356
  "use strict";
@@ -18358,6 +18358,7 @@ var init_local = __esm({
18358
18358
  import_node_path7 = __toESM(require("path"));
18359
18359
  BURN0_DIR = ".burn0";
18360
18360
  LEDGER_FILE = "costs.jsonl";
18361
+ SYNC_MARKER_FILE = "last-sync.txt";
18361
18362
  MAX_FILE_SIZE = 10 * 1024 * 1024;
18362
18363
  MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
18363
18364
  LocalLedger = class {
@@ -18381,6 +18382,24 @@ var init_local = __esm({
18381
18382
  return [];
18382
18383
  }
18383
18384
  }
18385
+ readUnsynced() {
18386
+ const all = this.read();
18387
+ const lastSync = this.getLastSyncTime();
18388
+ if (!lastSync) return all;
18389
+ return all.filter((e) => new Date(e.timestamp).getTime() > lastSync);
18390
+ }
18391
+ markSynced() {
18392
+ this.ensureDir();
18393
+ import_node_fs6.default.writeFileSync(import_node_path7.default.join(this.dirPath, SYNC_MARKER_FILE), (/* @__PURE__ */ new Date()).toISOString());
18394
+ }
18395
+ getLastSyncTime() {
18396
+ try {
18397
+ const ts = import_node_fs6.default.readFileSync(import_node_path7.default.join(this.dirPath, SYNC_MARKER_FILE), "utf-8").trim();
18398
+ return new Date(ts).getTime();
18399
+ } catch {
18400
+ return null;
18401
+ }
18402
+ }
18384
18403
  ensureDir() {
18385
18404
  if (!import_node_fs6.default.existsSync(this.dirPath)) import_node_fs6.default.mkdirSync(this.dirPath, { recursive: true });
18386
18405
  }
package/dist/index.js CHANGED
@@ -507,6 +507,7 @@ var import_node_fs = __toESM(require("fs"));
507
507
  var import_node_path = __toESM(require("path"));
508
508
  var BURN0_DIR = ".burn0";
509
509
  var LEDGER_FILE = "costs.jsonl";
510
+ var SYNC_MARKER_FILE = "last-sync.txt";
510
511
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
511
512
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
512
513
  var LocalLedger = class {
@@ -530,6 +531,24 @@ var LocalLedger = class {
530
531
  return [];
531
532
  }
532
533
  }
534
+ readUnsynced() {
535
+ const all = this.read();
536
+ const lastSync = this.getLastSyncTime();
537
+ if (!lastSync) return all;
538
+ return all.filter((e) => new Date(e.timestamp).getTime() > lastSync);
539
+ }
540
+ markSynced() {
541
+ this.ensureDir();
542
+ import_node_fs.default.writeFileSync(import_node_path.default.join(this.dirPath, SYNC_MARKER_FILE), (/* @__PURE__ */ new Date()).toISOString());
543
+ }
544
+ getLastSyncTime() {
545
+ try {
546
+ const ts = import_node_fs.default.readFileSync(import_node_path.default.join(this.dirPath, SYNC_MARKER_FILE), "utf-8").trim();
547
+ return new Date(ts).getTime();
548
+ } catch {
549
+ return null;
550
+ }
551
+ }
533
552
  ensureDir() {
534
553
  if (!import_node_fs.default.existsSync(this.dirPath)) import_node_fs.default.mkdirSync(this.dirPath, { recursive: true });
535
554
  }
@@ -843,13 +862,21 @@ try {
843
862
  var ticker = createTicker({ todayCost, todayCalls, perServiceCosts });
844
863
  var batch = null;
845
864
  var lateInitDone = false;
865
+ var failedEvents = [];
846
866
  function createBatch(key) {
847
867
  return new BatchBuffer({
848
868
  sizeThreshold: 50,
849
869
  timeThresholdMs: 1e4,
850
870
  maxSize: 500,
851
871
  onFlush: (events) => {
852
- shipEvents(events, key, BURN0_API_URL, originalFetch2).catch(() => {
872
+ const toShip = failedEvents.length > 0 ? [...failedEvents, ...events] : events;
873
+ failedEvents = [];
874
+ shipEvents(toShip, key, BURN0_API_URL, originalFetch2).then((ok) => {
875
+ if (!ok) {
876
+ failedEvents = toShip.slice(-500);
877
+ }
878
+ }).catch(() => {
879
+ failedEvents = toShip.slice(-500);
853
880
  });
854
881
  }
855
882
  });
@@ -889,6 +916,28 @@ function lateInit(event) {
889
916
  batch.add(e);
890
917
  }
891
918
  pendingEvents.length = 0;
919
+ syncLedger(lateKey);
920
+ }
921
+ function syncLedger(key) {
922
+ try {
923
+ const unsynced = ledger.readUnsynced();
924
+ if (unsynced.length === 0) {
925
+ ledger.markSynced();
926
+ return;
927
+ }
928
+ const promises = [];
929
+ for (let i = 0; i < unsynced.length; i += 500) {
930
+ const chunk = unsynced.slice(i, i + 500);
931
+ promises.push(shipEvents(chunk, key, BURN0_API_URL, originalFetch2));
932
+ }
933
+ Promise.all(promises).then((results) => {
934
+ if (results.every(Boolean)) {
935
+ ledger.markSynced();
936
+ }
937
+ }).catch(() => {
938
+ });
939
+ } catch {
940
+ }
892
941
  }
893
942
  var shouldWriteLedger = mode !== "test-disabled" && mode !== "prod-local";
894
943
  var dispatch = createDispatcher(mode, {
package/dist/index.mjs CHANGED
@@ -2,7 +2,7 @@ import {
2
2
  restore,
3
3
  startSpan,
4
4
  track
5
- } from "./chunk-PPEPVHNM.mjs";
5
+ } from "./chunk-UI6QVWA4.mjs";
6
6
  import "./chunk-DJ72YN4C.mjs";
7
7
  export {
8
8
  restore,
package/dist/register.js CHANGED
@@ -493,6 +493,7 @@ var import_node_fs = __toESM(require("fs"));
493
493
  var import_node_path = __toESM(require("path"));
494
494
  var BURN0_DIR = ".burn0";
495
495
  var LEDGER_FILE = "costs.jsonl";
496
+ var SYNC_MARKER_FILE = "last-sync.txt";
496
497
  var MAX_FILE_SIZE = 10 * 1024 * 1024;
497
498
  var MAX_AGE_MS = 7 * 24 * 60 * 60 * 1e3;
498
499
  var LocalLedger = class {
@@ -516,6 +517,24 @@ var LocalLedger = class {
516
517
  return [];
517
518
  }
518
519
  }
520
+ readUnsynced() {
521
+ const all = this.read();
522
+ const lastSync = this.getLastSyncTime();
523
+ if (!lastSync) return all;
524
+ return all.filter((e) => new Date(e.timestamp).getTime() > lastSync);
525
+ }
526
+ markSynced() {
527
+ this.ensureDir();
528
+ import_node_fs.default.writeFileSync(import_node_path.default.join(this.dirPath, SYNC_MARKER_FILE), (/* @__PURE__ */ new Date()).toISOString());
529
+ }
530
+ getLastSyncTime() {
531
+ try {
532
+ const ts = import_node_fs.default.readFileSync(import_node_path.default.join(this.dirPath, SYNC_MARKER_FILE), "utf-8").trim();
533
+ return new Date(ts).getTime();
534
+ } catch {
535
+ return null;
536
+ }
537
+ }
519
538
  ensureDir() {
520
539
  if (!import_node_fs.default.existsSync(this.dirPath)) import_node_fs.default.mkdirSync(this.dirPath, { recursive: true });
521
540
  }
@@ -829,13 +848,21 @@ try {
829
848
  var ticker = createTicker({ todayCost, todayCalls, perServiceCosts });
830
849
  var batch = null;
831
850
  var lateInitDone = false;
851
+ var failedEvents = [];
832
852
  function createBatch(key) {
833
853
  return new BatchBuffer({
834
854
  sizeThreshold: 50,
835
855
  timeThresholdMs: 1e4,
836
856
  maxSize: 500,
837
857
  onFlush: (events) => {
838
- shipEvents(events, key, BURN0_API_URL, originalFetch2).catch(() => {
858
+ const toShip = failedEvents.length > 0 ? [...failedEvents, ...events] : events;
859
+ failedEvents = [];
860
+ shipEvents(toShip, key, BURN0_API_URL, originalFetch2).then((ok) => {
861
+ if (!ok) {
862
+ failedEvents = toShip.slice(-500);
863
+ }
864
+ }).catch(() => {
865
+ failedEvents = toShip.slice(-500);
839
866
  });
840
867
  }
841
868
  });
@@ -875,6 +902,28 @@ function lateInit(event) {
875
902
  batch.add(e);
876
903
  }
877
904
  pendingEvents.length = 0;
905
+ syncLedger(lateKey);
906
+ }
907
+ function syncLedger(key) {
908
+ try {
909
+ const unsynced = ledger.readUnsynced();
910
+ if (unsynced.length === 0) {
911
+ ledger.markSynced();
912
+ return;
913
+ }
914
+ const promises = [];
915
+ for (let i = 0; i < unsynced.length; i += 500) {
916
+ const chunk = unsynced.slice(i, i + 500);
917
+ promises.push(shipEvents(chunk, key, BURN0_API_URL, originalFetch2));
918
+ }
919
+ Promise.all(promises).then((results) => {
920
+ if (results.every(Boolean)) {
921
+ ledger.markSynced();
922
+ }
923
+ }).catch(() => {
924
+ });
925
+ } catch {
926
+ }
878
927
  }
879
928
  var shouldWriteLedger = mode !== "test-disabled" && mode !== "prod-local";
880
929
  var dispatch = createDispatcher(mode, {
package/dist/register.mjs CHANGED
@@ -1,3 +1,3 @@
1
- import "./chunk-PPEPVHNM.mjs";
1
+ import "./chunk-UI6QVWA4.mjs";
2
2
  import "./chunk-DJ72YN4C.mjs";
3
3
  //# sourceMappingURL=register.mjs.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@burn0/burn0",
3
- "version": "0.2.6",
3
+ "version": "0.2.7",
4
4
  "description": "Lightweight cost observability for every API call in your stack",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",