@kduma-oss/pcf 0.0.5 → 0.0.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.
package/README.md CHANGED
@@ -82,7 +82,7 @@ store.close();
82
82
  ## Project layout
83
83
 
84
84
  ```
85
- implementations/ts/
85
+ implementations/ts/pcf/
86
86
  ├── package.json
87
87
  ├── tsconfig.json
88
88
  ├── vitest.config.ts
package/dist/consts.d.ts CHANGED
@@ -39,4 +39,23 @@ export declare const NIL_UID: Uint8Array;
39
39
  * is a `u8`).
40
40
  */
41
41
  export declare const MAX_ENTRIES_PER_BLOCK = 255;
42
+ /**
43
+ * Sentinel value of `partition_table_offset` (header offset 12) meaning the
44
+ * partition-table head is recorded in the file trailer at the end of the file
45
+ * rather than in the header (spec section 4, "File Trailer"). The all-ones u64
46
+ * can never be a real offset, so it is unambiguous.
47
+ */
48
+ export declare const PT_OFFSET_TRAILER = 18446744073709551615n;
49
+ /** Fixed size of the optional file trailer, in bytes. */
50
+ export declare const TRAILER_SIZE = 20;
51
+ /**
52
+ * Trailer signature, 8 bytes: the file {@link MAGIC} reversed
53
+ * (`0x1A 0x0A 0x0D 'T' 'R' 'P' 'K' 0x89`). Placed as the final 8 bytes of the
54
+ * file so a reader can detect and validate the trailer at the end.
55
+ */
56
+ export declare const TRAILER_MAGIC: Uint8Array;
57
+ /** Chain-direction flag: forward chain, head = first block. */
58
+ export declare const CHAIN_FORWARD = 0;
59
+ /** Chain-direction flag: backward chain, head = last/newest block. */
60
+ export declare const CHAIN_BACKWARD = 1;
42
61
  //# sourceMappingURL=consts.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sEAAsE;AACtE,eAAO,MAAM,KAAK,EAAE,UAElB,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,wDAAwD;AACxD,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,+CAA+C;AAC/C,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,wDAAwD;AACxD,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,+EAA+E;AAC/E,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,mDAAmD;AACnD,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,iDAAiD;AACjD,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B;;;GAGG;AACH,eAAO,MAAM,aAAa,IAAc,CAAC;AACzC;;;GAGG;AACH,eAAO,MAAM,QAAQ,aAAc,CAAC;AAEpC,+DAA+D;AAC/D,eAAO,MAAM,OAAO,EAAE,UAAqC,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC"}
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sEAAsE;AACtE,eAAO,MAAM,KAAK,EAAE,UAElB,CAAC;AAEH,wDAAwD;AACxD,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,wDAAwD;AACxD,eAAO,MAAM,aAAa,IAAI,CAAC;AAE/B,+CAA+C;AAC/C,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,oDAAoD;AACpD,eAAO,MAAM,iBAAiB,KAAK,CAAC;AACpC,wDAAwD;AACxD,eAAO,MAAM,UAAU,MAAM,CAAC;AAE9B,+EAA+E;AAC/E,eAAO,MAAM,eAAe,KAAK,CAAC;AAClC,mDAAmD;AACnD,eAAO,MAAM,UAAU,KAAK,CAAC;AAC7B,iDAAiD;AACjD,eAAO,MAAM,QAAQ,KAAK,CAAC;AAE3B;;;GAGG;AACH,eAAO,MAAM,aAAa,IAAc,CAAC;AACzC;;;GAGG;AACH,eAAO,MAAM,QAAQ,aAAc,CAAC;AAEpC,+DAA+D;AAC/D,eAAO,MAAM,OAAO,EAAE,UAAqC,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,wBAAyB,CAAC;AAExD,yDAAyD;AACzD,eAAO,MAAM,YAAY,KAAK,CAAC;AAE/B;;;;GAIG;AACH,eAAO,MAAM,aAAa,EAAE,UAE1B,CAAC;AAEH,+DAA+D;AAC/D,eAAO,MAAM,aAAa,IAAI,CAAC;AAC/B,sEAAsE;AACtE,eAAO,MAAM,cAAc,IAAI,CAAC"}
package/dist/consts.js CHANGED
@@ -41,4 +41,25 @@ export const NIL_UID = new Uint8Array(UID_SIZE);
41
41
  * is a `u8`).
42
42
  */
43
43
  export const MAX_ENTRIES_PER_BLOCK = 255;
44
+ /**
45
+ * Sentinel value of `partition_table_offset` (header offset 12) meaning the
46
+ * partition-table head is recorded in the file trailer at the end of the file
47
+ * rather than in the header (spec section 4, "File Trailer"). The all-ones u64
48
+ * can never be a real offset, so it is unambiguous.
49
+ */
50
+ export const PT_OFFSET_TRAILER = 0xffffffffffffffffn;
51
+ /** Fixed size of the optional file trailer, in bytes. */
52
+ export const TRAILER_SIZE = 20;
53
+ /**
54
+ * Trailer signature, 8 bytes: the file {@link MAGIC} reversed
55
+ * (`0x1A 0x0A 0x0D 'T' 'R' 'P' 'K' 0x89`). Placed as the final 8 bytes of the
56
+ * file so a reader can detect and validate the trailer at the end.
57
+ */
58
+ export const TRAILER_MAGIC = new Uint8Array([
59
+ 0x1a, 0x0a, 0x0d, 0x54, 0x52, 0x50, 0x4b, 0x89,
60
+ ]);
61
+ /** Chain-direction flag: forward chain, head = first block. */
62
+ export const CHAIN_FORWARD = 0;
63
+ /** Chain-direction flag: backward chain, head = last/newest block. */
64
+ export const CHAIN_BACKWARD = 1;
44
65
  //# sourceMappingURL=consts.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,KAAK,GAAe,IAAI,UAAU,CAAC;IAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CAC/C,CAAC,CAAC;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B,+CAA+C;AAC/C,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,oDAAoD;AACpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,mDAAmD;AACnD,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,iDAAiD;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC;AAEpC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAe,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC"}
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,sEAAsE;AACtE,MAAM,CAAC,MAAM,KAAK,GAAe,IAAI,UAAU,CAAC;IAC9C,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CAC/C,CAAC,CAAC;AAEH,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,wDAAwD;AACxD,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAE/B,+CAA+C;AAC/C,MAAM,CAAC,MAAM,WAAW,GAAG,EAAE,CAAC;AAC9B,oDAAoD;AACpD,MAAM,CAAC,MAAM,iBAAiB,GAAG,EAAE,CAAC;AACpC,wDAAwD;AACxD,MAAM,CAAC,MAAM,UAAU,GAAG,GAAG,CAAC;AAE9B,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,EAAE,CAAC;AAClC,mDAAmD;AACnD,MAAM,CAAC,MAAM,UAAU,GAAG,EAAE,CAAC;AAC7B,iDAAiD;AACjD,MAAM,CAAC,MAAM,QAAQ,GAAG,EAAE,CAAC;AAE3B;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,WAAW,CAAC;AACzC;;;GAGG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,WAAW,CAAC;AAEpC,+DAA+D;AAC/D,MAAM,CAAC,MAAM,OAAO,GAAe,IAAI,UAAU,CAAC,QAAQ,CAAC,CAAC;AAE5D;;;GAGG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAEzC;;;;;GAKG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG,mBAAsB,CAAC;AAExD,yDAAyD;AACzD,MAAM,CAAC,MAAM,YAAY,GAAG,EAAE,CAAC;AAE/B;;;;GAIG;AACH,MAAM,CAAC,MAAM,aAAa,GAAe,IAAI,UAAU,CAAC;IACtD,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI;CAC/C,CAAC,CAAC;AAEH,+DAA+D;AAC/D,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC;AAC/B,sEAAsE;AACtE,MAAM,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC"}
@@ -57,6 +57,14 @@ export declare class Container {
57
57
  private dataEof;
58
58
  private defaultCapacity;
59
59
  private tableHashAlgo;
60
+ /**
61
+ * Resolved absolute offset of the partition-table head: the header pointer
62
+ * for a classic file, or the offset from the file trailer when the header
63
+ * holds {@link PT_OFFSET_TRAILER}. 0 denotes an empty table.
64
+ */
65
+ private tableHeadOffset;
66
+ /** Chain-direction flags resolved at open time (see {@link Trailer}). */
67
+ private chainFlags;
60
68
  private constructor();
61
69
  /**
62
70
  * Create an empty container with sensible defaults (first block capacity 16,
@@ -68,12 +76,45 @@ export declare class Container {
68
76
  * the table-hash algorithm.
69
77
  */
70
78
  static createWith(storage: Storage, firstBlockCapacity: number, tableHashAlgo: HashAlgo): Container;
71
- /** Open an existing container, validating the header (spec C1, C2). */
79
+ /**
80
+ * Open an existing container, validating the header (spec C1, C2).
81
+ *
82
+ * When the header's `partitionTableOffset` is the {@link PT_OFFSET_TRAILER}
83
+ * sentinel, the partition-table head and chain direction are read from the
84
+ * file trailer (located by scanning backward from the end of the file). Chain
85
+ * traversal is identical in both directions (follow `nextTableOffset` until
86
+ * 0); the direction only conveys which end is newest, exposed via
87
+ * {@link Container.chainIsBackward}.
88
+ */
72
89
  static open(storage: Storage): Container;
73
90
  /** Consume the container and return the backing store. */
74
91
  intoStorage(): Storage;
75
- /** The parsed file header. */
92
+ /**
93
+ * The parsed file header. In trailer mode its `partitionTableOffset` holds
94
+ * the {@link PT_OFFSET_TRAILER} sentinel; use {@link Container.tableHead} for
95
+ * the resolved head.
96
+ */
76
97
  header(): FileHeader;
98
+ /**
99
+ * The resolved absolute offset of the partition-table head (0 if empty). This
100
+ * is the value to follow regardless of header-pointer vs trailer mode.
101
+ */
102
+ tableHead(): number;
103
+ /**
104
+ * Whether the chain is backward-linked (head = newest block,
105
+ * `nextTableOffset` points at the previous/older block). Classic
106
+ * header-pointer files are always forward.
107
+ */
108
+ chainIsBackward(): boolean;
109
+ /**
110
+ * Locate the most recent valid file trailer by scanning backward from the end
111
+ * of the file for the last 20-byte window ending in {@link TRAILER_MAGIC}
112
+ * whose recorded head is empty (0) or references a parseable table block.
113
+ * Bytes after that trailer — an incomplete or aborted append — are ignored,
114
+ * which gives append-only writers crash recovery for free. In the clean case
115
+ * the trailer is the final {@link TRAILER_SIZE} bytes.
116
+ */
117
+ private static locateTrailer;
77
118
  private readBlock;
78
119
  private writeBlock;
79
120
  /** All live partition entries, in chain order. */
@@ -120,5 +161,13 @@ export declare class Container {
120
161
  compactedImage(): Uint8Array;
121
162
  /** Write a compacted copy of the container to `out`. */
122
163
  compactInto(out: Storage): void;
164
+ /**
165
+ * Convert the file to trailer mode: append a fixed trailer at the end of the
166
+ * file recording the current partition-table head, then overwrite the
167
+ * header's `partitionTableOffset` with the {@link PT_OFFSET_TRAILER} sentinel
168
+ * so the head is located via that trailer. The chain built by this writer is
169
+ * forward-linked, so the trailer records {@link CHAIN_FORWARD}.
170
+ */
171
+ finalizeWithTrailer(): void;
123
172
  }
124
173
  //# sourceMappingURL=container.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAYH,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA+B,QAAQ,EAAY,MAAM,WAAW,CAAC;AAC5E,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAWpB;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC;IACzB,4CAA4C;IAC5C,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAcD,mDAAmD;AACnD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAW;IAEhC,OAAO;IAkBP;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,GAAE,OAA6B,GAAG,SAAS;IAIhE;;;OAGG;IACH,MAAM,CAAC,UAAU,CACf,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,QAAQ,GACtB,SAAS;IA4BZ,uEAAuE;IACvE,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS;IA2BxC,0DAA0D;IAC1D,WAAW,IAAI,OAAO;IAItB,8BAA8B;IAC9B,MAAM,IAAI,UAAU;IAMpB,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,UAAU;IAyBlB,kDAAkD;IAClD,OAAO,IAAI,cAAc,EAAE;IAW3B;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAKtC,oCAAoC;IACpC,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU;IAQpD,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,UAAU;IAUlB;;;OAGG;IACH,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,MAAM,GAAG,MAAU,EACjC,YAAY,GAAE,QAA0B,GACvC,IAAI;IAuEP;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAmB/D;;;;OAIG;IACH,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAatC;;;OAGG;IACH,MAAM,IAAI,IAAI;IA8Bd;;;;;OAKG;IACH,cAAc,IAAI,UAAU;IAqF5B,wDAAwD;IACxD,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;CAGhC"}
1
+ {"version":3,"file":"container.d.ts","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAgBH,OAAO,EAIL,KAAK,cAAc,EAEpB,MAAM,YAAY,CAAC;AAEpB,OAAO,EAA+B,QAAQ,EAAY,MAAM,WAAW,CAAC;AAC5E,OAAO,EACL,KAAK,UAAU,EAGhB,MAAM,aAAa,CAAC;AACrB,OAAO,EAAiB,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,YAAY,CAAC;AAYpB;;;;;;;;;GASG;AACH,MAAM,WAAW,SAAS;IACxB,+CAA+C;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,mCAAmC;IACnC,MAAM,EAAE,gBAAgB,CAAC;IACzB,4CAA4C;IAC5C,OAAO,EAAE,cAAc,EAAE,CAAC;CAC3B;AAcD,mDAAmD;AACnD,qBAAa,SAAS;IACpB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,MAAM,CAAc;IAC5B,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,aAAa,CAAW;IAChC;;;;OAIG;IACH,OAAO,CAAC,eAAe,CAAe;IACtC,yEAAyE;IACzE,OAAO,CAAC,UAAU,CAAiB;IAEnC,OAAO;IAkBP;;;OAGG;IACH,MAAM,CAAC,MAAM,CAAC,OAAO,GAAE,OAA6B,GAAG,SAAS;IAIhE;;;OAGG;IACH,MAAM,CAAC,UAAU,CACf,OAAO,EAAE,OAAO,EAChB,kBAAkB,EAAE,MAAM,EAC1B,aAAa,EAAE,QAAQ,GACtB,SAAS;IA4BZ;;;;;;;;;OASG;IACH,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,GAAG,SAAS;IAiCxC,0DAA0D;IAC1D,WAAW,IAAI,OAAO;IAItB;;;;OAIG;IACH,MAAM,IAAI,UAAU;IAIpB;;;OAGG;IACH,SAAS,IAAI,MAAM;IAInB;;;;OAIG;IACH,eAAe,IAAI,OAAO;IAI1B;;;;;;;OAOG;IACH,OAAO,CAAC,MAAM,CAAC,aAAa;IAqC5B,OAAO,CAAC,SAAS;IAcjB,OAAO,CAAC,UAAU;IAyBlB,kDAAkD;IAClD,OAAO,IAAI,cAAc,EAAE;IAW3B;;;;;;OAMG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS;IAKtC,oCAAoC;IACpC,iBAAiB,CAAC,KAAK,EAAE,cAAc,GAAG,UAAU;IAQpD,OAAO,CAAC,MAAM;IAcd,OAAO,CAAC,UAAU;IAUlB;;;OAGG;IACH,YAAY,CACV,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,UAAU,EACf,KAAK,EAAE,MAAM,EACb,IAAI,EAAE,UAAU,EAChB,YAAY,GAAE,MAAM,GAAG,MAAU,EACjC,YAAY,GAAE,QAA0B,GACvC,IAAI;IAuEP;;;OAGG;IACH,mBAAmB,CAAC,GAAG,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,GAAG,IAAI;IAmB/D;;;;OAIG;IACH,eAAe,CAAC,GAAG,EAAE,UAAU,GAAG,IAAI;IAatC;;;OAGG;IACH,MAAM,IAAI,IAAI;IA8Bd;;;;;OAKG;IACH,cAAc,IAAI,UAAU;IAqF5B,wDAAwD;IACxD,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI;IAM/B;;;;;;OAMG;IACH,mBAAmB,IAAI,IAAI;CAe5B"}
package/dist/container.js CHANGED
@@ -26,13 +26,14 @@
26
26
  * fresh overflow blocks. {@link Container.compactedImage} rebuilds a tightly
27
27
  * packed file.
28
28
  */
29
- import { ENTRY_SIZE, HEADER_SIZE, MAX_ENTRIES_PER_BLOCK, NIL_UID, TABLE_HEADER_SIZE, TYPE_RESERVED, VERSION_MAJOR, VERSION_MINOR, } from "./consts.js";
29
+ import { CHAIN_FORWARD, ENTRY_SIZE, HEADER_SIZE, MAX_ENTRIES_PER_BLOCK, NIL_UID, PT_OFFSET_TRAILER, TABLE_HEADER_SIZE, TRAILER_MAGIC, TRAILER_SIZE, TYPE_RESERVED, VERSION_MAJOR, VERSION_MINOR, } from "./consts.js";
30
30
  import { encodeLabel, entryFromBytes, entryToBytes, validateEntry, } from "./entry.js";
31
31
  import { PcfError } from "./errors.js";
32
32
  import { computeHashField, digestLen, HashAlgo, verifies } from "./hash.js";
33
33
  import { headerFromBytes, headerToBytes, } from "./header.js";
34
34
  import { MemoryStorage } from "./storage.js";
35
35
  import { computeTableHash, tableHeaderFromBytes, tableHeaderToBytes, } from "./table.js";
36
+ import { trailerFromBytes, trailerToBytes } from "./trailer.js";
36
37
  function bytesEqual(a, b) {
37
38
  if (a.length !== b.length) {
38
39
  return false;
@@ -52,6 +53,14 @@ export class Container {
52
53
  dataEof;
53
54
  defaultCapacity;
54
55
  tableHashAlgo;
56
+ /**
57
+ * Resolved absolute offset of the partition-table head: the header pointer
58
+ * for a classic file, or the offset from the file trailer when the header
59
+ * holds {@link PT_OFFSET_TRAILER}. 0 denotes an empty table.
60
+ */
61
+ tableHeadOffset = HEADER_SIZE;
62
+ /** Chain-direction flags resolved at open time (see {@link Trailer}). */
63
+ chainFlags = CHAIN_FORWARD;
55
64
  constructor(storage, fileHeader, blocks, dataEof, defaultCapacity, tableHashAlgo) {
56
65
  this.storage = storage;
57
66
  this.fileHeader = fileHeader;
@@ -94,13 +103,29 @@ export class Container {
94
103
  ];
95
104
  return new Container(storage, header, blocks, dataEof, cap, tableHashAlgo);
96
105
  }
97
- /** Open an existing container, validating the header (spec C1, C2). */
106
+ /**
107
+ * Open an existing container, validating the header (spec C1, C2).
108
+ *
109
+ * When the header's `partitionTableOffset` is the {@link PT_OFFSET_TRAILER}
110
+ * sentinel, the partition-table head and chain direction are read from the
111
+ * file trailer (located by scanning backward from the end of the file). Chain
112
+ * traversal is identical in both directions (follow `nextTableOffset` until
113
+ * 0); the direction only conveys which end is newest, exposed via
114
+ * {@link Container.chainIsBackward}.
115
+ */
98
116
  static open(storage) {
99
117
  const hb = storage.readAt(0, HEADER_SIZE);
100
118
  const header = headerFromBytes(hb);
101
119
  const me = new Container(storage, header, [], 0, 16, HashAlgo.Sha256);
120
+ if (header.partitionTableOffset === PT_OFFSET_TRAILER) {
121
+ [me.tableHeadOffset, me.chainFlags] = Container.locateTrailer(storage);
122
+ }
123
+ else {
124
+ me.tableHeadOffset = Number(header.partitionTableOffset);
125
+ me.chainFlags = CHAIN_FORWARD;
126
+ }
102
127
  const blocks = [];
103
- let off = Number(header.partitionTableOffset);
128
+ let off = me.tableHeadOffset;
104
129
  while (off !== 0) {
105
130
  const [h] = me.readBlock(off);
106
131
  blocks.push({
@@ -123,10 +148,72 @@ export class Container {
123
148
  intoStorage() {
124
149
  return this.storage;
125
150
  }
126
- /** The parsed file header. */
151
+ /**
152
+ * The parsed file header. In trailer mode its `partitionTableOffset` holds
153
+ * the {@link PT_OFFSET_TRAILER} sentinel; use {@link Container.tableHead} for
154
+ * the resolved head.
155
+ */
127
156
  header() {
128
157
  return this.fileHeader;
129
158
  }
159
+ /**
160
+ * The resolved absolute offset of the partition-table head (0 if empty). This
161
+ * is the value to follow regardless of header-pointer vs trailer mode.
162
+ */
163
+ tableHead() {
164
+ return this.tableHeadOffset;
165
+ }
166
+ /**
167
+ * Whether the chain is backward-linked (head = newest block,
168
+ * `nextTableOffset` points at the previous/older block). Classic
169
+ * header-pointer files are always forward.
170
+ */
171
+ chainIsBackward() {
172
+ return (this.chainFlags & 1) !== 0;
173
+ }
174
+ /**
175
+ * Locate the most recent valid file trailer by scanning backward from the end
176
+ * of the file for the last 20-byte window ending in {@link TRAILER_MAGIC}
177
+ * whose recorded head is empty (0) or references a parseable table block.
178
+ * Bytes after that trailer — an incomplete or aborted append — are ignored,
179
+ * which gives append-only writers crash recovery for free. In the clean case
180
+ * the trailer is the final {@link TRAILER_SIZE} bytes.
181
+ */
182
+ static locateTrailer(storage) {
183
+ let end = storage.size();
184
+ while (end >= TRAILER_SIZE) {
185
+ const start = end - TRAILER_SIZE;
186
+ const window = storage.readAt(start, TRAILER_SIZE);
187
+ let magicOk = true;
188
+ for (let i = 0; i < TRAILER_MAGIC.length; i++) {
189
+ if (window[12 + i] !== TRAILER_MAGIC[i]) {
190
+ magicOk = false;
191
+ break;
192
+ }
193
+ }
194
+ if (magicOk) {
195
+ const t = trailerFromBytes(window);
196
+ if (t.partitionTableOffset === 0n) {
197
+ return [0, t.chainFlags];
198
+ }
199
+ const head = Number(t.partitionTableOffset);
200
+ if (t.partitionTableOffset > 0n && head + TABLE_HEADER_SIZE <= start) {
201
+ try {
202
+ tableHeaderFromBytes(storage.readAt(head, TABLE_HEADER_SIZE));
203
+ return [head, t.chainFlags];
204
+ }
205
+ catch (e) {
206
+ if (!(e instanceof PcfError)) {
207
+ throw e;
208
+ }
209
+ // Spurious magic in an aborted tail; keep scanning.
210
+ }
211
+ }
212
+ }
213
+ end -= 1;
214
+ }
215
+ throw PcfError.badTrailer();
216
+ }
130
217
  // ---- low-level I/O ------------------------------------------------------
131
218
  readBlock(off) {
132
219
  const hb = this.storage.readAt(off, TABLE_HEADER_SIZE);
@@ -159,7 +246,7 @@ export class Container {
159
246
  /** All live partition entries, in chain order. */
160
247
  entries() {
161
248
  const out = [];
162
- let off = Number(this.fileHeader.partitionTableOffset);
249
+ let off = this.tableHeadOffset;
163
250
  while (off !== 0) {
164
251
  const [h, entries] = this.readBlock(off);
165
252
  out.push(...entries);
@@ -187,7 +274,7 @@ export class Container {
187
274
  return this.storage.readAt(Number(entry.startOffset), used);
188
275
  }
189
276
  locate(uid) {
190
- let off = Number(this.fileHeader.partitionTableOffset);
277
+ let off = this.tableHeadOffset;
191
278
  while (off !== 0) {
192
279
  const [h, entries] = this.readBlock(off);
193
280
  for (let i = 0; i < entries.length; i++) {
@@ -314,7 +401,7 @@ export class Container {
314
401
  * hash, and run the per-entry conformance checks (spec section 12).
315
402
  */
316
403
  verify() {
317
- let off = Number(this.fileHeader.partitionTableOffset);
404
+ let off = this.tableHeadOffset;
318
405
  while (off !== 0) {
319
406
  const [h, entries] = this.readBlock(off);
320
407
  if (verifies(h.tableHashAlgo)) {
@@ -346,7 +433,7 @@ export class Container {
346
433
  compactedImage() {
347
434
  // Gather live entries and their data, in chain order.
348
435
  const live = [];
349
- let off = Number(this.fileHeader.partitionTableOffset);
436
+ let off = this.tableHeadOffset;
350
437
  while (off !== 0) {
351
438
  const [h, entries] = this.readBlock(off);
352
439
  for (const e of entries) {
@@ -424,6 +511,29 @@ export class Container {
424
511
  compactInto(out) {
425
512
  out.writeAt(0, this.compactedImage());
426
513
  }
514
+ // ---- trailer mode ------------------------------------------------------
515
+ /**
516
+ * Convert the file to trailer mode: append a fixed trailer at the end of the
517
+ * file recording the current partition-table head, then overwrite the
518
+ * header's `partitionTableOffset` with the {@link PT_OFFSET_TRAILER} sentinel
519
+ * so the head is located via that trailer. The chain built by this writer is
520
+ * forward-linked, so the trailer records {@link CHAIN_FORWARD}.
521
+ */
522
+ finalizeWithTrailer() {
523
+ const trailer = {
524
+ partitionTableOffset: BigInt(this.tableHeadOffset),
525
+ chainFlags: CHAIN_FORWARD,
526
+ };
527
+ const pos = this.storage.size();
528
+ this.storage.writeAt(pos, trailerToBytes(trailer));
529
+ this.fileHeader = {
530
+ ...this.fileHeader,
531
+ partitionTableOffset: PT_OFFSET_TRAILER,
532
+ };
533
+ this.storage.writeAt(0, headerToBytes(this.fileHeader));
534
+ this.chainFlags = CHAIN_FORWARD;
535
+ this.dataEof = pos + TRAILER_SIZE;
536
+ }
427
537
  }
428
538
  function verifyDataHash(e, data) {
429
539
  if (!verifies(e.dataHashAlgo)) {
@@ -1 +1 @@
1
- {"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"container.js","sourceRoot":"","sources":["../src/container.ts"],"names":[],"mappings":"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"}
package/dist/errors.d.ts CHANGED
@@ -28,7 +28,9 @@ export declare enum PcfErrorKind {
28
28
  /** No partition with the requested UID exists. */
29
29
  NotFound = "NotFound",
30
30
  /** An attempt was made to add a partition whose UID already exists. */
31
- DuplicateUid = "DuplicateUid"
31
+ DuplicateUid = "DuplicateUid",
32
+ /** The header requested trailer-based location but no valid trailer exists. */
33
+ BadTrailer = "BadTrailer"
32
34
  }
33
35
  /** All ways a PCF operation can fail. */
34
36
  export declare class PcfError extends Error {
@@ -52,5 +54,6 @@ export declare class PcfError extends Error {
52
54
  static dataTooLarge(): PcfError;
53
55
  static notFound(): PcfError;
54
56
  static duplicateUid(): PcfError;
57
+ static badTrailer(): PcfError;
55
58
  }
56
59
  //# sourceMappingURL=errors.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wEAAwE;AACxE,oBAAY,YAAY;IACtB,8BAA8B;IAC9B,EAAE,OAAO;IACT,kDAAkD;IAClD,QAAQ,aAAa;IACrB,mEAAmE;IACnE,gBAAgB,qBAAqB;IACrC,0DAA0D;IAC1D,eAAe,oBAAoB;IACnC,wDAAwD;IACxD,YAAY,iBAAiB;IAC7B,qCAAqC;IACrC,MAAM,WAAW;IACjB,uDAAuD;IACvD,cAAc,mBAAmB;IACjC,2EAA2E;IAC3E,YAAY,iBAAiB;IAC7B,8CAA8C;IAC9C,iBAAiB,sBAAsB;IACvC,mDAAmD;IACnD,gBAAgB,qBAAqB;IACrC,8EAA8E;IAC9E,YAAY,iBAAiB;IAC7B,kDAAkD;IAClD,QAAQ,aAAa;IACrB,uEAAuE;IACvE,YAAY,iBAAiB;CAC9B;AAED,yCAAyC;AACzC,qBAAa,QAAS,SAAQ,KAAK;IACjC,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAS/D,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ;IAQ5C,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ;IAQ5C,MAAM,CAAC,YAAY,IAAI,QAAQ;IAO/B,MAAM,CAAC,MAAM,IAAI,QAAQ;IAIzB,MAAM,CAAC,cAAc,IAAI,QAAQ;IAOjC,MAAM,CAAC,YAAY,IAAI,QAAQ;IAI/B,MAAM,CAAC,iBAAiB,IAAI,QAAQ;IAOpC,MAAM,CAAC,gBAAgB,IAAI,QAAQ;IAOnC,MAAM,CAAC,YAAY,IAAI,QAAQ;IAO/B,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,YAAY,IAAI,QAAQ;CAGhC"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,wEAAwE;AACxE,oBAAY,YAAY;IACtB,8BAA8B;IAC9B,EAAE,OAAO;IACT,kDAAkD;IAClD,QAAQ,aAAa;IACrB,mEAAmE;IACnE,gBAAgB,qBAAqB;IACrC,0DAA0D;IAC1D,eAAe,oBAAoB;IACnC,wDAAwD;IACxD,YAAY,iBAAiB;IAC7B,qCAAqC;IACrC,MAAM,WAAW;IACjB,uDAAuD;IACvD,cAAc,mBAAmB;IACjC,2EAA2E;IAC3E,YAAY,iBAAiB;IAC7B,8CAA8C;IAC9C,iBAAiB,sBAAsB;IACvC,mDAAmD;IACnD,gBAAgB,qBAAqB;IACrC,8EAA8E;IAC9E,YAAY,iBAAiB;IAC7B,kDAAkD;IAClD,QAAQ,aAAa;IACrB,uEAAuE;IACvE,YAAY,iBAAiB;IAC7B,+EAA+E;IAC/E,UAAU,eAAe;CAC1B;AAED,yCAAyC;AACzC,qBAAa,QAAS,SAAQ,KAAK;IACjC,2BAA2B;IAC3B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC;IAC5B;;;OAGG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;gBAEZ,IAAI,EAAE,YAAY,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAS/D,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,gBAAgB,CAAC,CAAC,EAAE,MAAM,GAAG,QAAQ;IAQ5C,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ;IAQ5C,MAAM,CAAC,YAAY,IAAI,QAAQ;IAO/B,MAAM,CAAC,MAAM,IAAI,QAAQ;IAIzB,MAAM,CAAC,cAAc,IAAI,QAAQ;IAOjC,MAAM,CAAC,YAAY,IAAI,QAAQ;IAI/B,MAAM,CAAC,iBAAiB,IAAI,QAAQ;IAOpC,MAAM,CAAC,gBAAgB,IAAI,QAAQ;IAOnC,MAAM,CAAC,YAAY,IAAI,QAAQ;IAO/B,MAAM,CAAC,QAAQ,IAAI,QAAQ;IAI3B,MAAM,CAAC,YAAY,IAAI,QAAQ;IAI/B,MAAM,CAAC,UAAU,IAAI,QAAQ;CAM9B"}
package/dist/errors.js CHANGED
@@ -30,6 +30,8 @@ export var PcfErrorKind;
30
30
  PcfErrorKind["NotFound"] = "NotFound";
31
31
  /** An attempt was made to add a partition whose UID already exists. */
32
32
  PcfErrorKind["DuplicateUid"] = "DuplicateUid";
33
+ /** The header requested trailer-based location but no valid trailer exists. */
34
+ PcfErrorKind["BadTrailer"] = "BadTrailer";
33
35
  })(PcfErrorKind || (PcfErrorKind = {}));
34
36
  /** All ways a PCF operation can fail. */
35
37
  export class PcfError extends Error {
@@ -84,5 +86,8 @@ export class PcfError extends Error {
84
86
  static duplicateUid() {
85
87
  return new PcfError(PcfErrorKind.DuplicateUid, "duplicate UID");
86
88
  }
89
+ static badTrailer() {
90
+ return new PcfError(PcfErrorKind.BadTrailer, "missing or invalid file trailer");
91
+ }
87
92
  }
88
93
  //# sourceMappingURL=errors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -36,6 +36,7 @@ export { crc32, crc32c, crc64 } from "./crc.js";
36
36
  export { type FileHeader, headerToBytes, headerFromBytes, } from "./header.js";
37
37
  export { type PartitionEntry, entryToBytes, entryFromBytes, validateEntry, freeBytes, entryLabelString, encodeLabel, decodeLabel, } from "./entry.js";
38
38
  export { type TableBlockHeader, tableHeaderToBytes, tableHeaderFromBytes, computeTableHash, } from "./table.js";
39
+ export { type Trailer, trailerToBytes, trailerFromBytes } from "./trailer.js";
39
40
  export { type Storage, MemoryStorage } from "./storage.js";
40
41
  export { NodeFileStorage } from "./node-storage.js";
41
42
  export { Container, type BlockView } from "./container.js";
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,QAAQ,EACR,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,KAAK,UAAU,EACf,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,cAAc,EACnB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,QAAQ,EACR,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EACL,KAAK,UAAU,EACf,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EACL,KAAK,cAAc,EACnB,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EACL,KAAK,gBAAgB,EACrB,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,KAAK,OAAO,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,KAAK,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAE,KAAK,SAAS,EAAE,MAAM,gBAAgB,CAAC"}
package/dist/index.js CHANGED
@@ -36,6 +36,7 @@ export { crc32, crc32c, crc64 } from "./crc.js";
36
36
  export { headerToBytes, headerFromBytes, } from "./header.js";
37
37
  export { entryToBytes, entryFromBytes, validateEntry, freeBytes, entryLabelString, encodeLabel, decodeLabel, } from "./entry.js";
38
38
  export { tableHeaderToBytes, tableHeaderFromBytes, computeTableHash, } from "./table.js";
39
+ export { trailerToBytes, trailerFromBytes } from "./trailer.js";
39
40
  export { MemoryStorage } from "./storage.js";
40
41
  export { NodeFileStorage } from "./node-storage.js";
41
42
  export { Container } from "./container.js";
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,QAAQ,EACR,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAEL,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAEL,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAgB,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AAEH,cAAc,aAAa,CAAC;AAC5B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EACL,QAAQ,EACR,cAAc,EACd,UAAU,EACV,SAAS,EACT,QAAQ,EACR,gBAAgB,EAChB,eAAe,GAChB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAEL,aAAa,EACb,eAAe,GAChB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEL,YAAY,EACZ,cAAc,EACd,aAAa,EACb,SAAS,EACT,gBAAgB,EAChB,WAAW,EACX,WAAW,GACZ,MAAM,YAAY,CAAC;AACpB,OAAO,EAEL,kBAAkB,EAClB,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAgB,cAAc,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAgB,aAAa,EAAE,MAAM,cAAc,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,SAAS,EAAkB,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * The optional fixed 20-byte file trailer (spec section 4, "File Trailer").
3
+ *
4
+ * A trailer is present only when the file header's `partitionTableOffset` holds
5
+ * the {@link PT_OFFSET_TRAILER} sentinel. It occupies the final
6
+ * {@link TRAILER_SIZE} bytes of the file and records the real offset of the
7
+ * partition-table head together with the chain direction. Because every append
8
+ * places a fresh trailer at the new end of file, the file's last bytes always
9
+ * point at the newest table — enabling append-only writers with no in-place
10
+ * header rewrite.
11
+ */
12
+ /** Parsed file trailer. */
13
+ export interface Trailer {
14
+ /** Absolute offset of the partition-table head (0 = empty container). */
15
+ partitionTableOffset: bigint;
16
+ /** Chain-direction flags; bit 0 selects forward (0) or backward (1). */
17
+ chainFlags: number;
18
+ }
19
+ /** Serialise to the on-disk 20-byte layout (reserved bytes 9..12 are zero). */
20
+ export declare function trailerToBytes(t: Trailer): Uint8Array;
21
+ /**
22
+ * Parse from the on-disk 20-byte layout, validating the trailer magic. Throws
23
+ * {@link PcfError} (BadTrailer) if the magic does not match.
24
+ */
25
+ export declare function trailerFromBytes(b: Uint8Array): Trailer;
26
+ //# sourceMappingURL=trailer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trailer.d.ts","sourceRoot":"","sources":["../src/trailer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAKH,2BAA2B;AAC3B,MAAM,WAAW,OAAO;IACtB,yEAAyE;IACzE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,CAAC,EAAE,OAAO,GAAG,UAAU,CAOrD;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,UAAU,GAAG,OAAO,CAWvD"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * The optional fixed 20-byte file trailer (spec section 4, "File Trailer").
3
+ *
4
+ * A trailer is present only when the file header's `partitionTableOffset` holds
5
+ * the {@link PT_OFFSET_TRAILER} sentinel. It occupies the final
6
+ * {@link TRAILER_SIZE} bytes of the file and records the real offset of the
7
+ * partition-table head together with the chain direction. Because every append
8
+ * places a fresh trailer at the new end of file, the file's last bytes always
9
+ * point at the newest table — enabling append-only writers with no in-place
10
+ * header rewrite.
11
+ */
12
+ import { TRAILER_MAGIC, TRAILER_SIZE } from "./consts.js";
13
+ import { PcfError } from "./errors.js";
14
+ /** Serialise to the on-disk 20-byte layout (reserved bytes 9..12 are zero). */
15
+ export function trailerToBytes(t) {
16
+ const b = new Uint8Array(TRAILER_SIZE);
17
+ const view = new DataView(b.buffer);
18
+ view.setBigUint64(0, t.partitionTableOffset, true);
19
+ b[8] = t.chainFlags & 0xff;
20
+ b.set(TRAILER_MAGIC, 12);
21
+ return b;
22
+ }
23
+ /**
24
+ * Parse from the on-disk 20-byte layout, validating the trailer magic. Throws
25
+ * {@link PcfError} (BadTrailer) if the magic does not match.
26
+ */
27
+ export function trailerFromBytes(b) {
28
+ if (b.length < TRAILER_SIZE) {
29
+ throw PcfError.badTrailer();
30
+ }
31
+ for (let i = 0; i < TRAILER_MAGIC.length; i++) {
32
+ if (b[12 + i] !== TRAILER_MAGIC[i]) {
33
+ throw PcfError.badTrailer();
34
+ }
35
+ }
36
+ const view = new DataView(b.buffer, b.byteOffset, b.byteLength);
37
+ return { partitionTableOffset: view.getBigUint64(0, true), chainFlags: b[8] };
38
+ }
39
+ //# sourceMappingURL=trailer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trailer.js","sourceRoot":"","sources":["../src/trailer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAUvC,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,CAAU;IACvC,MAAM,CAAC,GAAG,IAAI,UAAU,CAAC,YAAY,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACpC,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,CAAC,CAAC,oBAAoB,EAAE,IAAI,CAAC,CAAC;IACnD,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,UAAU,GAAG,IAAI,CAAC;IAC3B,CAAC,CAAC,GAAG,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC;IACzB,OAAO,CAAC,CAAC;AACX,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB,CAAC,CAAa;IAC5C,IAAI,CAAC,CAAC,MAAM,GAAG,YAAY,EAAE,CAAC;QAC5B,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;IAC9B,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,aAAa,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAC9C,IAAI,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,QAAQ,CAAC,UAAU,EAAE,CAAC;QAC9B,CAAC;IACH,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,CAAC,CAAC;IAChE,OAAO,EAAE,oBAAoB,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,UAAU,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC;AACjF,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kduma-oss/pcf",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "TypeScript implementation of the Partitioned Container Format (PCF) v1.0",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "author": "Krystian Duma",
@@ -21,7 +21,7 @@
21
21
  "repository": {
22
22
  "type": "git",
23
23
  "url": "git+https://github.com/kduma-OSS/Partitioned-Container-Format.git",
24
- "directory": "implementations/ts"
24
+ "directory": "implementations/ts/pcf"
25
25
  },
26
26
  "bugs": {
27
27
  "url": "https://github.com/kduma-OSS/Partitioned-Container-Format/issues"
package/src/consts.ts CHANGED
@@ -48,3 +48,28 @@ export const NIL_UID: Uint8Array = new Uint8Array(UID_SIZE);
48
48
  * is a `u8`).
49
49
  */
50
50
  export const MAX_ENTRIES_PER_BLOCK = 255;
51
+
52
+ /**
53
+ * Sentinel value of `partition_table_offset` (header offset 12) meaning the
54
+ * partition-table head is recorded in the file trailer at the end of the file
55
+ * rather than in the header (spec section 4, "File Trailer"). The all-ones u64
56
+ * can never be a real offset, so it is unambiguous.
57
+ */
58
+ export const PT_OFFSET_TRAILER = 0xffff_ffff_ffff_ffffn;
59
+
60
+ /** Fixed size of the optional file trailer, in bytes. */
61
+ export const TRAILER_SIZE = 20;
62
+
63
+ /**
64
+ * Trailer signature, 8 bytes: the file {@link MAGIC} reversed
65
+ * (`0x1A 0x0A 0x0D 'T' 'R' 'P' 'K' 0x89`). Placed as the final 8 bytes of the
66
+ * file so a reader can detect and validate the trailer at the end.
67
+ */
68
+ export const TRAILER_MAGIC: Uint8Array = new Uint8Array([
69
+ 0x1a, 0x0a, 0x0d, 0x54, 0x52, 0x50, 0x4b, 0x89,
70
+ ]);
71
+
72
+ /** Chain-direction flag: forward chain, head = first block. */
73
+ export const CHAIN_FORWARD = 0;
74
+ /** Chain-direction flag: backward chain, head = last/newest block. */
75
+ export const CHAIN_BACKWARD = 1;
package/src/container.ts CHANGED
@@ -28,11 +28,15 @@
28
28
  */
29
29
 
30
30
  import {
31
+ CHAIN_FORWARD,
31
32
  ENTRY_SIZE,
32
33
  HEADER_SIZE,
33
34
  MAX_ENTRIES_PER_BLOCK,
34
35
  NIL_UID,
36
+ PT_OFFSET_TRAILER,
35
37
  TABLE_HEADER_SIZE,
38
+ TRAILER_MAGIC,
39
+ TRAILER_SIZE,
36
40
  TYPE_RESERVED,
37
41
  VERSION_MAJOR,
38
42
  VERSION_MINOR,
@@ -58,6 +62,7 @@ import {
58
62
  tableHeaderToBytes,
59
63
  type TableBlockHeader,
60
64
  } from "./table.js";
65
+ import { type Trailer, trailerFromBytes, trailerToBytes } from "./trailer.js";
61
66
 
62
67
  /** In-memory bookkeeping for one table block (not stored on disk). */
63
68
  interface BlockInfo {
@@ -107,6 +112,14 @@ export class Container {
107
112
  private dataEof: number;
108
113
  private defaultCapacity: number;
109
114
  private tableHashAlgo: HashAlgo;
115
+ /**
116
+ * Resolved absolute offset of the partition-table head: the header pointer
117
+ * for a classic file, or the offset from the file trailer when the header
118
+ * holds {@link PT_OFFSET_TRAILER}. 0 denotes an empty table.
119
+ */
120
+ private tableHeadOffset = HEADER_SIZE;
121
+ /** Chain-direction flags resolved at open time (see {@link Trailer}). */
122
+ private chainFlags = CHAIN_FORWARD;
110
123
 
111
124
  private constructor(
112
125
  storage: Storage,
@@ -170,15 +183,30 @@ export class Container {
170
183
  return new Container(storage, header, blocks, dataEof, cap, tableHashAlgo);
171
184
  }
172
185
 
173
- /** Open an existing container, validating the header (spec C1, C2). */
186
+ /**
187
+ * Open an existing container, validating the header (spec C1, C2).
188
+ *
189
+ * When the header's `partitionTableOffset` is the {@link PT_OFFSET_TRAILER}
190
+ * sentinel, the partition-table head and chain direction are read from the
191
+ * file trailer (located by scanning backward from the end of the file). Chain
192
+ * traversal is identical in both directions (follow `nextTableOffset` until
193
+ * 0); the direction only conveys which end is newest, exposed via
194
+ * {@link Container.chainIsBackward}.
195
+ */
174
196
  static open(storage: Storage): Container {
175
197
  const hb = storage.readAt(0, HEADER_SIZE);
176
198
  const header = headerFromBytes(hb);
177
199
 
178
200
  const me = new Container(storage, header, [], 0, 16, HashAlgo.Sha256);
201
+ if (header.partitionTableOffset === PT_OFFSET_TRAILER) {
202
+ [me.tableHeadOffset, me.chainFlags] = Container.locateTrailer(storage);
203
+ } else {
204
+ me.tableHeadOffset = Number(header.partitionTableOffset);
205
+ me.chainFlags = CHAIN_FORWARD;
206
+ }
179
207
 
180
208
  const blocks: BlockInfo[] = [];
181
- let off = Number(header.partitionTableOffset);
209
+ let off = me.tableHeadOffset;
182
210
  while (off !== 0) {
183
211
  const [h] = me.readBlock(off);
184
212
  blocks.push({
@@ -203,11 +231,75 @@ export class Container {
203
231
  return this.storage;
204
232
  }
205
233
 
206
- /** The parsed file header. */
234
+ /**
235
+ * The parsed file header. In trailer mode its `partitionTableOffset` holds
236
+ * the {@link PT_OFFSET_TRAILER} sentinel; use {@link Container.tableHead} for
237
+ * the resolved head.
238
+ */
207
239
  header(): FileHeader {
208
240
  return this.fileHeader;
209
241
  }
210
242
 
243
+ /**
244
+ * The resolved absolute offset of the partition-table head (0 if empty). This
245
+ * is the value to follow regardless of header-pointer vs trailer mode.
246
+ */
247
+ tableHead(): number {
248
+ return this.tableHeadOffset;
249
+ }
250
+
251
+ /**
252
+ * Whether the chain is backward-linked (head = newest block,
253
+ * `nextTableOffset` points at the previous/older block). Classic
254
+ * header-pointer files are always forward.
255
+ */
256
+ chainIsBackward(): boolean {
257
+ return (this.chainFlags & 1) !== 0;
258
+ }
259
+
260
+ /**
261
+ * Locate the most recent valid file trailer by scanning backward from the end
262
+ * of the file for the last 20-byte window ending in {@link TRAILER_MAGIC}
263
+ * whose recorded head is empty (0) or references a parseable table block.
264
+ * Bytes after that trailer — an incomplete or aborted append — are ignored,
265
+ * which gives append-only writers crash recovery for free. In the clean case
266
+ * the trailer is the final {@link TRAILER_SIZE} bytes.
267
+ */
268
+ private static locateTrailer(storage: Storage): [number, number] {
269
+ let end = storage.size();
270
+ while (end >= TRAILER_SIZE) {
271
+ const start = end - TRAILER_SIZE;
272
+ const window = storage.readAt(start, TRAILER_SIZE);
273
+ let magicOk = true;
274
+ for (let i = 0; i < TRAILER_MAGIC.length; i++) {
275
+ if (window[12 + i] !== TRAILER_MAGIC[i]) {
276
+ magicOk = false;
277
+ break;
278
+ }
279
+ }
280
+ if (magicOk) {
281
+ const t = trailerFromBytes(window);
282
+ if (t.partitionTableOffset === 0n) {
283
+ return [0, t.chainFlags];
284
+ }
285
+ const head = Number(t.partitionTableOffset);
286
+ if (t.partitionTableOffset > 0n && head + TABLE_HEADER_SIZE <= start) {
287
+ try {
288
+ tableHeaderFromBytes(storage.readAt(head, TABLE_HEADER_SIZE));
289
+ return [head, t.chainFlags];
290
+ } catch (e) {
291
+ if (!(e instanceof PcfError)) {
292
+ throw e;
293
+ }
294
+ // Spurious magic in an aborted tail; keep scanning.
295
+ }
296
+ }
297
+ }
298
+ end -= 1;
299
+ }
300
+ throw PcfError.badTrailer();
301
+ }
302
+
211
303
  // ---- low-level I/O ------------------------------------------------------
212
304
 
213
305
  private readBlock(off: number): [TableBlockHeader, PartitionEntry[]] {
@@ -252,7 +344,7 @@ export class Container {
252
344
  /** All live partition entries, in chain order. */
253
345
  entries(): PartitionEntry[] {
254
346
  const out: PartitionEntry[] = [];
255
- let off = Number(this.fileHeader.partitionTableOffset);
347
+ let off = this.tableHeadOffset;
256
348
  while (off !== 0) {
257
349
  const [h, entries] = this.readBlock(off);
258
350
  out.push(...entries);
@@ -283,7 +375,7 @@ export class Container {
283
375
  }
284
376
 
285
377
  private locate(uid: Uint8Array): [number, number, PartitionEntry] {
286
- let off = Number(this.fileHeader.partitionTableOffset);
378
+ let off = this.tableHeadOffset;
287
379
  while (off !== 0) {
288
380
  const [h, entries] = this.readBlock(off);
289
381
  for (let i = 0; i < entries.length; i++) {
@@ -434,7 +526,7 @@ export class Container {
434
526
  * hash, and run the per-entry conformance checks (spec section 12).
435
527
  */
436
528
  verify(): void {
437
- let off = Number(this.fileHeader.partitionTableOffset);
529
+ let off = this.tableHeadOffset;
438
530
  while (off !== 0) {
439
531
  const [h, entries] = this.readBlock(off);
440
532
  if (verifies(h.tableHashAlgo)) {
@@ -472,7 +564,7 @@ export class Container {
472
564
  compactedImage(): Uint8Array {
473
565
  // Gather live entries and their data, in chain order.
474
566
  const live: Array<{ entry: PartitionEntry; data: Uint8Array }> = [];
475
- let off = Number(this.fileHeader.partitionTableOffset);
567
+ let off = this.tableHeadOffset;
476
568
  while (off !== 0) {
477
569
  const [h, entries] = this.readBlock(off);
478
570
  for (const e of entries) {
@@ -558,6 +650,31 @@ export class Container {
558
650
  compactInto(out: Storage): void {
559
651
  out.writeAt(0, this.compactedImage());
560
652
  }
653
+
654
+ // ---- trailer mode ------------------------------------------------------
655
+
656
+ /**
657
+ * Convert the file to trailer mode: append a fixed trailer at the end of the
658
+ * file recording the current partition-table head, then overwrite the
659
+ * header's `partitionTableOffset` with the {@link PT_OFFSET_TRAILER} sentinel
660
+ * so the head is located via that trailer. The chain built by this writer is
661
+ * forward-linked, so the trailer records {@link CHAIN_FORWARD}.
662
+ */
663
+ finalizeWithTrailer(): void {
664
+ const trailer: Trailer = {
665
+ partitionTableOffset: BigInt(this.tableHeadOffset),
666
+ chainFlags: CHAIN_FORWARD,
667
+ };
668
+ const pos = this.storage.size();
669
+ this.storage.writeAt(pos, trailerToBytes(trailer));
670
+ this.fileHeader = {
671
+ ...this.fileHeader,
672
+ partitionTableOffset: PT_OFFSET_TRAILER,
673
+ };
674
+ this.storage.writeAt(0, headerToBytes(this.fileHeader));
675
+ this.chainFlags = CHAIN_FORWARD;
676
+ this.dataEof = pos + TRAILER_SIZE;
677
+ }
561
678
  }
562
679
 
563
680
  function verifyDataHash(e: PartitionEntry, data: Uint8Array): boolean {
package/src/errors.ts CHANGED
@@ -30,6 +30,8 @@ export enum PcfErrorKind {
30
30
  NotFound = "NotFound",
31
31
  /** An attempt was made to add a partition whose UID already exists. */
32
32
  DuplicateUid = "DuplicateUid",
33
+ /** The header requested trailer-based location but no valid trailer exists. */
34
+ BadTrailer = "BadTrailer",
33
35
  }
34
36
 
35
37
  /** All ways a PCF operation can fail. */
@@ -121,4 +123,11 @@ export class PcfError extends Error {
121
123
  static duplicateUid(): PcfError {
122
124
  return new PcfError(PcfErrorKind.DuplicateUid, "duplicate UID");
123
125
  }
126
+
127
+ static badTrailer(): PcfError {
128
+ return new PcfError(
129
+ PcfErrorKind.BadTrailer,
130
+ "missing or invalid file trailer",
131
+ );
132
+ }
124
133
  }
package/src/index.ts CHANGED
@@ -63,6 +63,7 @@ export {
63
63
  tableHeaderFromBytes,
64
64
  computeTableHash,
65
65
  } from "./table.js";
66
+ export { type Trailer, trailerToBytes, trailerFromBytes } from "./trailer.js";
66
67
  export { type Storage, MemoryStorage } from "./storage.js";
67
68
  export { NodeFileStorage } from "./node-storage.js";
68
69
  export { Container, type BlockView } from "./container.js";
package/src/trailer.ts ADDED
@@ -0,0 +1,49 @@
1
+ /**
2
+ * The optional fixed 20-byte file trailer (spec section 4, "File Trailer").
3
+ *
4
+ * A trailer is present only when the file header's `partitionTableOffset` holds
5
+ * the {@link PT_OFFSET_TRAILER} sentinel. It occupies the final
6
+ * {@link TRAILER_SIZE} bytes of the file and records the real offset of the
7
+ * partition-table head together with the chain direction. Because every append
8
+ * places a fresh trailer at the new end of file, the file's last bytes always
9
+ * point at the newest table — enabling append-only writers with no in-place
10
+ * header rewrite.
11
+ */
12
+
13
+ import { TRAILER_MAGIC, TRAILER_SIZE } from "./consts.js";
14
+ import { PcfError } from "./errors.js";
15
+
16
+ /** Parsed file trailer. */
17
+ export interface Trailer {
18
+ /** Absolute offset of the partition-table head (0 = empty container). */
19
+ partitionTableOffset: bigint;
20
+ /** Chain-direction flags; bit 0 selects forward (0) or backward (1). */
21
+ chainFlags: number;
22
+ }
23
+
24
+ /** Serialise to the on-disk 20-byte layout (reserved bytes 9..12 are zero). */
25
+ export function trailerToBytes(t: Trailer): Uint8Array {
26
+ const b = new Uint8Array(TRAILER_SIZE);
27
+ const view = new DataView(b.buffer);
28
+ view.setBigUint64(0, t.partitionTableOffset, true);
29
+ b[8] = t.chainFlags & 0xff;
30
+ b.set(TRAILER_MAGIC, 12);
31
+ return b;
32
+ }
33
+
34
+ /**
35
+ * Parse from the on-disk 20-byte layout, validating the trailer magic. Throws
36
+ * {@link PcfError} (BadTrailer) if the magic does not match.
37
+ */
38
+ export function trailerFromBytes(b: Uint8Array): Trailer {
39
+ if (b.length < TRAILER_SIZE) {
40
+ throw PcfError.badTrailer();
41
+ }
42
+ for (let i = 0; i < TRAILER_MAGIC.length; i++) {
43
+ if (b[12 + i] !== TRAILER_MAGIC[i]) {
44
+ throw PcfError.badTrailer();
45
+ }
46
+ }
47
+ const view = new DataView(b.buffer, b.byteOffset, b.byteLength);
48
+ return { partitionTableOffset: view.getBigUint64(0, true), chainFlags: b[8]! };
49
+ }