@parity/product-deploy 0.7.28-rc.0 → 0.7.28

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.
Files changed (40) hide show
  1. package/assets/environments.json +0 -2
  2. package/dist/bug-report.js +4 -4
  3. package/dist/{chunk-KJH2T5TQ.js → chunk-37M4NISG.js} +1 -1
  4. package/dist/{chunk-43HLT335.js → chunk-64KTKZ7H.js} +1 -1
  5. package/dist/{chunk-DNXH4QTI.js → chunk-6Y3XJGV7.js} +112 -16
  6. package/dist/{chunk-QTZNULSH.js → chunk-7NKOV5SU.js} +1 -1
  7. package/dist/{chunk-OITUIM2E.js → chunk-HZKRLQLG.js} +0 -3
  8. package/dist/{chunk-KHVTYIIX.js → chunk-IW3X2MJF.js} +2 -0
  9. package/dist/chunk-L2SKSKB6.js +308 -0
  10. package/dist/{chunk-MFTODIIT.js → chunk-LFKP64TQ.js} +13 -7
  11. package/dist/{chunk-ADNBLFDP.js → chunk-THZU3FZU.js} +2 -2
  12. package/dist/{chunk-P6CHOMN3.js → chunk-TPDF24MG.js} +25 -36
  13. package/dist/{chunk-QMYW3D6E.js → chunk-Y7XKC43A.js} +54 -100
  14. package/dist/{chunk-NF2FL4ZO.js → chunk-ZJDGVUN3.js} +3 -3
  15. package/dist/chunk-probe.js +3 -3
  16. package/dist/deploy.d.ts +1 -2
  17. package/dist/deploy.js +11 -11
  18. package/dist/dotns.d.ts +10 -1
  19. package/dist/dotns.js +9 -5
  20. package/dist/environments.d.ts +0 -2
  21. package/dist/environments.js +1 -1
  22. package/dist/incremental-stats.d.ts +2 -0
  23. package/dist/incremental-stats.js +1 -1
  24. package/dist/index.js +12 -12
  25. package/dist/manifest/publish.js +12 -12
  26. package/dist/manifest-fetch.d.ts +2 -1
  27. package/dist/manifest-fetch.js +1 -1
  28. package/dist/manifest-roundtrip.js +1 -1
  29. package/dist/memory-report.js +2 -2
  30. package/dist/merkle.js +11 -11
  31. package/dist/personhood/bootstrap.js +5 -5
  32. package/dist/personhood/people-client.js +5 -5
  33. package/dist/pool.d.ts +6 -13
  34. package/dist/pool.js +3 -1
  35. package/dist/run-state.js +1 -1
  36. package/dist/telemetry.d.ts +1 -1
  37. package/dist/telemetry.js +2 -2
  38. package/dist/version-check.js +3 -3
  39. package/package.json +1 -1
  40. package/dist/chunk-FZWJV5AD.js +0 -231
