keyframe-store 3.2.0 → 3.3.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/README.md CHANGED
@@ -78,14 +78,14 @@ We highly recommend you take a look at the [documentation](https://esposter.com/
78
78
 
79
79
  ### Key exports
80
80
 
81
- | Export | Role |
82
- | ---------------------- | --------------------------------------------------------------------------------------------------- |
83
- | `createKeyframeStore` | The factory, taking an `ObjectStore` and optional `KeyframeStoreOptions` |
84
- | `ObjectStore` | The backend interface — `read`, `write`, `delete` by key |
85
- | `KeyframeStore` | `write(plaintext, anchor)`, `read(hash)`, `collect(released, retained)` — every one a `ResultAsync` |
86
- | `VersionAnchor` | What a lineage passes to a write: its keyframe's hash and the bytes anchored to it |
87
- | `WrittenVersion` | What a write reports: the hash, its base, both sizes and whether it was deduplicated |
88
- | `KeyframeStoreOptions` | `compressionLevel`, `promotionRatio`, `segmentBudgetRatio`, each defaulted from `constants` |
81
+ | Export | Role |
82
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
83
+ | `createKeyframeStore` | The factory, taking an `ObjectStore` and optional `KeyframeStoreOptions` |
84
+ | `ObjectStore` | The backend interface — `read`, `write`, `delete` by key |
85
+ | `KeyframeStore` | `write(plaintext, anchor)`, `read(hash)`, `collect(released, retained)` — every one a `ResultAsync` |
86
+ | `VersionAnchor` | What a lineage passes to a write: its keyframe's hash and the bytes anchored to it |
87
+ | `WrittenVersion` | What a write reports: the hash, its base, both sizes and whether it was deduplicated |
88
+ | `KeyframeStoreOptions` | `compressionLevel`, `promotionRatio`, `segmentBudgetRatio`, each defaulted from `constants` — the level from `@esposter/shared`'s, which the app's browser encoder shares |
89
89
 
90
90
  ### Commands
91
91
 
package/dist/index.d.ts CHANGED
@@ -11,9 +11,6 @@ export declare const KEYFRAME_FLAG = 0;
11
11
  export declare const DELTA_FLAG = 1;
12
12
  export declare const HASH_BYTE_COUNT = 32;
13
13
  export declare const DELTA_HEADER_BYTE_COUNT: number;
14
- export declare const DEFAULT_COMPRESSION_LEVEL = 12;
15
- export declare const MIN_WINDOW_LOG = 10;
16
- export declare const MAX_WINDOW_LOG = 27;
17
14
  export declare const DEFAULT_PROMOTION_RATIO: number;
18
15
  export declare const DEFAULT_SEGMENT_BUDGET_RATIO = 1;
19
16
  //#endregion
@@ -80,9 +77,6 @@ export declare const encodeObject: (plaintext: Uint8Array, compressionLevel: num
80
77
  //#region src/services/getContentAddress.d.ts
81
78
  export declare const getContentAddress: (plaintext: Uint8Array) => string;
82
79
  //#endregion
83
- //#region src/services/getWindowLog.d.ts
84
- export declare const getWindowLog: (dictionaryByteCount: number, inputByteCount: number) => number;
85
- //#endregion
86
80
  //#region src/services/parseObject.d.ts
87
81
  export declare const parseObject: (hash: string, bytes: Uint8Array) => ParsedObject;
88
82
  //#endregion
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- import { InvalidOperationError, Operation, getResultAsync } from "@esposter/shared";
1
+ import { DEFAULT_COMPRESSION_LEVEL, InvalidOperationError, Operation, getResultAsync, getWindowLog } from "@esposter/shared";
2
2
  import { promisify } from "node:util";
3
3
  import { constants, zstdCompress, zstdDecompress } from "node:zlib";
4
4
  import { createHash } from "node:crypto";
@@ -18,9 +18,6 @@ const KEYFRAME_FLAG = 0;
18
18
  const DELTA_FLAG = 1;
19
19
  const HASH_BYTE_COUNT = 32;
20
20
  const DELTA_HEADER_BYTE_COUNT = 40;
21
- const DEFAULT_COMPRESSION_LEVEL = 12;
22
- const MIN_WINDOW_LOG = 10;
23
- const MAX_WINDOW_LOG = 27;
24
21
  const DEFAULT_PROMOTION_RATIO = 1 / 3;
25
22
  const DEFAULT_SEGMENT_BUDGET_RATIO = 1;
26
23
  //#endregion
@@ -39,9 +36,6 @@ const decodeObject = (parsedObject, basePlaintext) => decompress(parsedObject.pa
39
36
  params: { [constants.ZSTD_d_windowLogMax]: parsedObject.windowLog }
40
37
  });
41
38
  //#endregion
42
- //#region src/services/getWindowLog.ts
43
- const getWindowLog = (dictionaryByteCount, inputByteCount) => Math.min(27, Math.max(10, Math.ceil(Math.log2(dictionaryByteCount + inputByteCount + 1))));
44
- //#endregion
45
39
  //#region src/services/encodeObject.ts
46
40
  const compress = promisify(zstdCompress);
47
41
  const encodeObject = async (plaintext, compressionLevel, base) => {
@@ -88,18 +82,19 @@ const parseObject = (hash, bytes) => {
88
82
  };
89
83
  //#endregion
90
84
  //#region src/createKeyframeStore.ts
91
- const verifyContentAddress = (hash, plaintext) => {
85
+ const decodeVerifiedObject = async (hash, parsedObject, basePlaintext) => {
86
+ const plaintext = await decodeObject(parsedObject, basePlaintext);
92
87
  if (getContentAddress(plaintext) !== hash) throw new InvalidOperationError(Operation.Read, hash, "object does not hash to its key");
93
88
  return plaintext;
94
89
  };
95
- const createKeyframeStore = (objectStore, { compressionLevel = 12, promotionRatio = DEFAULT_PROMOTION_RATIO, segmentBudgetRatio = 1 } = {}) => {
90
+ const createKeyframeStore = (objectStore, { compressionLevel = DEFAULT_COMPRESSION_LEVEL, promotionRatio = DEFAULT_PROMOTION_RATIO, segmentBudgetRatio = 1 } = {}) => {
96
91
  const readKeyframe = async (hash) => {
97
92
  const bytes = await objectStore.read(hash);
98
93
  if (!bytes) return void 0;
99
94
  const parsedObject = parseObject(hash, bytes);
100
95
  if (parsedObject.baseHash) throw new InvalidOperationError(Operation.Read, hash, `is a delta against ${parsedObject.baseHash}, not a keyframe`);
101
96
  return {
102
- plaintext: verifyContentAddress(hash, await decodeObject(parsedObject)),
97
+ plaintext: await decodeVerifiedObject(hash, parsedObject),
103
98
  storedBytes: bytes.byteLength
104
99
  };
105
100
  };
@@ -109,13 +104,13 @@ const createKeyframeStore = (objectStore, { compressionLevel = 12, promotionRati
109
104
  const parsedObject = parseObject(hash, bytes);
110
105
  if (!parsedObject.baseHash) return {
111
106
  baseHash: "",
112
- plaintext: verifyContentAddress(hash, await decodeObject(parsedObject))
107
+ plaintext: await decodeVerifiedObject(hash, parsedObject)
113
108
  };
114
109
  const keyframe = await readKeyframe(parsedObject.baseHash);
115
110
  if (!keyframe) throw new ObjectNotStoredError(hash, `keyframe ${parsedObject.baseHash} is not stored`);
116
111
  return {
117
112
  baseHash: parsedObject.baseHash,
118
- plaintext: verifyContentAddress(hash, await decodeObject(parsedObject, keyframe.plaintext))
113
+ plaintext: await decodeVerifiedObject(hash, parsedObject, keyframe.plaintext)
119
114
  };
120
115
  };
121
116
  return {
@@ -172,9 +167,9 @@ const createKeyframeStore = (objectStore, { compressionLevel = 12, promotionRati
172
167
  const isWithinPromotionRatio = delta.bytes.byteLength <= keyframeBytes.byteLength * promotionRatio;
173
168
  const isWithinSegmentBudget = anchor.anchoredBytes + delta.bytes.byteLength <= delta.keyframeStoredBytes * segmentBudgetRatio;
174
169
  if (!isWithinPromotionRatio || !isWithinSegmentBudget) return writeObject(keyframeBytes, "");
175
- return writeObject(delta.bytes, anchor.hash);
170
+ else return writeObject(delta.bytes, anchor.hash);
176
171
  })
177
172
  };
178
173
  };
179
174
  //#endregion
180
- export { DEFAULT_COMPRESSION_LEVEL, DEFAULT_PROMOTION_RATIO, DEFAULT_SEGMENT_BUDGET_RATIO, DELTA_FLAG, DELTA_HEADER_BYTE_COUNT, HASH_BYTE_COUNT, KEYFRAME_FLAG, MAX_WINDOW_LOG, MIN_WINDOW_LOG, OBJECT_FLAGS_OFFSET, OBJECT_FORMAT_VERSION, OBJECT_HEADER_BYTE_COUNT, OBJECT_MAGIC, OBJECT_VERSION_OFFSET, OBJECT_WINDOW_LOG_OFFSET, ObjectNotStoredError, createKeyframeStore, decodeObject, encodeObject, getContentAddress, getWindowLog, parseObject };
175
+ export { DEFAULT_PROMOTION_RATIO, DEFAULT_SEGMENT_BUDGET_RATIO, DELTA_FLAG, DELTA_HEADER_BYTE_COUNT, HASH_BYTE_COUNT, KEYFRAME_FLAG, OBJECT_FLAGS_OFFSET, OBJECT_FORMAT_VERSION, OBJECT_HEADER_BYTE_COUNT, OBJECT_MAGIC, OBJECT_VERSION_OFFSET, OBJECT_WINDOW_LOG_OFFSET, ObjectNotStoredError, createKeyframeStore, decodeObject, encodeObject, getContentAddress, parseObject };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "keyframe-store",
3
- "version": "3.2.0",
3
+ "version": "3.3.0",
4
4
  "description": "Content-addressed version storage — every version is a zstd keyframe or a delta against one, over any backend that can store bytes by key.",
5
5
  "keywords": [
6
6
  "compression",
@@ -53,17 +53,17 @@
53
53
  "typecheck": "tsc"
54
54
  },
55
55
  "dependencies": {
56
- "@esposter/shared": "3.2.0",
56
+ "@esposter/shared": "3.3.0",
57
57
  "neverthrow": "^8.2.0"
58
58
  },
59
59
  "devDependencies": {
60
60
  "@arethetypeswrong/core": "^0.18.5",
61
- "@esposter/configuration": "3.2.0",
62
- "@esposter/shared-node": "3.2.0",
63
- "@types/node": "^26.6.1",
61
+ "@esposter/configuration": "3.3.0",
62
+ "@esposter/shared-node": "3.3.0",
63
+ "@types/node": "^26.6.3",
64
64
  "publint": "^0.3.24",
65
65
  "tsdown": "^0.23.0",
66
- "vitest": "^5.0.1"
66
+ "vitest": "^5.0.2"
67
67
  },
68
- "gitHead": "bc055ed2f154eff219a355016a6b586962dbfa9c"
68
+ "gitHead": "5854a00717502d8de96adc8b44d3621ab85f9b57"
69
69
  }