@bitsocial/bitsocial-cli 0.19.86 → 0.19.87

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/README.md CHANGED
@@ -421,7 +421,7 @@ EXAMPLES
421
421
  $ bitsocial challenge install ./my-local-challenge
422
422
  ```
423
423
 
424
- _See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/challenge/install.ts)_
424
+ _See code: [src/cli/commands/challenge/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/challenge/install.ts)_
425
425
 
426
426
  ## `bitsocial challenge list`
427
427
 
@@ -447,7 +447,7 @@ EXAMPLES
447
447
  $ bitsocial challenge list -q
448
448
  ```
449
449
 
450
- _See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/challenge/list.ts)_
450
+ _See code: [src/cli/commands/challenge/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/challenge/list.ts)_
451
451
 
452
452
  ## `bitsocial challenge ls`
453
453
 
@@ -501,7 +501,7 @@ EXAMPLES
501
501
  $ bitsocial challenge remove @scope/my-challenge
502
502
  ```
503
503
 
504
- _See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/challenge/remove.ts)_
504
+ _See code: [src/cli/commands/challenge/remove.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/challenge/remove.ts)_
505
505
 
506
506
  ## `bitsocial challenge rm NAME`
507
507
 
@@ -615,7 +615,7 @@ EXAMPLES
615
615
  $ bitsocial community create --jsonFile ./create-options.json
616
616
  ```
617
617
 
618
- _See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/create.ts)_
618
+ _See code: [src/cli/commands/community/create.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/create.ts)_
619
619
 
620
620
  ## `bitsocial community delete ADDRESSES`
621
621
 
@@ -640,7 +640,7 @@ EXAMPLES
640
640
  $ bitsocial community delete 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
641
641
  ```
642
642
 
643
- _See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/delete.ts)_
643
+ _See code: [src/cli/commands/community/delete.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/delete.ts)_
644
644
 
645
645
  ## `bitsocial community edit ADDRESS`
646
646
 
@@ -710,7 +710,7 @@ EXAMPLES
710
710
  $ bitsocial community edit bitsocial.bso --jsonFile ./edit-options.json
711
711
  ```
712
712
 
713
- _See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/edit.ts)_
713
+ _See code: [src/cli/commands/community/edit.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/edit.ts)_
714
714
 
715
715
  ## `bitsocial community export [ADDRESS]`
716
716
 
@@ -751,7 +751,7 @@ EXAMPLES
751
751
  $ bitsocial community export --publicKey 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
752
752
  ```
753
753
 
754
- _See code: [src/cli/commands/community/export.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/export.ts)_
754
+ _See code: [src/cli/commands/community/export.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/export.ts)_
755
755
 
756
756
  ## `bitsocial community get [ADDRESS]`
757
757
 
@@ -782,7 +782,7 @@ EXAMPLES
782
782
  $ bitsocial community get --publicKey 12D3KooWG3XbzoVyAE6Y9vHZKF64Yuuu4TjdgQKedk14iYmTEPWu
783
783
  ```
784
784
 
785
- _See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/get.ts)_
785
+ _See code: [src/cli/commands/community/get.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/get.ts)_
786
786
 
787
787
  ## `bitsocial community list`
788
788
 
@@ -805,7 +805,7 @@ EXAMPLES
805
805
  $ bitsocial community list
806
806
  ```
807
807
 
808
- _See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/list.ts)_
808
+ _See code: [src/cli/commands/community/list.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/list.ts)_
809
809
 
810
810
  ## `bitsocial community start ADDRESSES`
811
811
 
@@ -839,7 +839,7 @@ EXAMPLES
839
839
  $ bitsocial community start $(bitsocial community list -q) --concurrency 1
840
840
  ```
841
841
 
842
- _See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/start.ts)_
842
+ _See code: [src/cli/commands/community/start.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/start.ts)_
843
843
 
844
844
  ## `bitsocial community stop ADDRESSES`
845
845
 
@@ -864,7 +864,7 @@ EXAMPLES
864
864
  $ bitsocial community stop Qmb99crTbSUfKXamXwZBe829Vf6w5w5TktPkb6WstC9RFW