@@ -25,7 +25,6 @@ interface Environment {
25
25
  ipfs?: string;
26
26
  uptimeUrl?: string;
27
27
  autoAccountMapping?: boolean;
28
- bulletinAuthorizeV2?: boolean;
29
28
  nativeToEthRatio?: number;
30
29
  registerStorageDeposit?: number;
31
30
  contracts?: Record<string, string>;
@@ -62,7 +61,6 @@ interface ResolvedEndpoints {
62
61
  envName: string;
63
62
  ipfs?: string;
64
63
  autoAccountMapping: boolean;
65
- bulletinAuthorizeV2: boolean;
66
64
  contracts: Record<string, string>;
67
65
  nativeToEthRatio: bigint;
68
66
  registerStorageDeposit?: bigint;
@@ -8,7 +8,7 @@ import {
8
8
  loadEnvironments,
9
9
  resolveEndpoints,
10
10
  validateContractAddresses
11
- } from "./chunk-OITUIM2E.js";
11
+ } from "./chunk-HZKRLQLG.js";
12
12
  import "./chunk-ZOC4GITL.js";
13
13
  export {
14
14
  DEFAULT_ENV_ID,
@@ -4,6 +4,7 @@ import { ManifestChunkEntry } from './manifest.js';
4
4
  interface IncrementalStats {
5
5
  manifestSource: "embedded" | "heuristic_fallback" | "none";
6
6
  manifestFetchAttempts: number;
7
+ manifestFetchReason?: string;
7
8
  manifestBytes: number;
8
9
  framework: string | null;
9
10
  filesTotal: number;
@@ -37,6 +38,7 @@ interface IncrementalStats {
37
38
  interface ComputeStatsInput {
38
39
  manifestSource: IncrementalStats["manifestSource"];
39
40
  manifestFetchAttempts: number;
41
+ manifestFetchReason?: string;
40
42
  manifestBytes?: number;
41
43
  framework: string | null;
42
44
  filesTotal: number;
@@ -2,7 +2,7 @@ import {
2
2
  computeStats,
3
3
  renderSummary,
4
4
  telemetryAttributes
5
- } from "./chunk-KHVTYIIX.js";
5
+ } from "./chunk-IW3X2MJF.js";
6
6
  export {
7
7
  computeStats,
8
8
  renderSummary,
package/dist/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-MMAZFJDG.js";
8
8
  import {
9
9
  publishManifest
10
- } from "./chunk-NF2FL4ZO.js";
10
+ } from "./chunk-ZJDGVUN3.js";
11
11
  import {
12
12
  DEFAULT_TEXT_RECORD_BUDGET_BYTES,
13
13
  PLACEHOLDER_CID,
@@ -24,19 +24,19 @@ import {
24
24
  deploy,
25
25
  merkleizeJS,
26
26
  merkleizeWithStableOrder
27
- } from "./chunk-P6CHOMN3.js";
27
+ } from "./chunk-TPDF24MG.js";
28
28
  import {
29
29
  computeStats,
30
30
  renderSummary,
31
31
  telemetryAttributes
32
- } from "./chunk-KHVTYIIX.js";
32
+ } from "./chunk-IW3X2MJF.js";
33
33
  import {
34
34
  finaliseEmbeddedManifest,
35
35
  writeEmbeddedManifestPlaceholder
36
36
  } from "./chunk-KOSF5FDO.js";
37
37
  import {
38
38
  fetchPreviousManifest
39
- } from "./chunk-FZWJV5AD.js";
39
+ } from "./chunk-L2SKSKB6.js";
40
40
  import {
41
41
  MANIFEST_DIR,
42
42
  MANIFEST_FILENAME,
@@ -46,26 +46,26 @@ import {
46
46
  isVolatilePath,
47
47
  parseManifest
48
48
  } from "./chunk-S7EM5VMW.js";
49
- import "./chunk-ADNBLFDP.js";
50
- import "./chunk-43HLT335.js";
49
+ import "./chunk-THZU3FZU.js";
50
+ import "./chunk-64KTKZ7H.js";
51
51
  import {
52
52
  probeChunks
53
- } from "./chunk-QTZNULSH.js";
53
+ } from "./chunk-7NKOV5SU.js";
54
54
  import "./chunk-C2TS5MER.js";
55
55
  import {
56
56
  DEFAULT_MNEMONIC,
57
57
  DotNS,
58
58
  parseDomainName,
59
59
  sanitizeDomainLabel
60
- } from "./chunk-DNXH4QTI.js";
60
+ } from "./chunk-6Y3XJGV7.js";
61
61
  import {
62
62
  bootstrapPool,
63
63
  derivePoolAccounts,
64
64
  ensureAuthorized,
65
65
  fetchPoolAuthorizations,
66
66
  selectAccount
67
- } from "./chunk-QMYW3D6E.js";
68
- import "./chunk-MFTODIIT.js";
67
+ } from "./chunk-Y7XKC43A.js";
68
+ import "./chunk-LFKP64TQ.js";
69
69
  import {
70
70
  VERSION,
71
71
  loadRunState,
@@ -75,7 +75,7 @@ import {
75
75
  shouldSkipStaleWarning,
76
76
  stateFilePath,
77
77
  writeRunState
78
- } from "./chunk-KJH2T5TQ.js";
78
+ } from "./chunk-37M4NISG.js";
79
79
  import {
80
80
  DEFAULT_ENV_ID,
81
81
  defaultBundledPath,
@@ -85,7 +85,7 @@ import {
85
85
  loadEnvironments,
86
86
  resolveEndpoints,
87
87
  validateContractAddresses
88
- } from "./chunk-OITUIM2E.js";
88
+ } from "./chunk-HZKRLQLG.js";
89
89
  import "./chunk-ZOC4GITL.js";
