@mikeargento/bitgraph 1.5.0 → 1.6.0
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/__tests__/fuse-set-sdk.test.js +104 -1
- package/dist/__tests__/fuse-set-sdk.test.js.map +1 -1
- package/dist/fuse.d.ts +63 -8
- package/dist/fuse.d.ts.map +1 -1
- package/dist/fuse.js +120 -41
- package/dist/fuse.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/fuse-set-sdk.test.ts +116 -8
- package/src/fuse.ts +177 -47
- package/src/index.ts +2 -2
package/src/fuse.ts
CHANGED
|
@@ -49,6 +49,8 @@ import {
|
|
|
49
49
|
parseSetManifest,
|
|
50
50
|
readSetMetadata,
|
|
51
51
|
SET_METADATA_KEY,
|
|
52
|
+
TRAILER_LENGTH,
|
|
53
|
+
TRAILER_MAGIC,
|
|
52
54
|
verifyFuse,
|
|
53
55
|
verifyFuseMember,
|
|
54
56
|
base64ToBytes,
|
|
@@ -153,6 +155,7 @@ export type FuseErrorCode =
|
|
|
153
155
|
| "bad-input"
|
|
154
156
|
| "allocate-failed"
|
|
155
157
|
| "builder-failed"
|
|
158
|
+
| "load-failed"
|
|
156
159
|
| "commitment-missing"
|
|
157
160
|
| "commit-refused"
|
|
158
161
|
| "slot-unavailable"
|
|
@@ -478,7 +481,18 @@ export const MAX_SET_MEMBERS = 2000;
|
|
|
478
481
|
/** The placements a set member takes: Forms A and B, one original per member. */
|
|
479
482
|
export type SetMemberPlacement = "trailer/1" | "container/1";
|
|
480
483
|
|
|
481
|
-
|
|
484
|
+
/** What a hashed member's fused digest is computed for: the held slot and its commitment. */
|
|
485
|
+
export interface FusedDigestInput {
|
|
486
|
+
commitment: Uint8Array;
|
|
487
|
+
commitmentHex: string;
|
|
488
|
+
slot: SlotAllocation;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
/**
|
|
492
|
+
* A member given as bytes. The core hashes the original, builds the fused
|
|
493
|
+
* bytes under the slot's commitment, checks them, and hashes them.
|
|
494
|
+
*/
|
|
495
|
+
export interface FuseSetBytesMember {
|
|
482
496
|
/** The original bytes. Never modified. */
|
|
483
497
|
original: Uint8Array;
|
|
484
498
|
/** Default: placementForBytes(original). */
|
|
@@ -489,10 +503,62 @@ export interface FuseSetMember {
|
|
|
489
503
|
builder?: FuseBuilder;
|
|
490
504
|
}
|
|
491
505
|
|
|
506
|
+
/**
|
|
507
|
+
* A member whose bytes are read only when it is that member's turn, after
|
|
508
|
+
* the slot is held, and released once hashed: one member's bytes in memory
|
|
509
|
+
* at a time, however large the set. Nothing can be read before allocation
|
|
510
|
+
* without reading twice, so the caller names the placement and the origin
|
|
511
|
+
* digest up front; the digest is checked against the loaded bytes, and the
|
|
512
|
+
* byte guards run as for a bytes member.
|
|
513
|
+
*/
|
|
514
|
+
export interface FuseSetLoadedMember {
|
|
515
|
+
load: () => Promise<Uint8Array> | Uint8Array;
|
|
516
|
+
originDigest: Uint8Array;
|
|
517
|
+
placement: SetMemberPlacement;
|
|
518
|
+
/** Advisory; feeds fusedNamesFor. */
|
|
519
|
+
name?: string;
|
|
520
|
+
/** Default: builderFor(placement, bytes). The locate and origin guards run regardless. */
|
|
521
|
+
builder?: FuseBuilder;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
/**
|
|
525
|
+
* A member the caller hashes itself: it answers the fused digest for the
|
|
526
|
+
* held slot's commitment. For trailer/1 that is a hash state saved after
|
|
527
|
+
* the original and finished with trailerBytesFor(commitment), so the bytes
|
|
528
|
+
* are read once, when they are scanned, and never again. The core never
|
|
529
|
+
* sees this member's bytes: no byte guard runs, keepFused returns nothing
|
|
530
|
+
* for it, and verifyMembers refuses it before any request. Its row is bound
|
|
531
|
+
* to the committed manifest by digest like every other.
|
|
532
|
+
*/
|
|
533
|
+
export interface FuseSetHashedMember {
|
|
534
|
+
originDigest: Uint8Array;
|
|
535
|
+
placement: SetMemberPlacement;
|
|
536
|
+
fusedDigest: (input: FusedDigestInput) => Promise<Uint8Array> | Uint8Array;
|
|
537
|
+
/** Advisory; feeds fusedNamesFor. */
|
|
538
|
+
name?: string;
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
export type FuseSetMember = FuseSetBytesMember | FuseSetLoadedMember | FuseSetHashedMember;
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* The 48 bytes trailer/1 appends after the original: the magic, eight
|
|
545
|
+
* reserved zero bytes, the commitment. A hasher whose state was saved after
|
|
546
|
+
* the original finishes with these and holds the member's fused digest
|
|
547
|
+
* without reading the original again. A test pins them against the
|
|
548
|
+
* placement's own build.
|
|
549
|
+
*/
|
|
550
|
+
export function trailerBytesFor(commitment: Uint8Array): Uint8Array {
|
|
551
|
+
if (!(commitment instanceof Uint8Array) || commitment.length !== 32) throw new FuseError("bad-input", "a slot commitment is 32 bytes");
|
|
552
|
+
const out = new Uint8Array(TRAILER_LENGTH);
|
|
553
|
+
out.set(new TextEncoder().encode(TRAILER_MAGIC), 0);
|
|
554
|
+
out.set(commitment, TRAILER_LENGTH - 32);
|
|
555
|
+
return out;
|
|
556
|
+
}
|
|
557
|
+
|
|
492
558
|
export interface FuseSetProgress {
|
|
493
559
|
/**
|
|
494
|
-
* "hash":
|
|
495
|
-
* "fuse": each member
|
|
560
|
+
* "hash": each member checked before any request (a bytes member's origin digest is taken here).
|
|
561
|
+
* "fuse": each member's fused digest taken, after the slot is held.
|
|
496
562
|
* "commit": 0 of 1 before the request, 1 of 1 when the proof is back.
|
|
497
563
|
* "verify": only with verifyMembers, one per member.
|
|
498
564
|
*/
|
|
@@ -502,7 +568,7 @@ export interface FuseSetProgress {
|
|
|
502
568
|
}
|
|
503
569
|
|
|
504
570
|
export interface FuseSetOptions {
|
|
505
|
-
/** Return each member's fused bytes. Default false: they are virtual, rebuilt from the original and the proof. */
|
|
571
|
+
/** Return each member's fused bytes. Default false: they are virtual, rebuilt from the original and the proof. A hashed member has none to return. */
|
|
506
572
|
keepFused?: boolean;
|
|
507
573
|
/**
|
|
508
574
|
* Run the full verifier (verifyFuseMember) over every member's fused bytes
|
|
@@ -510,7 +576,8 @@ export interface FuseSetOptions {
|
|
|
510
576
|
* false: every member is bound to the returned proof by digest, its row in
|
|
511
577
|
* the committed manifest, which is itself verified FUSED_DIRECT; that is
|
|
512
578
|
* linear and reads no bytes. The full pass re-hashes every member with the
|
|
513
|
-
* verifier's own hasher and grows with the square of the member count.
|
|
579
|
+
* verifier's own hasher and grows with the square of the member count. A
|
|
580
|
+
* set with a hashed member refuses it before any request.
|
|
514
581
|
*/
|
|
515
582
|
verifyMembers?: boolean;
|
|
516
583
|
/** Called as the set advances. A throw inside it is ignored: a progress hook never changes the outcome. */
|
|
@@ -533,7 +600,7 @@ export interface FuseSetMemberResult {
|
|
|
533
600
|
fusedName: string | null;
|
|
534
601
|
/** Advisory; no Frame is written for a set member this phase. */
|
|
535
602
|
frameName: string | null;
|
|
536
|
-
/** Present only when keepFused is true. */
|
|
603
|
+
/** Present only when keepFused is true and the member's bytes passed through the core (never for a hashed member). */
|
|
537
604
|
fusedBytes?: Uint8Array;
|
|
538
605
|
/** Present only with verifyMembers: the verifier's own verdict against this member's fused bytes. Always SET_MEMBER_DIRECT on success, with set.manifestSource "argument". */
|
|
539
606
|
verification?: FuseMemberResult;
|
|
@@ -562,13 +629,28 @@ export interface FuseSetResult {
|
|
|
562
629
|
* Allocate once, fuse every member with the one commitment, hash the set
|
|
563
630
|
* manifest, fill the slot with it. Returns the proof with the manifest bytes
|
|
564
631
|
* beside it, or throws a FuseError; it never commits a partial set and never
|
|
565
|
-
* allocates a second slot.
|
|
632
|
+
* allocates a second slot. Members may be given as bytes, as a loader read
|
|
633
|
+
* one at a time after the slot is held, or as a digest the caller finishes
|
|
634
|
+
* itself; one set may mix them.
|
|
566
635
|
*/
|
|
567
636
|
export async function fuseSet(members: readonly FuseSetMember[], options: FuseSetOptions = {}): Promise<FuseSetResult> {
|
|
568
637
|
// 0. validate, before any request. A refusal here burns nothing.
|
|
569
638
|
if (!Array.isArray(members) || members.length === 0) throw new FuseError("bad-input", "a set lists at least one member");
|
|
570
639
|
if (members.length > MAX_SET_MEMBERS) throw new FuseError("bad-input", `a set lists at most ${MAX_SET_MEMBERS} members (got ${members.length})`);
|
|
571
|
-
|
|
640
|
+
const keep = options.keepFused === true;
|
|
641
|
+
const verifyMembers = options.verifyMembers === true;
|
|
642
|
+
type Kind = "bytes" | "loaded" | "hashed";
|
|
643
|
+
interface Checked {
|
|
644
|
+
kind: Kind;
|
|
645
|
+
placement: Placement;
|
|
646
|
+
id: SetMemberPlacement;
|
|
647
|
+
originDigest: Uint8Array;
|
|
648
|
+
name: string | null;
|
|
649
|
+
original: Uint8Array | null;
|
|
650
|
+
load: (() => Promise<Uint8Array> | Uint8Array) | null;
|
|
651
|
+
builder: FuseBuilder | null;
|
|
652
|
+
fusedDigest: ((input: FusedDigestInput) => Promise<Uint8Array> | Uint8Array) | null;
|
|
653
|
+
}
|
|
572
654
|
const checked: Checked[] = [];
|
|
573
655
|
const seen = new Map<string, number>();
|
|
574
656
|
const report = (phase: FuseSetProgress["phase"], done: number, total: number) => {
|
|
@@ -579,17 +661,23 @@ export async function fuseSet(members: readonly FuseSetMember[], options: FuseSe
|
|
|
579
661
|
// a progress hook never changes the outcome
|
|
580
662
|
}
|
|
581
663
|
};
|
|
664
|
+
const bad = (i: number, message: string) => new FuseError("bad-input", `member ${i}: ${message}`, null, i);
|
|
582
665
|
for (let i = 0; i < members.length; i++) {
|
|
583
|
-
const m = members[i];
|
|
584
|
-
// A null, undefined or missing element is refused like any other member without
|
|
585
|
-
if (m === null || typeof m !== "object"
|
|
586
|
-
const
|
|
666
|
+
const m = members[i] as Partial<FuseSetBytesMember & FuseSetLoadedMember & FuseSetHashedMember> | null | undefined;
|
|
667
|
+
// A null, undefined or missing element is refused like any other member without bytes, a loader or a digest.
|
|
668
|
+
if (m === null || typeof m !== "object") throw bad(i, "original must be a Uint8Array, or load or fusedDigest a function");
|
|
669
|
+
const kind: Kind | null = m.original instanceof Uint8Array ? "bytes" : typeof m.load === "function" ? "loaded" : typeof m.fusedDigest === "function" ? "hashed" : null;
|
|
670
|
+
if (kind === null) throw bad(i, "original must be a Uint8Array, or load or fusedDigest a function");
|
|
671
|
+
if (kind !== "bytes" && m.placement === undefined) throw bad(i, `a ${kind} member names its placement`);
|
|
672
|
+
const id = m.placement ?? placementForBytes(m.original as Uint8Array);
|
|
587
673
|
const placement = getPlacement(id);
|
|
588
674
|
if (placement === undefined) throw new FuseError("bad-placement", `member ${i}: placement "${id}" is not registered`, null, i);
|
|
589
|
-
if (placement.form === "C") throw
|
|
590
|
-
if (m.name !== undefined && typeof m.name !== "string") throw
|
|
591
|
-
if (m.builder !== undefined && typeof m.builder !== "function") throw
|
|
592
|
-
|
|
675
|
+
if (placement.form === "C") throw bad(i, `${id} takes no original; a set holds trailer/1 and container/1 members only`);
|
|
676
|
+
if (m.name !== undefined && typeof m.name !== "string") throw bad(i, "name must be a string");
|
|
677
|
+
if (m.builder !== undefined && typeof m.builder !== "function") throw bad(i, "builder must be a function");
|
|
678
|
+
if (kind !== "bytes" && !(m.originDigest instanceof Uint8Array && m.originDigest.length === 32)) throw bad(i, `a ${kind} member names its originDigest, 32 bytes`);
|
|
679
|
+
if (kind === "hashed" && verifyMembers) throw bad(i, "a hashed member cannot be verified in full; pass its bytes or drop verifyMembers");
|
|
680
|
+
const originDigest = kind === "bytes" ? await digest(m.original as Uint8Array) : (m.originDigest as Uint8Array);
|
|
593
681
|
// The same original under the same placement fuses to the same bytes, which one manifest lists once.
|
|
594
682
|
const key = `${id}:${bytesToHex(originDigest)}`;
|
|
595
683
|
const j = seen.get(key);
|
|
@@ -597,7 +685,17 @@ export async function fuseSet(members: readonly FuseSetMember[], options: FuseSe
|
|
|
597
685
|
throw new FuseError("bad-input", `members ${j} and ${i} are the same original under the same placement (${id}) and would fuse to the same bytes; a set lists each fused artifact once`, null, i);
|
|
598
686
|
}
|
|
599
687
|
seen.set(key, i);
|
|
600
|
-
checked.push({
|
|
688
|
+
checked.push({
|
|
689
|
+
kind,
|
|
690
|
+
placement,
|
|
691
|
+
id,
|
|
692
|
+
originDigest,
|
|
693
|
+
name: m.name ?? null,
|
|
694
|
+
original: kind === "bytes" ? (m.original as Uint8Array) : null,
|
|
695
|
+
load: kind === "loaded" ? (m.load as Checked["load"]) : null,
|
|
696
|
+
builder: kind !== "hashed" && m.builder !== undefined ? (m.builder as FuseBuilder) : null,
|
|
697
|
+
fusedDigest: kind === "hashed" ? (m.fusedDigest as Checked["fusedDigest"]) : null,
|
|
698
|
+
});
|
|
601
699
|
report("hash", i + 1, members.length);
|
|
602
700
|
}
|
|
603
701
|
const t: BoundTransport = { ...DEFAULTS, ...(options.transport ?? {}) };
|
|
@@ -605,41 +703,72 @@ export async function fuseSet(members: readonly FuseSetMember[], options: FuseSe
|
|
|
605
703
|
// 1. nonce: one slot for the whole set
|
|
606
704
|
const slot = await allocateSlot(t);
|
|
607
705
|
|
|
608
|
-
// 2. fuse: the commitment once, every member's
|
|
609
|
-
// is held and its TTL is running; a throw here burns it but commits
|
|
706
|
+
// 2. fuse: the commitment once, every member's digest under it. The slot
|
|
707
|
+
// is held and its TTL is running; a throw here burns it but commits
|
|
708
|
+
// nothing. A member's fused bytes are virtual: each is built, hashed
|
|
709
|
+
// and released in turn, so memory holds one member's bytes at a time.
|
|
710
|
+
// They are held only for a caller who keeps them or asks the full
|
|
711
|
+
// verifier to read them.
|
|
610
712
|
const commitment = computeSlotCommitment(slot);
|
|
611
713
|
const commitmentHex = bytesToHex(commitment);
|
|
612
|
-
const keep = options.keepFused === true;
|
|
613
|
-
const verifyMembers = options.verifyMembers === true;
|
|
614
|
-
// A member's fused bytes are virtual: each is built, hashed and released in
|
|
615
|
-
// turn, so memory holds the originals and one fused copy. They are held only
|
|
616
|
-
// for a caller who keeps them or asks the full verifier to read them.
|
|
617
714
|
const fusedBytes: (Uint8Array | null)[] = [];
|
|
618
715
|
const rows: SetMember[] = [];
|
|
716
|
+
const expiring = "nothing was committed and the slot will expire";
|
|
619
717
|
for (let i = 0; i < checked.length; i++) {
|
|
620
718
|
const c = checked[i]!;
|
|
621
|
-
let
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
719
|
+
let artifact: Uint8Array;
|
|
720
|
+
let held: Uint8Array | null = null;
|
|
721
|
+
if (c.kind === "hashed") {
|
|
722
|
+
let d: unknown;
|
|
723
|
+
try {
|
|
724
|
+
d = await c.fusedDigest!({ commitment, commitmentHex, slot });
|
|
725
|
+
} catch (err) {
|
|
726
|
+
throw new FuseError("builder-failed", `member ${i}: fusedDigest threw: ${err instanceof Error ? err.message : String(err)}; ${expiring}`, null, i);
|
|
727
|
+
}
|
|
728
|
+
if (!(d instanceof Uint8Array) || d.length !== 32) throw new FuseError("builder-failed", `member ${i}: fusedDigest must return a 32-byte digest; ${expiring}`, null, i);
|
|
729
|
+
artifact = d;
|
|
730
|
+
} else {
|
|
731
|
+
let original: Uint8Array;
|
|
732
|
+
if (c.kind === "loaded") {
|
|
733
|
+
let loaded: unknown;
|
|
734
|
+
try {
|
|
735
|
+
loaded = await c.load!();
|
|
736
|
+
} catch (err) {
|
|
737
|
+
throw new FuseError("load-failed", `member ${i}: load threw: ${err instanceof Error ? err.message : String(err)}; ${expiring}`, null, i);
|
|
738
|
+
}
|
|
739
|
+
if (!(loaded instanceof Uint8Array)) throw new FuseError("load-failed", `member ${i}: load must return a Uint8Array; ${expiring}`, null, i);
|
|
740
|
+
original = loaded;
|
|
741
|
+
// The digest the caller named is the row's origin; it must be these bytes' own.
|
|
742
|
+
if (!bytesEqual(await digest(original), c.originDigest)) throw new FuseError("bad-input", `member ${i}: originDigest is not the SHA-256 of the loaded bytes; ${expiring}`, null, i);
|
|
743
|
+
} else {
|
|
744
|
+
original = c.original!;
|
|
745
|
+
}
|
|
746
|
+
const builder = c.builder ?? builderFor(c.id, original);
|
|
747
|
+
let fused: Uint8Array;
|
|
748
|
+
try {
|
|
749
|
+
fused = await builder({ commitment, commitmentHex, originDigest: c.originDigest, slot });
|
|
750
|
+
} catch (err) {
|
|
751
|
+
throw new FuseError("builder-failed", `member ${i}: the builder threw: ${err instanceof Error ? err.message : String(err)}`, null, i);
|
|
752
|
+
}
|
|
753
|
+
if (!(fused instanceof Uint8Array)) throw new FuseError("builder-failed", `member ${i}: the builder must return a Uint8Array`, null, i);
|
|
754
|
+
const located = requireCommitment(c.placement, fused, commitment, i);
|
|
755
|
+
// The row's origin must be the origin the bytes embed, else the member
|
|
756
|
+
// would verify INVALID_ORIGIN_ATTRIBUTION after the slot is spent. Both
|
|
757
|
+
// facts are checked when both are present: the digest the bytes declare
|
|
758
|
+
// (container/1's payload) and the bytes they carry, compared byte for
|
|
759
|
+
// byte with the member's original rather than hashed again, so a builder
|
|
760
|
+
// cannot pack other bytes under the member's digest and leave a member no
|
|
761
|
+
// original rebuilds.
|
|
762
|
+
const declared = located.originDigest;
|
|
763
|
+
const carried = located.originalBytes;
|
|
764
|
+
if ((declared !== undefined && !bytesEqual(declared, c.originDigest)) || (carried !== undefined && !bytesEqual(carried, original))) {
|
|
765
|
+
throw new FuseError("builder-failed", `member ${i}: the fused bytes embed an origin that is not the member's original; ${expiring}`, null, i);
|
|
766
|
+
}
|
|
767
|
+
artifact = await digest(fused);
|
|
768
|
+
if (keep || verifyMembers) held = fused;
|
|
640
769
|
}
|
|
641
|
-
rows.push({ artifact
|
|
642
|
-
fusedBytes.push(
|
|
770
|
+
rows.push({ artifact, origin: c.originDigest, placement: c.id });
|
|
771
|
+
fusedBytes.push(held);
|
|
643
772
|
report("fuse", i + 1, checked.length);
|
|
644
773
|
}
|
|
645
774
|
|
|
@@ -648,7 +777,7 @@ export async function fuseSet(members: readonly FuseSetMember[], options: FuseSe
|
|
|
648
777
|
try {
|
|
649
778
|
manifestBytes = buildSetManifest(commitment, rows);
|
|
650
779
|
} catch (err) {
|
|
651
|
-
throw new FuseError("bad-input", `the set manifest could not be built: ${err instanceof Error ? err.message : String(err)};
|
|
780
|
+
throw new FuseError("bad-input", `the set manifest could not be built: ${err instanceof Error ? err.message : String(err)}; ${expiring}`);
|
|
652
781
|
}
|
|
653
782
|
const artifactDigestB64 = bytesToBase64(await digest(manifestBytes));
|
|
654
783
|
const manifest = JSON.parse(new TextDecoder().decode(manifestBytes)) as SetManifest;
|
|
@@ -712,6 +841,7 @@ export async function fuseSet(members: readonly FuseSetMember[], options: FuseSe
|
|
|
712
841
|
report("verify", i + 1, checked.length);
|
|
713
842
|
}
|
|
714
843
|
const names = c.name !== null ? fusedNamesFor(c.name, c.id) : null;
|
|
844
|
+
const held = fusedBytes[i];
|
|
715
845
|
results.push({
|
|
716
846
|
index: i,
|
|
717
847
|
manifestIndex: k,
|
|
@@ -720,7 +850,7 @@ export async function fuseSet(members: readonly FuseSetMember[], options: FuseSe
|
|
|
720
850
|
artifactDigestB64: memberArtifactB64,
|
|
721
851
|
fusedName: names?.fusedName ?? null,
|
|
722
852
|
frameName: names?.frameName ?? null,
|
|
723
|
-
...(keep ? { fusedBytes:
|
|
853
|
+
...(keep && held !== null ? { fusedBytes: held } : {}),
|
|
724
854
|
...(verification !== undefined ? { verification } : {}),
|
|
725
855
|
});
|
|
726
856
|
}
|
package/src/index.ts
CHANGED
|
@@ -40,9 +40,9 @@ export { Constructor } from "./constructor.js";
|
|
|
40
40
|
// The producer profile over the primitive (working name Fuse): allocate a
|
|
41
41
|
// slot, write a commitment to it into the artifact, hash, commit under the
|
|
42
42
|
// same slot. The resulting proof is ordinary bitgraph/1.
|
|
43
|
-
export { fuse, fuseSet, MAX_SET_MEMBERS, builderFor, FuseError, digestFromBase64, placementForBytes, fusedNamesFor } from "./fuse.js";
|
|
43
|
+
export { fuse, fuseSet, MAX_SET_MEMBERS, trailerBytesFor, builderFor, FuseError, digestFromBase64, placementForBytes, fusedNamesFor } from "./fuse.js";
|
|
44
44
|
export type { FuseBuilder, BuilderInput, FuseOptions, FuseResult, FuseTransport, FuseErrorCode } from "./fuse.js";
|
|
45
|
-
export type { FuseSetMember, SetMemberPlacement, FuseSetOptions, FuseSetProgress, FuseSetMemberResult, FuseSetResult } from "./fuse.js";
|
|
45
|
+
export type { FuseSetMember, FuseSetBytesMember, FuseSetLoadedMember, FuseSetHashedMember, FusedDigestInput, SetMemberPlacement, FuseSetOptions, FuseSetProgress, FuseSetMemberResult, FuseSetResult } from "./fuse.js";
|
|
46
46
|
// The verify-package types those results are made of, so the core entry names everything it returns.
|
|
47
47
|
export type { FuseFrame, PlacementId, SetManifest, FuseMemberResult, FuseVerifyResult } from "@mikeargento/bitgraph-verify";
|
|
48
48
|
|