@tinycloud/share-sdk 1.1.1-beta.0 → 1.2.0-beta.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.
@@ -0,0 +1,104 @@
1
+ declare const ARTIFACT_ROOT = "artifacts";
2
+ declare const ARTIFACT_MANIFEST_NAME = "manifest.json";
3
+ declare const ARTIFACT_MANIFEST_VERSION: 1;
4
+ /** A lost create race bumps `n`; this bounds how many times one publish retries. */
5
+ declare const ARTIFACT_MAX_PUBLISH_ATTEMPTS = 16;
6
+ type ArtifactErrorCode = "invalid-argument" | "conflict" | "storage" | "corrupt";
7
+ declare class ArtifactError extends Error {
8
+ readonly code: ArtifactErrorCode;
9
+ constructor(code: ArtifactErrorCode, message: string, options?: {
10
+ readonly cause?: unknown;
11
+ });
12
+ }
13
+ /**
14
+ * The only storage operations the layout needs. `put` with `ifNoneMatch`
15
+ * resolves `"exists"` on a 412 and `"created"` otherwise; every other failure
16
+ * throws. `list` returns full keys and follows pagination to the end.
17
+ */
18
+ interface ArtifactStore {
19
+ put(key: string, bytes: Uint8Array, options: {
20
+ readonly ifNoneMatch: "*";
21
+ readonly contentType?: string;
22
+ }): Promise<"created" | "exists">;
23
+ get(key: string): Promise<Uint8Array | undefined>;
24
+ list(prefix: string): Promise<readonly string[]>;
25
+ }
26
+ interface ArtifactManifestFile {
27
+ /** One safe path segment, relative to the version directory. */
28
+ readonly path: string;
29
+ /** SHA-256 (lowercase hex) of the bytes stored at this key. */
30
+ readonly sha256: string;
31
+ readonly bytes: number;
32
+ }
33
+ interface ArtifactManifest {
34
+ readonly v: typeof ARTIFACT_MANIFEST_VERSION;
35
+ readonly files: readonly ArtifactManifestFile[];
36
+ readonly createdAt: string;
37
+ /** The version this one follows, or `null` for the first. */
38
+ readonly parent: number | null;
39
+ readonly note?: string;
40
+ }
41
+ interface ArtifactVersionInput {
42
+ readonly artifactId: string;
43
+ readonly files: readonly {
44
+ readonly filename: string;
45
+ readonly bytes: Uint8Array;
46
+ readonly contentType?: string;
47
+ }[];
48
+ readonly note?: string;
49
+ readonly now?: () => number;
50
+ }
51
+ interface ArtifactVersionResult {
52
+ readonly artifactId: string;
53
+ readonly version: number;
54
+ readonly manifest: ArtifactManifest;
55
+ /** SHA-256 of the exact stored `manifest.json` bytes. */
56
+ readonly manifestSha256: string;
57
+ /** `false` when an existing version already held the same content (idempotent re-run). */
58
+ readonly created: boolean;
59
+ }
60
+ interface ArtifactVersionSummary {
61
+ readonly version: number;
62
+ /** `false` while `manifest.json` is missing (an interrupted or lost-race attempt) or unreadable (`corrupt`). */
63
+ readonly complete: boolean;
64
+ /** `manifest.json` exists but does not parse: the version is listed, never trusted, never reused. */
65
+ readonly corrupt?: true;
66
+ readonly manifest?: ArtifactManifest;
67
+ readonly manifestSha256?: string;
68
+ }
69
+ declare function sha256Hex(bytes: Uint8Array): string;
70
+ declare function newArtifactId(random?: (length: number) => Uint8Array): string;
71
+ declare function assertArtifactId(value: string): string;
72
+ declare function artifactVersionsPrefix(artifactId: string): string;
73
+ /** Delegation resource for one version: a prefix, NO trailing slash. */
74
+ declare function artifactVersionResource(artifactId: string, version: number): string;
75
+ declare function artifactVersionFilePath(artifactId: string, version: number, filename: string): string;
76
+ /** The artifact and version a stored KV path belongs to, if it is under a version directory. */
77
+ declare function parseArtifactVersionPath(path: string): {
78
+ readonly artifactId: string;
79
+ readonly version: number;
80
+ readonly file: string;
81
+ } | undefined;
82
+ declare function manifestBytes(manifest: ArtifactManifest): Uint8Array;
83
+ /**
84
+ * Strict manifest parser. Unknown fields, duplicate paths and malformed
85
+ * digests are refused: the bytes a viewer verifies against are exactly the
86
+ * ones this accepts.
87
+ */
88
+ declare function parseArtifactManifest(bytes: Uint8Array): ArtifactManifest;
89
+ /** Versions present under `artifacts/<aid>/versions/`, ascending, with their manifests when complete. */
90
+ declare function listArtifactVersions(store: ArtifactStore, artifactId: string): Promise<ArtifactVersionSummary[]>;
91
+ /**
92
+ * Publish `files` as the next version.
93
+ *
94
+ * - Content identical to the latest complete version: no new version, that
95
+ * one is returned (`created: false`). Safe to re-run after a crash.
96
+ * - Files are created with `If-None-Match: *`. A 412 is success only when the
97
+ * stored bytes hash to the same sha256 as ours; otherwise another publisher
98
+ * owns that `n` and the next number is tried.
99
+ * - `manifest.json` is written last. A version without one is incomplete and
100
+ * is never reused, and a manifest lists the only files it vouches for.
101
+ */
102
+ declare function publishArtifactVersion(store: ArtifactStore, input: ArtifactVersionInput): Promise<ArtifactVersionResult>;
103
+
104
+ export { ARTIFACT_MANIFEST_NAME, ARTIFACT_MANIFEST_VERSION, ARTIFACT_MAX_PUBLISH_ATTEMPTS, ARTIFACT_ROOT, ArtifactError, type ArtifactErrorCode, type ArtifactManifest, type ArtifactManifestFile, type ArtifactStore, type ArtifactVersionInput, type ArtifactVersionResult, type ArtifactVersionSummary, artifactVersionFilePath, artifactVersionResource, artifactVersionsPrefix, assertArtifactId, listArtifactVersions, manifestBytes, newArtifactId, parseArtifactManifest, parseArtifactVersionPath, publishArtifactVersion, sha256Hex };
@@ -0,0 +1,104 @@
1
+ declare const ARTIFACT_ROOT = "artifacts";
2
+ declare const ARTIFACT_MANIFEST_NAME = "manifest.json";
3
+ declare const ARTIFACT_MANIFEST_VERSION: 1;
4
+ /** A lost create race bumps `n`; this bounds how many times one publish retries. */
5
+ declare const ARTIFACT_MAX_PUBLISH_ATTEMPTS = 16;
6
+ type ArtifactErrorCode = "invalid-argument" | "conflict" | "storage" | "corrupt";
7
+ declare class ArtifactError extends Error {
8
+ readonly code: ArtifactErrorCode;
9
+ constructor(code: ArtifactErrorCode, message: string, options?: {
10
+ readonly cause?: unknown;
11
+ });
12
+ }
13
+ /**
14
+ * The only storage operations the layout needs. `put` with `ifNoneMatch`
15
+ * resolves `"exists"` on a 412 and `"created"` otherwise; every other failure
16
+ * throws. `list` returns full keys and follows pagination to the end.
17
+ */
18
+ interface ArtifactStore {
19
+ put(key: string, bytes: Uint8Array, options: {
20
+ readonly ifNoneMatch: "*";
21
+ readonly contentType?: string;
22
+ }): Promise<"created" | "exists">;
23
+ get(key: string): Promise<Uint8Array | undefined>;
24
+ list(prefix: string): Promise<readonly string[]>;
25
+ }
26
+ interface ArtifactManifestFile {
27
+ /** One safe path segment, relative to the version directory. */
28
+ readonly path: string;
29
+ /** SHA-256 (lowercase hex) of the bytes stored at this key. */
30
+ readonly sha256: string;
31
+ readonly bytes: number;
32
+ }
33
+ interface ArtifactManifest {
34
+ readonly v: typeof ARTIFACT_MANIFEST_VERSION;
35
+ readonly files: readonly ArtifactManifestFile[];
36
+ readonly createdAt: string;
37
+ /** The version this one follows, or `null` for the first. */
38
+ readonly parent: number | null;
39
+ readonly note?: string;
40
+ }
41
+ interface ArtifactVersionInput {
42
+ readonly artifactId: string;
43
+ readonly files: readonly {
44
+ readonly filename: string;
45
+ readonly bytes: Uint8Array;
46
+ readonly contentType?: string;
47
+ }[];
48
+ readonly note?: string;
49
+ readonly now?: () => number;
50
+ }
51
+ interface ArtifactVersionResult {
52
+ readonly artifactId: string;
53
+ readonly version: number;
54
+ readonly manifest: ArtifactManifest;
55
+ /** SHA-256 of the exact stored `manifest.json` bytes. */
56
+ readonly manifestSha256: string;
57
+ /** `false` when an existing version already held the same content (idempotent re-run). */
58
+ readonly created: boolean;
59
+ }
60
+ interface ArtifactVersionSummary {
61
+ readonly version: number;
62
+ /** `false` while `manifest.json` is missing (an interrupted or lost-race attempt) or unreadable (`corrupt`). */
63
+ readonly complete: boolean;
64
+ /** `manifest.json` exists but does not parse: the version is listed, never trusted, never reused. */
65
+ readonly corrupt?: true;
66
+ readonly manifest?: ArtifactManifest;
67
+ readonly manifestSha256?: string;
68
+ }
69
+ declare function sha256Hex(bytes: Uint8Array): string;
70
+ declare function newArtifactId(random?: (length: number) => Uint8Array): string;
71
+ declare function assertArtifactId(value: string): string;
72
+ declare function artifactVersionsPrefix(artifactId: string): string;
73
+ /** Delegation resource for one version: a prefix, NO trailing slash. */
74
+ declare function artifactVersionResource(artifactId: string, version: number): string;
75
+ declare function artifactVersionFilePath(artifactId: string, version: number, filename: string): string;
76
+ /** The artifact and version a stored KV path belongs to, if it is under a version directory. */
77
+ declare function parseArtifactVersionPath(path: string): {
78
+ readonly artifactId: string;
79
+ readonly version: number;
80
+ readonly file: string;
81
+ } | undefined;
82
+ declare function manifestBytes(manifest: ArtifactManifest): Uint8Array;
83
+ /**
84
+ * Strict manifest parser. Unknown fields, duplicate paths and malformed
85
+ * digests are refused: the bytes a viewer verifies against are exactly the
86
+ * ones this accepts.
87
+ */
88
+ declare function parseArtifactManifest(bytes: Uint8Array): ArtifactManifest;
89
+ /** Versions present under `artifacts/<aid>/versions/`, ascending, with their manifests when complete. */
90
+ declare function listArtifactVersions(store: ArtifactStore, artifactId: string): Promise<ArtifactVersionSummary[]>;
91
+ /**
92
+ * Publish `files` as the next version.
93
+ *
94
+ * - Content identical to the latest complete version: no new version, that
95
+ * one is returned (`created: false`). Safe to re-run after a crash.
96
+ * - Files are created with `If-None-Match: *`. A 412 is success only when the
97
+ * stored bytes hash to the same sha256 as ours; otherwise another publisher
98
+ * owns that `n` and the next number is tried.
99
+ * - `manifest.json` is written last. A version without one is incomplete and
100
+ * is never reused, and a manifest lists the only files it vouches for.
101
+ */
102
+ declare function publishArtifactVersion(store: ArtifactStore, input: ArtifactVersionInput): Promise<ArtifactVersionResult>;
103
+
104
+ export { ARTIFACT_MANIFEST_NAME, ARTIFACT_MANIFEST_VERSION, ARTIFACT_MAX_PUBLISH_ATTEMPTS, ARTIFACT_ROOT, ArtifactError, type ArtifactErrorCode, type ArtifactManifest, type ArtifactManifestFile, type ArtifactStore, type ArtifactVersionInput, type ArtifactVersionResult, type ArtifactVersionSummary, artifactVersionFilePath, artifactVersionResource, artifactVersionsPrefix, assertArtifactId, listArtifactVersions, manifestBytes, newArtifactId, parseArtifactManifest, parseArtifactVersionPath, publishArtifactVersion, sha256Hex };