90
90
  import "./chunk-HOTQDYHD.js";
91
91
  export {
@@ -1,21 +1,21 @@
1
1
  import {
2
2
  publishManifest
3
- } from "../chunk-NF2FL4ZO.js";
3
+ } from "../chunk-ZJDGVUN3.js";
4
4
  import "../chunk-RI3ZLNPN.js";
5
- import "../chunk-P6CHOMN3.js";
6
- import "../chunk-KHVTYIIX.js";
5
+ import "../chunk-TPDF24MG.js";
6
+ import "../chunk-IW3X2MJF.js";
7
7
  import "../chunk-KOSF5FDO.js";
8
- import "../chunk-FZWJV5AD.js";
8
+ import "../chunk-L2SKSKB6.js";
9
9
  import "../chunk-S7EM5VMW.js";
10
- import "../chunk-ADNBLFDP.js";
11
- import "../chunk-43HLT335.js";
12
- import "../chunk-QTZNULSH.js";
10
+ import "../chunk-THZU3FZU.js";
11
+ import "../chunk-64KTKZ7H.js";
12
+ import "../chunk-7NKOV5SU.js";
13
13
  import "../chunk-C2TS5MER.js";
14
- import "../chunk-DNXH4QTI.js";
15
- import "../chunk-QMYW3D6E.js";
16
- import "../chunk-MFTODIIT.js";
17
- import "../chunk-KJH2T5TQ.js";
18
- import "../chunk-OITUIM2E.js";
14
+ import "../chunk-6Y3XJGV7.js";
15
+ import "../chunk-Y7XKC43A.js";
16
+ import "../chunk-LFKP64TQ.js";
17
+ import "../chunk-37M4NISG.js";
18
+ import "../chunk-HZKRLQLG.js";
19
19
  import "../chunk-ZOC4GITL.js";
20
20
  import "../chunk-HOTQDYHD.js";
21
21
  export {
@@ -22,6 +22,7 @@ interface FetchOptions {
22
22
  domain?: string;
23
23
  buildDir?: string;
24
24
  }
25
+ type TierOutcome = "timeout" | "network_error" | `http_${number}` | "body_read_error" | "car_truncated" | "manifest_not_in_slice" | "car_parse_error" | "manifest_missing" | "manifest_parse_error" | "success";
25
26
  declare function getCacheDir(): string | null;
26
27
  declare function readPersistentLocalManifest(domain: string | undefined, prevContenthash: string): FetchOutcome | null;
27
28
  declare function writePersistentLocalManifest(domain: string, storageCid: string, manifestJson: string): void;
@@ -29,4 +30,4 @@ declare function fetchPreviousManifest(prevContenthash: string | null, options?:
29
30
  declare function extractManifestFromCar(carBytes: Uint8Array): Promise<Uint8Array | null>;
30
31
  declare function walkDagToManifest(blocks: Map<string, Uint8Array>, rootCid: string): Promise<Uint8Array | null>;
31
32
 
32
- export { DEFAULT_TIMEOUT_MS, type FetchOptions, type FetchOutcome, SIDECAR_FILENAME, extractManifestFromCar, fetchPreviousManifest, getCacheDir, readPersistentLocalManifest, walkDagToManifest, writePersistentLocalManifest };
33
+ export { DEFAULT_TIMEOUT_MS, type FetchOptions, type FetchOutcome, SIDECAR_FILENAME, type TierOutcome, extractManifestFromCar, fetchPreviousManifest, getCacheDir, readPersistentLocalManifest, walkDagToManifest, writePersistentLocalManifest };
@@ -7,7 +7,7 @@ import {
7
7
  readPersistentLocalManifest,
8
8
  walkDagToManifest,
9
9
  writePersistentLocalManifest
10
- } from "./chunk-FZWJV5AD.js";
10
+ } from "./chunk-L2SKSKB6.js";
11
11
  import "./chunk-S7EM5VMW.js";
12
12
  export {
13
13
  DEFAULT_TIMEOUT_MS,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  extractManifestFromCar
3
- } from "./chunk-FZWJV5AD.js";
3
+ } from "./chunk-L2SKSKB6.js";
4
4
  import "./chunk-S7EM5VMW.js";
5
5
 
6
6
  // src/manifest-roundtrip.ts
