@amalgm/live 0.2.17 → 0.2.18
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/PURPOSE.md
CHANGED
|
@@ -154,6 +154,10 @@ its cutover.
|
|
|
154
154
|
content-addressed block identities, while cold upload and download move
|
|
155
155
|
adjacent missing blocks in bounded binary batches. Batching may reduce
|
|
156
156
|
transport work but can never weaken per-block verification or commit order.
|
|
157
|
+
32. **A content layout owns a cloud namespace.** A writer change that derives
|
|
158
|
+
different block identities for the same complete bytes advances the
|
|
159
|
+
content contract and storage namespace together. Readers remain additive;
|
|
160
|
+
an immutable manifest is never reinterpreted or overwritten in place.
|
|
157
161
|
|
|
158
162
|
## Five surfaces, one behavior
|
|
159
163
|
|
|
@@ -10,7 +10,12 @@
|
|
|
10
10
|
* host effects; this file owns the shape and its laws.
|
|
11
11
|
*/
|
|
12
12
|
import { type Checked } from './validate.js';
|
|
13
|
-
|
|
13
|
+
/** Version 3 changes only the canonical writer layout: ordinary files begin
|
|
14
|
+
* at Dropbox's stable 4 MiB block size. Version 2 remains readable because
|
|
15
|
+
* immutable cloud heads created by an older writer must still materialize. */
|
|
16
|
+
export declare const LEGACY_CONTENT_CONTRACT = "amalgm-entity-content@2";
|
|
17
|
+
export declare const CONTENT_CONTRACT = "amalgm-entity-content@3";
|
|
18
|
+
export type ContentContract = typeof CONTENT_CONTRACT | typeof LEGACY_CONTENT_CONTRACT;
|
|
14
19
|
export declare const MIN_CONTENT_BLOCK_BYTES: number;
|
|
15
20
|
export declare const MAX_CONTENT_BLOCK_BYTES: number;
|
|
16
21
|
/** Maximum accepted block size. Kept as the public manifest-bound name. */
|
|
@@ -21,7 +26,7 @@ export interface ContentChunk {
|
|
|
21
26
|
readonly bytes: number;
|
|
22
27
|
}
|
|
23
28
|
export interface ContentManifest {
|
|
24
|
-
readonly contract:
|
|
29
|
+
readonly contract: ContentContract;
|
|
25
30
|
readonly contentHash: string;
|
|
26
31
|
readonly bytes: number;
|
|
27
32
|
readonly chunks: readonly ContentChunk[];
|
|
@@ -39,8 +44,8 @@ export declare function checkContentManifest(input: unknown, expectedHash?: stri
|
|
|
39
44
|
* hand-built manifest cannot drift from the derivation rule.
|
|
40
45
|
*/
|
|
41
46
|
export declare function manifestFromChunks(contentHash: string, chunks: readonly ContentChunk[]): Checked<ContentManifest>;
|
|
42
|
-
/** Syncthing's adaptive
|
|
43
|
-
*
|
|
47
|
+
/** Dropbox-sized cold blocks, widened by Syncthing's adaptive rule only when
|
|
48
|
+
* needed to keep a manifest below 2,000 blocks, capped at 16 MiB. */
|
|
44
49
|
export declare function contentBlockSize(totalBytes: number): number;
|
|
45
50
|
/** Split a byte count into adaptive full blocks, then the remainder. */
|
|
46
51
|
export declare function chunkSizes(totalBytes: number): number[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/contracts/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,eAAe,CAAC;AAEnE,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/contracts/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAE,KAAK,OAAO,EAAwB,MAAM,eAAe,CAAC;AAEnE;;8EAE8E;AAC9E,eAAO,MAAM,uBAAuB,4BAA4B,CAAC;AACjE,eAAO,MAAM,gBAAgB,4BAA4B,CAAC;AAC1D,MAAM,MAAM,eAAe,GAAG,OAAO,gBAAgB,GAAG,OAAO,uBAAuB,CAAC;AAEvF,eAAO,MAAM,uBAAuB,QAAkB,CAAC;AACvD,eAAO,MAAM,uBAAuB,QAAmB,CAAC;AACxD,2EAA2E;AAC3E,eAAO,MAAM,WAAW,QAA0B,CAAC;AACnD,eAAO,MAAM,kBAAkB,OAAQ,CAAC;AAIxC,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC;IACnC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAC;CAC1C;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,OAAO,EAAE,YAAY,GAAE,MAAM,GAAG,IAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAoCjH;AAED;;;;GAIG;AACH,wBAAgB,kBAAkB,CAChC,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,SAAS,YAAY,EAAE,GAC9B,OAAO,CAAC,eAAe,CAAC,CAK1B;AAED;qEACqE;AACrE,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAO3D;AAED,wEAAwE;AACxE,wBAAgB,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAQvD"}
|
|
@@ -10,8 +10,12 @@
|
|
|
10
10
|
* host effects; this file owns the shape and its laws.
|
|
11
11
|
*/
|
|
12
12
|
import { pass, fail, isRecord } from './validate.js';
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
/** Version 3 changes only the canonical writer layout: ordinary files begin
|
|
14
|
+
* at Dropbox's stable 4 MiB block size. Version 2 remains readable because
|
|
15
|
+
* immutable cloud heads created by an older writer must still materialize. */
|
|
16
|
+
export const LEGACY_CONTENT_CONTRACT = 'amalgm-entity-content@2';
|
|
17
|
+
export const CONTENT_CONTRACT = 'amalgm-entity-content@3';
|
|
18
|
+
export const MIN_CONTENT_BLOCK_BYTES = 4 * 1024 * 1024;
|
|
15
19
|
export const MAX_CONTENT_BLOCK_BYTES = 16 * 1024 * 1024;
|
|
16
20
|
/** Maximum accepted block size. Kept as the public manifest-bound name. */
|
|
17
21
|
export const CHUNK_BYTES = MAX_CONTENT_BLOCK_BYTES;
|
|
@@ -25,6 +29,7 @@ const HASH = /^[0-9a-f]{64}$/;
|
|
|
25
29
|
*/
|
|
26
30
|
export function checkContentManifest(input, expectedHash = null) {
|
|
27
31
|
if (!isRecord(input) ||
|
|
32
|
+
(input.contract !== CONTENT_CONTRACT && input.contract !== LEGACY_CONTENT_CONTRACT) ||
|
|
28
33
|
typeof input.contentHash !== 'string' ||
|
|
29
34
|
!HASH.test(input.contentHash) ||
|
|
30
35
|
(expectedHash !== null && input.contentHash !== expectedHash) ||
|
|
@@ -48,7 +53,7 @@ export function checkContentManifest(input, expectedHash = null) {
|
|
|
48
53
|
return fail('empty entity content must have no chunks');
|
|
49
54
|
}
|
|
50
55
|
return pass({
|
|
51
|
-
contract:
|
|
56
|
+
contract: input.contract,
|
|
52
57
|
contentHash: input.contentHash,
|
|
53
58
|
bytes,
|
|
54
59
|
chunks: chunks.map((chunk) => ({ sha256: chunk.sha256, bytes: chunk.bytes })),
|
|
@@ -62,8 +67,8 @@ export function checkContentManifest(input, expectedHash = null) {
|
|
|
62
67
|
export function manifestFromChunks(contentHash, chunks) {
|
|
63
68
|
return checkContentManifest({ contract: CONTENT_CONTRACT, contentHash, bytes: chunks.reduce((t, c) => t + c.bytes, 0), chunks }, contentHash);
|
|
64
69
|
}
|
|
65
|
-
/** Syncthing's adaptive
|
|
66
|
-
*
|
|
70
|
+
/** Dropbox-sized cold blocks, widened by Syncthing's adaptive rule only when
|
|
71
|
+
* needed to keep a manifest below 2,000 blocks, capped at 16 MiB. */
|
|
67
72
|
export function contentBlockSize(totalBytes) {
|
|
68
73
|
if (!Number.isSafeInteger(totalBytes) || totalBytes < 0)
|
|
69
74
|
return MIN_CONTENT_BLOCK_BYTES;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/contracts/content.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EAAgB,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEnE,MAAM,CAAC,MAAM,gBAAgB,GAAG,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"content.js","sourceRoot":"","sources":["../../src/contracts/content.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@amalgm/live",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.18",
|
|
4
4
|
"description": "Portable realtime SDK for Amalgm — wire contracts, mutation discipline, and delivery state machines behind host-injected adapters.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "UNLICENSED",
|