865
865
  ```
866
866
 
867
- _See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/community/stop.ts)_
867
+ _See code: [src/cli/commands/community/stop.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/community/stop.ts)_
868
868
 
869
869
  ## `bitsocial daemon`
870
870
 
@@ -872,20 +872,24 @@ Run a network-connected Bitsocial node. Once the daemon is running you can creat
872
872
 
873
873
  ```
874
874
  USAGE
875
- $ bitsocial daemon --pkcRpcUrl <value> --logPath <value> [--chainProviderUrls <value>...]
876
- [--allowPrivateKeyExport]
875
+ $ bitsocial daemon --pkcRpcUrl <value> --logPath <value> [--chainProviderUrls <value>...] [--enableIpfsGc]
876
+ [--ipfsGcIntervalMinutes <value>] [--allowPrivateKeyExport]
877
877
 
878
878
  FLAGS
879
- --[no-]allowPrivateKeyExport Allow RPC clients to request community exports that include the community signer's
880
- private key (`bitsocial community export --includePrivateKey`). Disable with
881
- --no-allowPrivateKeyExport when exposing the RPC to untrusted clients
882
- --chainProviderUrls=<value>... [default:
883
- https://eth.drpc.org,https://ethereum.publicnode.com,https://ethereum-rpc.publicnode.c
884
- om,https://rpc.mevblocker.io,https://1rpc.io/eth,https://eth-pokt.nodies.app] RPC
885
- URL(s) for .bso name resolution. Can be specified multiple times.
886
- --logPath=<value> (required) [default: /home/runner/.local/state/bitsocial] Specify a directory which
887
- will be used to store logs
888
- --pkcRpcUrl=<value> (required) [default: ws://localhost:9138/] Specify PKC RPC URL to listen on
879
+ --[no-]allowPrivateKeyExport Allow RPC clients to request community exports that include the community signer's
880
+ private key (`bitsocial community export --includePrivateKey`). Disable with
881
+ --no-allowPrivateKeyExport when exposing the RPC to untrusted clients
882
+ --chainProviderUrls=<value>... [default:
883
+ https://eth.drpc.org,https://ethereum.publicnode.com,https://ethereum-rpc.publicnode.
884
+ com,https://rpc.mevblocker.io,https://1rpc.io/eth,https://eth-pokt.nodies.app] RPC
885
+ URL(s) for .bso name resolution. Can be specified multiple times.
886
+ --[no-]enableIpfsGc Periodically garbage-collect the IPFS repo over the kubo RPC API while the daemon is
887
+ up. Only reclaims unpinned blocks — pinned data and MFS are never collected. Disable
888
+ with --no-enableIpfsGc
889
+ --ipfsGcIntervalMinutes=<value> [default: 60] How often to garbage-collect the IPFS repo, in minutes
890
+ --logPath=<value> (required) [default: /home/runner/.local/state/bitsocial] Specify a directory which
891
+ will be used to store logs
892
+ --pkcRpcUrl=<value> (required) [default: ws://localhost:9138/] Specify PKC RPC URL to listen on
889
893
 
890
894
  DESCRIPTION
891
895
  Run a network-connected Bitsocial node. Once the daemon is running you can create and start your communities and
@@ -911,7 +915,7 @@ EXAMPLES
911
915
  $ bitsocial daemon --no-allowPrivateKeyExport
912
916
  ```
913
917
 
914
- _See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/daemon.ts)_
918
+ _See code: [src/cli/commands/daemon.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/daemon.ts)_
915
919
 
916
920
  ## `bitsocial help [COMMAND]`
917
921
 
@@ -977,7 +981,7 @@ EXAMPLES
977
981
  $ bitsocial logs --stdout -f
978
982
  ```
979
983
 
980
- _See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/logs.ts)_
984
+ _See code: [src/cli/commands/logs.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/logs.ts)_
981
985
 
982
986
  ## `bitsocial update check`
983
987
 
@@ -994,7 +998,7 @@ EXAMPLES
994
998
  $ bitsocial update check
995
999
  ```
996
1000
 
997
- _See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/update/check.ts)_
1001
+ _See code: [src/cli/commands/update/check.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/update/check.ts)_
998
1002
 
999
1003
  ## `bitsocial update install [VERSION]`
1000
1004
 
@@ -1026,7 +1030,7 @@ EXAMPLES
1026
1030
  $ bitsocial update install --no-restart-daemons
1027
1031
  ```
1028
1032
 
1029
- _See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/update/install.ts)_
1033
+ _See code: [src/cli/commands/update/install.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/update/install.ts)_
1030
1034
 
1031
1035
  ## `bitsocial update versions`
1032
1036
 
@@ -1048,7 +1052,7 @@ EXAMPLES
1048
1052
  $ bitsocial update versions --limit 5
1049
1053
  ```
1050
1054
 
1051
- _See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.86/src/cli/commands/update/versions.ts)_
1055
+ _See code: [src/cli/commands/update/versions.ts](https://github.com/bitsocialnet/bitsocial-cli/blob/v0.19.87/src/cli/commands/update/versions.ts)_
1052
1056
  <!-- commandsstop -->
1053
1057
 
1054
1058
  ## Contribution
@@ -26,6 +26,8 @@ export default class Daemon extends Command {
26
26
  pkcRpcUrl: import("@oclif/core/interfaces").OptionFlag<import("url").URL, import("@oclif/core/interfaces").CustomOptions>;
27
27
  logPath: import("@oclif/core/interfaces").OptionFlag<string, import("@oclif/core/interfaces").CustomOptions>;
28
28
  chainProviderUrls: import("@oclif/core/interfaces").OptionFlag<string[], import("@oclif/core/interfaces").CustomOptions>;
29
+ enableIpfsGc: import("@oclif/core/interfaces").BooleanFlag<boolean>;
30
+ ipfsGcIntervalMinutes: import("@oclif/core/interfaces").OptionFlag<number, import("@oclif/core/interfaces").CustomOptions>;
29
31
  allowPrivateKeyExport: import("@oclif/core/interfaces").BooleanFlag<boolean>;
30
32
  };
31
33
  static examples: string[];
@@ -1,6 +1,7 @@
1
1
  import { Flags, Command } from "@oclif/core";
2
2
  import defaults from "../../common-utils/defaults.js";
3
3
  import { startKuboNode } from "../../ipfs/startIpfs.js";
4
+ import { startRepoGcScheduler, DEFAULT_REPO_GC_INTERVAL_MS } from "../../ipfs/repoGc.js";
4
5
  import path from "path";
5
6
  import tcpPortUsed from "tcp-port-used";
6
7
  import { getLanIpV4Address, PKCLogger, setupDebugLogger, loadKuboConfigFile, parseMultiAddrKuboRpcToUrl, parseMultiAddrIpfsGatewayToUrl } from "../../util.js";
@@ -84,6 +85,16 @@ export default class Daemon extends Command {
84
85
  multiple: true,
85
86
  default: DEFAULT_PROVIDERS
86
87
  }),
88
+ enableIpfsGc: Flags.boolean({
89
+ description: "Periodically garbage-collect the IPFS repo over the kubo RPC API while the daemon is up. Only reclaims unpinned blocks — pinned data and MFS are never collected. Disable with --no-enableIpfsGc",
90
+ allowNo: true,
91
+ default: true
92
+ }),
93
+ ipfsGcIntervalMinutes: Flags.integer({
94
+ description: "How often to garbage-collect the IPFS repo, in minutes",
95
+ default: DEFAULT_REPO_GC_INTERVAL_MS / 60_000,
96
+ min: 1
97
+ }),
87
98
  allowPrivateKeyExport: Flags.boolean({
88
99
  description: "Allow RPC clients to request community exports that include the community signer's private key (`bitsocial community export --includePrivateKey`). Disable with --no-allowPrivateKeyExport when exposing the RPC to untrusted clients",
89
100
  allowNo: true,
@@ -465,6 +476,7 @@ export default class Daemon extends Command {
465
476
  }
466
477
  };
467
478
  let keepKuboUpInterval;
479
+ let stopRepoGcScheduler;
468
480
  const { asyncExitHook } = await import("exit-hook");
469
481
  const killKuboProcessGroup = (pid, signal) => {
470
482
  // Kill the entire process group (negative PID) on non-Windows.
@@ -546,6 +558,7 @@ export default class Daemon extends Command {
546
558
  const shutdownDaemon = async () => {
547
559
  if (keepKuboUpInterval)
548
560
  clearInterval(keepKuboUpInterval);
561
+ stopRepoGcScheduler?.();
549
562
  if (mainProcessExited)
550
563
  return; // we already exited
551
564
  console.log("\nShutting down Bitsocial daemon, it may take a few seconds to shut down all communities and the IPFS node...");
@@ -637,6 +650,16 @@ export default class Daemon extends Command {
637
650
  if (!pkcOptionsFromFlag?.kuboRpcClientsOptions)
638
651
  await keepKuboUp();
639
652
  await createOrConnectRpc();
653
+ // Runs against whichever kubo the daemon ends up talking to, including one started by
654
+ // another program (--pkcOptions.kuboRpcClientsOptions). pkc-js also GCs, but only from
655
+ // a started local community's IPNS sync — a daemon that is up with no community
656
+ // started would otherwise never reclaim anything (issue #119).
657
+ if (flags.enableIpfsGc)
658
+ stopRepoGcScheduler = startRepoGcScheduler({
659
+ kuboApiUrl: kuboRpcEndpoint,
660
+ intervalMs: flags.ipfsGcIntervalMinutes * 60 * 1000,
661
+ log: PKCLogger("bitsocial-cli:ipfs:repoGc")
662
+ });
640
663
  keepKuboUpInterval = setInterval(async () => {
641
664
  if (mainProcessExited)
642
665
  return;
@@ -0,0 +1,46 @@
1
+ export declare const DEFAULT_REPO_GC_INTERVAL_MS: number;
2
+ type FetchLike = (input: string, init?: {
3
+ method?: string;
4
+ signal?: AbortSignal;
5
+ }) => Promise<Response>;
6
+ /**
7
+ * Runs `repo gc` over the kubo RPC API. GC only ever reclaims unpinned blocks, so this is safe to
8
+ * run unconditionally — kubo decides what is actually collectable.
9
+ *
10
+ * We drive GC over RPC rather than passing kubo's own `--enable-gc` daemon flag. A kubo daemon
11
+ * started with `--enable-gc` never exits in response to `POST /api/v0/shutdown` — it logs
12
+ * "cannot access config, repo not open" and lingers indefinitely as a half-shutdown zombie
13
+ * (SIGTERM still works; verified permanent past 300s). pkc-js POSTs that exact endpoint when it
14
+ * rewrites the kubo Routing config on first connect and relies on the daemon restarting kubo
15
+ * afterwards, so `--enable-gc` wedges the supervision loop.
16
+ *
17
+ * Reported upstream as ipfs/kubo#11424: `maybeRunGC` gives `PeriodicGC` the command request
18
+ * context, but the shutdown command only calls `nd.Close()`, which cancels the node context — so
19
+ * `gcErrc` never closes and `daemonFunc` blocks forever draining it. Reproduces on 0.24.0, 0.42.0
20
+ * and 0.43.0, which is also why the earlier attempt at the flag (f228d7d, Dec 2023, kubo ~0.24)
21
+ * was reverted two days later. Do not add `--enable-gc` back without re-testing that path.
22
+ */
23
+ export declare function runRepoGc(options: {
24
+ kuboApiUrl: URL | string;
25
+ log?: any;
26
+ signal?: AbortSignal;
27
+ fetchImpl?: FetchLike;
28
+ }): Promise<{
29
+ ran: boolean;
30
+ reclaimedCids?: number;
31
+ }>;
32
+ /**
33
+ * Starts the periodic repo GC. Returns a stop function.
34
+ *
35
+ * The timer is unref'd so it never by itself keeps the daemon process alive, and runs are
36
+ * single-flighted: a GC that outlives its own interval must not have a second one stacked on top
37
+ * of it. Errors are swallowed inside the tick — an interval callback that rejects becomes an
38
+ * unhandledRejection and takes the daemon down (same failure mode as issue #37 bug 3).
39
+ */
40
+ export declare function startRepoGcScheduler(options: {
41
+ kuboApiUrl: URL | string;
42
+ intervalMs?: number;
43
+ log?: any;
44
+ fetchImpl?: FetchLike;
45
+ }): () => void;
46
+ export {};
@@ -0,0 +1,101 @@
1
+ import { PKCLogger } from "../util.js";
2
+ // Matches kubo's default Datastore.GCPeriod.
3
+ export const DEFAULT_REPO_GC_INTERVAL_MS = 60 * 60 * 1000;
4
+ // The daemon tracks kubo at its configured bind address, which is routinely a wildcard
5
+ // (`http://0.0.0.0:5001/api/v0`). Connecting to 0.0.0.0 fails with EINVAL on macOS, so resolve
6
+ // wildcards to loopback the same way daemon.ts does for its port checks.
7
+ function toConnectableApiBase(kuboApiUrl) {
8
+ const url = new URL(String(kuboApiUrl));
9
+ if (url.hostname === "0.0.0.0")
10
+ url.hostname = "127.0.0.1";
11
+ else if (url.hostname === "::" || url.hostname === "[::]")
12
+ url.hostname = "[::1]";
13
+ return url.toString().replace(/\/+$/, "");
14
+ }
15
+ /**
16
+ * Runs `repo gc` over the kubo RPC API. GC only ever reclaims unpinned blocks, so this is safe to
17
+ * run unconditionally — kubo decides what is actually collectable.
18
+ *
19
+ * We drive GC over RPC rather than passing kubo's own `--enable-gc` daemon flag. A kubo daemon
20
+ * started with `--enable-gc` never exits in response to `POST /api/v0/shutdown` — it logs
21
+ * "cannot access config, repo not open" and lingers indefinitely as a half-shutdown zombie
22
+ * (SIGTERM still works; verified permanent past 300s). pkc-js POSTs that exact endpoint when it
23
+ * rewrites the kubo Routing config on first connect and relies on the daemon restarting kubo
24
+ * afterwards, so `--enable-gc` wedges the supervision loop.
25
+ *
26
+ * Reported upstream as ipfs/kubo#11424: `maybeRunGC` gives `PeriodicGC` the command request
27
+ * context, but the shutdown command only calls `nd.Close()`, which cancels the node context — so
28
+ * `gcErrc` never closes and `daemonFunc` blocks forever draining it. Reproduces on 0.24.0, 0.42.0
29
+ * and 0.43.0, which is also why the earlier attempt at the flag (f228d7d, Dec 2023, kubo ~0.24)
30
+ * was reverted two days later. Do not add `--enable-gc` back without re-testing that path.
31
+ */
32
+ export async function runRepoGc(options) {
33
+ const log = options.log ?? PKCLogger("bitsocial-cli:ipfs:repoGc");
34
+ const fetchImpl = options.fetchImpl ?? globalThis.fetch;
35
+ const apiBase = toConnectableApiBase(options.kuboApiUrl);
36
+ let reclaimedCids = 0;
37
+ try {
38
+ const response = await fetchImpl(`${apiBase}/repo/gc?quiet=true`, { method: "POST", signal: options.signal });
39
+ if (!response.ok)
40
+ throw new Error(`kubo RPC repo/gc responded ${response.status} ${response.statusText}`);
41
+ // repo/gc streams newline-delimited JSON, one object per reclaimed CID. Draining it fully
42
+ // is what makes this await mean "GC finished" rather than "GC started".
43
+ const text = await response.text();
44
+ for (const line of text.split("\n")) {
45
+ const trimmed = line.trim();
46
+ if (!trimmed)
47
+ continue;
48
+ try {
49
+ const parsed = JSON.parse(trimmed);
50
+ if (parsed.Error)
51
+ log.error?.("Failed to GC a block out of the ipfs repo", parsed.Error);
52
+ else if (parsed.Key)
53
+ reclaimedCids++;
54
+ }
55
+ catch {
56
+ // A malformed line is not worth aborting a completed GC over.
57
+ }
58
+ }
59
+ }
60
+ catch (error) {
61
+ log.error?.("Failed to GC ipfs repo", apiBase, error);
62
+ return { ran: false };
63
+ }
64
+ log(`GC reclaimed ${reclaimedCids} cids from the IPFS node ${apiBase}`);
65
+ return { ran: true, reclaimedCids };
66
+ }
67
+ /**
68
+ * Starts the periodic repo GC. Returns a stop function.
69
+ *
70
+ * The timer is unref'd so it never by itself keeps the daemon process alive, and runs are
71
+ * single-flighted: a GC that outlives its own interval must not have a second one stacked on top
72
+ * of it. Errors are swallowed inside the tick — an interval callback that rejects becomes an
73
+ * unhandledRejection and takes the daemon down (same failure mode as issue #37 bug 3).
74
+ */
75
+ export function startRepoGcScheduler(options) {
76
+ const log = options.log ?? PKCLogger("bitsocial-cli:ipfs:repoGc");
77
+ const intervalMs = options.intervalMs ?? DEFAULT_REPO_GC_INTERVAL_MS;
78
+ const abortController = new AbortController();
79
+ let inFlight;
80
+ const tick = () => {
81
+ if (inFlight)
82
+ return;
83
+ inFlight = runRepoGc({
84
+ kuboApiUrl: options.kuboApiUrl,
85
+ log,
86
+ signal: abortController.signal,
87
+ fetchImpl: options.fetchImpl
88
+ })
89
+ .catch((error) => log.error?.("repo gc tick error (will retry next interval)", error))
90
+ .finally(() => {
91
+ inFlight = undefined;
92
+ });
93
+ };
94
+ const timer = setInterval(tick, intervalMs);
95
+ timer.unref?.();
96
+ log(`Scheduled IPFS repo GC every ${intervalMs}ms against ${String(options.kuboApiUrl)}`);
97
+ return () => {
98
+ clearInterval(timer);
99
+ abortController.abort();
100
+ };
101
+ }
@@ -46,6 +46,20 @@
46
46
  "multiple": true,
47
47
  "type": "option"
48
48
  },
49
+ "enableIpfsGc": {
50
+ "description": "Periodically garbage-collect the IPFS repo over the kubo RPC API while the daemon is up. Only reclaims unpinned blocks — pinned data and MFS are never collected. Disable with --no-enableIpfsGc",
51
+ "name": "enableIpfsGc",
52
+ "allowNo": true,
53
+ "type": "boolean"
54
+ },
55
+ "ipfsGcIntervalMinutes": {
56
+ "description": "How often to garbage-collect the IPFS repo, in minutes",
57
+ "name": "ipfsGcIntervalMinutes",
58
+ "default": 60,
59
+ "hasDynamicHelp": false,
60
+ "multiple": false,
61
+ "type": "option"
62
+ },
49
63
  "allowPrivateKeyExport": {
50
64
  "description": "Allow RPC clients to request community exports that include the community signer's private key (`bitsocial community export --includePrivateKey`). Disable with --no-allowPrivateKeyExport when exposing the RPC to untrusted clients",
51
65
  "name": "allowPrivateKeyExport",
@@ -871,5 +885,5 @@
871
885
  ]
872
886
  }
873
887
  },
874
- "version": "0.19.86"
888
+ "version": "0.19.87"
875
889
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bitsocial/bitsocial-cli",
3
- "version": "0.19.86",
3
+ "version": "0.19.87",
4
4
  "description": "Command line interface to Bitsocial API",
5
5
  "types": "./dist/index.d.ts",
6
6
  "homepage": "https://github.com/bitsocialnet/bitsocial-cli",
@@ -119,13 +119,13 @@
119
119
  "@oclif/plugin-help": "6.2.36",
120
120
  "@oclif/plugin-not-found": "3.2.73",
121
121
  "@oclif/table": "0.5.1",
122
- "@pkcprotocol/pkc-js": "0.0.73",
122
+ "@pkcprotocol/pkc-js": "0.0.77",
123
123
  "dataobject-parser": "1.2.22",
124
124
  "decompress": "4.2.1",
125
125
  "env-paths": "2.2.1",
126
126
  "exit-hook": "4.0.0",
127
127
  "express": "4.19.2",
128
- "kubo": "0.42.0",
128
+ "kubo": "0.43.0",
129
129
  "p-limit": "7.3.0",
130
130
  "strip-json-comments": "5.0.3",
131
131
  "tcp-port-used": "1.0.2",