@@ -5,8 +5,8 @@ import {
5
5
  maybeWriteMemoryReport,
6
6
  safeHeap,
7
7
  sampleFromBytes
8
- } from "./chunk-MFTODIIT.js";
9
- import "./chunk-KJH2T5TQ.js";
8
+ } from "./chunk-LFKP64TQ.js";
9
+ import "./chunk-37M4NISG.js";
10
10
  export {
11
11
  DEFAULT_THRESHOLD_MB,
12
12
  buildMemoryReport,
package/dist/merkle.js CHANGED
@@ -6,20 +6,20 @@ import {
6
6
  merkleizeKuboBackend,
7
7
  merkleizeWithStableOrder,
8
8
  rebuildOrderedCarFromBytes
9
- } from "./chunk-P6CHOMN3.js";
10
- import "./chunk-KHVTYIIX.js";
9
+ } from "./chunk-TPDF24MG.js";
10
+ import "./chunk-IW3X2MJF.js";
11
11
  import "./chunk-KOSF5FDO.js";
12
- import "./chunk-FZWJV5AD.js";
12
+ import "./chunk-L2SKSKB6.js";
13
13
  import "./chunk-S7EM5VMW.js";
14
- import "./chunk-ADNBLFDP.js";
15
- import "./chunk-43HLT335.js";
16
- import "./chunk-QTZNULSH.js";
14
+ import "./chunk-THZU3FZU.js";
15
+ import "./chunk-64KTKZ7H.js";
16
+ import "./chunk-7NKOV5SU.js";
17
17
  import "./chunk-C2TS5MER.js";
18
- import "./chunk-DNXH4QTI.js";
19
- import "./chunk-QMYW3D6E.js";
20
- import "./chunk-MFTODIIT.js";
21
- import "./chunk-KJH2T5TQ.js";
22
- import "./chunk-OITUIM2E.js";
18
+ import "./chunk-6Y3XJGV7.js";
19
+ import "./chunk-Y7XKC43A.js";
20
+ import "./chunk-LFKP64TQ.js";
21
+ import "./chunk-37M4NISG.js";
22
+ import "./chunk-HZKRLQLG.js";
23
23
  import "./chunk-ZOC4GITL.js";
24
24
  import "./chunk-HOTQDYHD.js";
25
25
  export {
@@ -21,13 +21,13 @@ import {
21
21
  import "../chunk-UPWEOGLQ.js";
22
22
  import {
23
23
  WS_HEARTBEAT_TIMEOUT_MS
24
- } from "../chunk-DNXH4QTI.js";
25
- import "../chunk-QMYW3D6E.js";
26
- import "../chunk-MFTODIIT.js";
27
- import "../chunk-KJH2T5TQ.js";
24
+ } from "../chunk-6Y3XJGV7.js";
25
+ import "../chunk-Y7XKC43A.js";
26
+ import "../chunk-LFKP64TQ.js";
27
+ import "../chunk-37M4NISG.js";
28
28
  import {
29
29
  loadEnvironments
30
- } from "../chunk-OITUIM2E.js";
30
+ } from "../chunk-HZKRLQLG.js";
31
31
  import "../chunk-ZOC4GITL.js";
32
32
 
33
33
  // src/personhood/bootstrap.ts
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  WS_HEARTBEAT_TIMEOUT_MS
3
- } from "../chunk-DNXH4QTI.js";
4
- import "../chunk-QMYW3D6E.js";
5
- import "../chunk-MFTODIIT.js";
6
- import "../chunk-KJH2T5TQ.js";
3
+ } from "../chunk-6Y3XJGV7.js";
4
+ import "../chunk-Y7XKC43A.js";
5
+ import "../chunk-LFKP64TQ.js";
6
+ import "../chunk-37M4NISG.js";
7
7
  import {
8
8
  loadEnvironments
9
- } from "../chunk-OITUIM2E.js";
9
+ } from "../chunk-HZKRLQLG.js";
10
10
  import "../chunk-ZOC4GITL.js";
11
11
 
12
12
  // src/personhood/people-client.ts
package/dist/pool.d.ts CHANGED
@@ -14,16 +14,12 @@ interface PoolAuthorization extends PoolAccount {
14
14
  expiration: number;
15
15
  }
16
16
  declare function derivePoolAccounts(poolSize?: number, mnemonic?: string): PoolAccount[];
17
- interface AuthorizationCheck {
18
- needs?: AuthorizationNeeds;
19
- bulletinAuthorizeV2?: boolean;
20
- }
21
- declare function isAuthorizationSufficient(auth: any, currentBlock: number, check?: AuthorizationCheck): boolean;
17
+ declare function isAuthorizationSufficient(auth: any, currentBlock: number, needs?: AuthorizationNeeds): boolean;
22
18
  interface SelectionResult {
23
19
  account: PoolAuthorization;
24
20
  eligibleCount: number;
25
21
  }
26
- declare function selectAccount(authorizations: PoolAuthorization[], random?: () => number, currentBlock?: number): SelectionResult | null;
22
+ declare function selectAccount(authorizations: PoolAuthorization[], random?: () => number): SelectionResult;
27
23
  declare function fetchPoolAuthorizations(api: any, accounts: PoolAccount[]): Promise<PoolAuthorization[]>;
28
24
  interface AuthorizationNeeds {
29
25
  txs: bigint;
@@ -41,11 +37,8 @@ declare function classifyAliceTxError(err: unknown): TxRetryDecision;
41
37
  declare function isTestnetSpecName(specName: string | undefined | null): boolean;
42
38
  declare function detectTestnet(api: any): Promise<boolean>;
43
39
  declare function _resetTestnetCacheForTests(): void;
44
- declare function ensureAuthorized(api: any, address: string, label?: string, bulletinAuthorizeV2?: boolean, needs?: AuthorizationNeeds): Promise<void>;
45
- declare function topUpBy(api: any, address: string, needs: AuthorizationNeeds, label?: string, bulletinAuthorizeV2?: boolean): Promise<void>;
46
- interface BootstrapOptions {
47
- bulletinAuthorizeV2?: boolean;
48
- }
49
- declare function bootstrapPool(bulletinRpc: string, poolSize?: number, mnemonic?: string, opts?: BootstrapOptions): Promise<void>;
40
+ declare function ensureAuthorized(api: any, address: string, label?: string, needs?: AuthorizationNeeds): Promise<void>;
41
+ declare function topUpBy(api: any, address: string, needs: AuthorizationNeeds, label?: string): Promise<void>;
42
+ declare function bootstrapPool(bulletinRpc: string, poolSize?: number, mnemonic?: string): Promise<void>;
50
43
 
51
- export { type AuthorizationCheck, type AuthorizationNeeds, type BootstrapOptions, type PoolAccount, type PoolAuthorization, type SelectionResult, type TxRetryDecision, _resetTestnetCacheForTests, bootstrapPool, classifyAliceTxError, computeTopUpTarget, derivePoolAccounts, detectTestnet, ensureAuthorized, fetchPoolAuthorizations, formatPasBalance, isAuthorizationSufficient, isTestnetSpecName, selectAccount, topUpBy };
44
+ export { type AuthorizationNeeds, type PoolAccount, type PoolAuthorization, type SelectionResult, type TxRetryDecision, _resetTestnetCacheForTests, bootstrapPool, classifyAliceTxError, computeTopUpTarget, derivePoolAccounts, detectTestnet, ensureAuthorized, fetchPoolAuthorizations, formatPasBalance, isAuthorizationSufficient, isTestnetSpecName, selectAccount, topUpBy };
package/dist/pool.js CHANGED
@@ -12,7 +12,9 @@ import {
12
12
  isTestnetSpecName,
13
13
  selectAccount,
14
14
  topUpBy
15
- } from "./chunk-QMYW3D6E.js";
15
+ } from "./chunk-Y7XKC43A.js";
16
+ import "./chunk-LFKP64TQ.js";
17
+ import "./chunk-37M4NISG.js";
16
18
  export {
17
19
  _resetTestnetCacheForTests,
18
20
  bootstrapPool,
package/dist/run-state.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  shouldSkipStaleWarning,
8
8
  stateFilePath,
9
9
  writeRunState
10
- } from "./chunk-KJH2T5TQ.js";
10
+ } from "./chunk-37M4NISG.js";
11
11
  export {
12
12
  VERSION,
13
13
  loadRunState,
@@ -29,7 +29,7 @@ type DeployErrorCategory = 'user' | 'environment' | 'internal' | 'unknown';
29
29
  declare function classifyDeployError(msg: string): DeployErrorCategory;
30
30
  declare function classifySadReason(message: string): string;
31
31
  declare function computeDeployOutcome(errorCategory: DeployErrorCategory | null, isSad: boolean, sadReason: string): string;
32
- type DeployErrorKind = 'contract-revert' | 'chain-timeout' | 'nonce-stale' | 'connection' | 'naming.pop_required' | 'naming.already_owned' | 'naming.subdomain_orphan' | 'verify.contenthash_mismatch' | 'verify.dagpb_not_finalised' | 'network.recovery_exhausted' | 'chain.api_timeout' | 'tool.invariant' | 'unknown';
32
+ type DeployErrorKind = 'contract-revert' | 'chain-timeout' | 'nonce-stale' | 'connection' | 'naming.pop_required' | 'naming.already_owned' | 'naming.subdomain_orphan' | 'verify.contenthash_mismatch' | 'verify.dagpb_not_finalised' | 'network.recovery_exhausted' | 'chain.api_timeout' | 'chain.tx_timeout' | 'chain.tx_silent' | 'tool.invariant' | 'unknown';
33
33
  declare function classifyErrorKind(msg: string): DeployErrorKind;
34
34
  declare function sanitizeErrorMessage(msg: string): string;
35
35
  /**
package/dist/telemetry.js CHANGED
@@ -32,8 +32,8 @@ import {
32
32
  truncateAddress,
33
33
  withDeploySpan,
34
34
  withSpan
35
- } from "./chunk-MFTODIIT.js";
36
- import "./chunk-KJH2T5TQ.js";
35
+ } from "./chunk-LFKP64TQ.js";
36
+ import "./chunk-37M4NISG.js";
37
37
  export {
38
38
  VERSION,
39
39
  __setDeployRootSpanForTest,
@@ -11,9 +11,9 @@ import {
11
11
  isPreReleaseVersion,
12
12
  preReleaseWarning,
13
13
  promptYesNo
14
- } from "./chunk-43HLT335.js";
15
- import "./chunk-MFTODIIT.js";
16
- import "./chunk-KJH2T5TQ.js";
14
+ } from "./chunk-64KTKZ7H.js";
15
+ import "./chunk-LFKP64TQ.js";
16
+ import "./chunk-37M4NISG.js";
17
17
  export {
18
18
  assessVersion,
19
19
  checkNodeVersion,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parity/product-deploy",
3
- "version": "0.7.28-rc.0",
3
+ "version": "0.7.28",
4
4
  "private": false,
5
5
  "repository": {
6
6
  "type": "git",
@@ -1,231 +0,0 @@
1
- import {
2
- MANIFEST_DIR,
3
- MANIFEST_FILENAME,
4
- parseManifest
5
- } from "./chunk-S7EM5VMW.js";
6
-
7
- // src/manifest-fetch.ts
8
- import * as fs from "fs";
9
- import * as path from "path";
10
- import * as os from "os";
11
- import { CarReader } from "@ipld/car/reader";
12
- import * as dagPB from "@ipld/dag-pb";
13
- import { CID } from "multiformats/cid";
14
- var DEFAULT_TIMEOUT_MS = 3e4;
15
- var SIDECAR_FILENAME = ".last_deploy_cid";
16
- var RANGE_TIERS = [
17
- "bytes=0-4095",
18
- "bytes=0-65535",
19
- "bytes=0-1048575",
20
- void 0
21
- // full body
22
- ];
23
- function getCacheDir() {
24
- const override = process.env.BULLETIN_DEPLOY_CACHE_DIR;
25
- if (override) return path.join(override, "manifests");
26
- if (process.platform === "win32") return null;
27
- const xdg = process.env.XDG_CACHE_HOME;
28
- if (xdg) return path.join(xdg, "bulletin-deploy", "manifests");
29
- return path.join(os.homedir(), ".cache", "bulletin-deploy", "manifests");
30
- }
31
- function readPersistentLocalManifest(domain, prevContenthash) {
32
- if (!domain) return null;
33
- const cacheDir = getCacheDir();
34
- if (!cacheDir) return null;
35
- const cidPath = path.join(cacheDir, `${domain}.cid`);
36
- const manifestPath = path.join(cacheDir, `${domain}.json`);
37
- let storedCid;
38
- try {
39
- storedCid = fs.readFileSync(cidPath, "utf8").trim();
40
- } catch {
41
- return null;
42
- }
43
- if (storedCid !== prevContenthash) return null;
44
- let text;
45
- try {
46
- text = fs.readFileSync(manifestPath, "utf8");
47
- } catch {
48
- return null;
49
- }
50
- const parsed = parseManifest(text);
51
- if (!parsed.ok) return null;
52
- return {
53
- source: "embedded",
54
- manifest: parsed.manifest,
55
- attempts: 0,
56
- bytesDownloaded: text.length
57
- };
58
- }
59
- function writePersistentLocalManifest(domain, storageCid, manifestJson) {
60
- const cacheDir = getCacheDir();
61
- if (!cacheDir) return;
62
- try {
63
- fs.mkdirSync(cacheDir, { recursive: true });
64
- const cidPath = path.join(cacheDir, `${domain}.cid`);
65
- const manifestPath = path.join(cacheDir, `${domain}.json`);
66
- const cidTmp = `${cidPath}.${process.pid}.tmp`;
67
- const manifestTmp = `${manifestPath}.${process.pid}.tmp`;
68
- fs.writeFileSync(cidTmp, storageCid);
69
- fs.renameSync(cidTmp, cidPath);
70
- fs.writeFileSync(manifestTmp, manifestJson);
71
- fs.renameSync(manifestTmp, manifestPath);
72
- } catch {
73
- }
74
- }
75
- async function fetchAcrossTiers(url, budget, start) {
76
- let lastReason = "unknown";
77
- let attempts = 0;
78
- let bytesDownloaded = 0;
79
- for (let tier = 0; tier < RANGE_TIERS.length; tier++) {
80
- if (Date.now() - start > budget) {
81
- return { outcome: "retryable", reason: `budget exceeded: ${lastReason}`, attempts, bytesDownloaded };
82
- }
83
- attempts++;
84
- const headers = {};
85
- if (RANGE_TIERS[tier] !== void 0) headers.Range = RANGE_TIERS[tier];
86
- let res;
87
- try {
88
- const ctrl = new AbortController();
89
- const remaining = budget - (Date.now() - start);
90
- const timer = setTimeout(() => ctrl.abort(), Math.max(100, remaining));
91
- try {
92
- res = await fetch(url, { headers, signal: ctrl.signal });
93
- } finally {
94
- clearTimeout(timer);
95
- }
96
- } catch (e) {
97
- lastReason = `network error: ${e?.message ?? e}`;
98
- continue;
99
- }
100
- if (res.status === 404) return { outcome: "404", attempts, bytesDownloaded };
101
- if (res.status !== 200 && res.status !== 206) {
102
- lastReason = `gateway HTTP ${res.status}`;
103
- continue;
104
- }
105
- const isFullBody = res.status === 200;
106
- let carBytes;
107
- try {
108
- const buf = await res.arrayBuffer();
109
- carBytes = new Uint8Array(buf);
110
- bytesDownloaded = carBytes.length;
111
- } catch (e) {
112
- if (isFullBody) return { outcome: "parse_error", reason: `body read error: ${e?.message ?? e}`, attempts, bytesDownloaded };
113
- lastReason = `body read error: ${e?.message ?? e}`;
114
- continue;
115
- }
116
- let manifestBytes;
117
- try {
118
- manifestBytes = await extractManifestFromCar(carBytes);
119
- } catch (e) {
120
- const msg = String(e?.message ?? e);
121
- if (isFullBody) return { outcome: "parse_error", reason: `CAR parse error: ${msg}`, attempts, bytesDownloaded };
122
- lastReason = `truncated at tier ${tier}: ${msg}`;
123
- continue;
124
- }
125
- if (!manifestBytes) {
126
- if (isFullBody) return { outcome: "parse_error", reason: "no .bulletin-deploy/manifest.json in deployed DAG", attempts, bytesDownloaded };
127
- lastReason = `manifest not in slice tier ${tier}`;
128
- continue;
129
- }
130
- const text = new TextDecoder().decode(manifestBytes);
131
- const parsed = parseManifest(text);
132
- if (parsed.ok) return { outcome: "success", manifest: parsed.manifest, attempts, bytesDownloaded };
133
- return { outcome: "parse_error", reason: parsed.error, attempts, bytesDownloaded };
134
- }
135
- return { outcome: "retryable", reason: `tiers exhausted: ${lastReason}`, attempts, bytesDownloaded };
136
- }
137
- async function fetchPreviousManifest(prevContenthash, options = {}) {
138
- if (prevContenthash === null) return { source: "none" };
139
- const local = readPersistentLocalManifest(options.domain, prevContenthash);
140
- if (local) return local;
141
- const gatewayList = (options.gateways ?? (options.gateway ? [options.gateway] : [])).map((g) => g.replace(/\/$/, ""));
142
- const budget = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
143
- const start = Date.now();
144
- let lastReason = "unknown";
145
- let totalAttempts = 0;
146
- let bytesDownloaded = 0;
147
- for (const gatewayRaw of gatewayList) {
148
- const gateway = gatewayRaw.replace(/\/ipfs\/?$/, "");
149
- const url = `${gateway}/ipfs/${prevContenthash}`;
150
- const tierResult = await fetchAcrossTiers(url, budget, start);
151
- if (tierResult.outcome === "success") {
152
- return {
153
- source: "embedded",
154
- manifest: tierResult.manifest,
155
- attempts: totalAttempts + tierResult.attempts,
156
- bytesDownloaded: bytesDownloaded + tierResult.bytesDownloaded
157
- };
158
- }
159
- if (tierResult.outcome === "404" || tierResult.outcome === "parse_error") {
160
- return {
161
- source: "heuristic_fallback",
162
- reason: tierResult.outcome === "404" ? "gateway 404" : tierResult.reason,
163
- attempts: totalAttempts + tierResult.attempts,
164
- bytesDownloaded: bytesDownloaded + tierResult.bytesDownloaded
165
- };
166
- }
167
- lastReason = tierResult.reason;
168
- totalAttempts += tierResult.attempts;
169
- bytesDownloaded += tierResult.bytesDownloaded;
170
- }
171
- return { source: "heuristic_fallback", reason: `all gateways exhausted: ${lastReason}`, attempts: totalAttempts, bytesDownloaded };
172
- }
173
- async function extractManifestFromCar(carBytes) {
174
- const reader = await CarReader.fromBytes(carBytes);
175
- const roots = await reader.getRoots();
176
- if (roots.length === 0) return null;
177
- const blocks = /* @__PURE__ */ new Map();
178
- for await (const { cid, bytes } of reader.blocks()) {
179
- blocks.set(cid.toString(), bytes);
180
- }
181
- return walkDagToManifest(blocks, roots[0].toString());
182
- }
183
- async function walkDagToManifest(blocks, rootCid) {
184
- const rootBytes = blocks.get(rootCid);
185
- if (!rootBytes) return null;
186
- const rootNode = dagPB.decode(rootBytes);
187
- const bdLink = (rootNode.Links ?? []).find((l) => l.Name === MANIFEST_DIR);
188
- if (!bdLink) return null;
189
- const bdBytes = blocks.get(bdLink.Hash.toString());
190
- if (!bdBytes) return null;
191
- const bdNode = dagPB.decode(bdBytes);
192
- const manLink = (bdNode.Links ?? []).find((l) => l.Name === MANIFEST_FILENAME);
193
- if (!manLink) return null;
194
- const manCidStr = manLink.Hash.toString();
195
- const manCid = CID.parse(manCidStr);
196
- const manBytes = blocks.get(manCidStr);
197
- if (!manBytes) return null;
198
- if (manCid.code === 85) {
199
- return manBytes;
200
- }
201
- if (manCid.code === 112) {
202
- const node = dagPB.decode(manBytes);
203
- const parts = [];
204
- let total = 0;
205
- for (const link of node.Links ?? []) {
206
- const leafBytes = blocks.get(link.Hash.toString());
207
- if (!leafBytes) return null;
208
- parts.push(leafBytes);
209
- total += leafBytes.length;
210
- }
211
- const out = new Uint8Array(total);
212
- let pos = 0;
213
- for (const part of parts) {
214
- out.set(part, pos);
215
- pos += part.length;
216
- }
217
- return out;
218
- }
219
- return null;
220
- }
221
-
222
- export {
223
- DEFAULT_TIMEOUT_MS,
224
- SIDECAR_FILENAME,
225
- getCacheDir,
226
- readPersistentLocalManifest,
227
- writePersistentLocalManifest,
228
- fetchPreviousManifest,
229
- extractManifestFromCar,
230
- walkDagToManifest
231
- };