@voltro/plugin-storage 0.86.0 → 0.88.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/CHANGELOG.md +5484 -0
- package/README.md +27 -0
- package/THIRD-PARTY-NOTICES.md +2503 -690
- package/dist/access.js +26 -27
- package/dist/assetRef.js +1 -2
- package/dist/avatar.js +1 -2
- package/dist/byteSecurity.d.ts +3 -0
- package/dist/byteSecurity.js +6 -0
- package/dist/connection.js +98 -0
- package/dist/constraints.js +1 -2
- package/dist/custody.js +131 -0
- package/dist/derivatives.js +1 -2
- package/dist/env.js +8 -3
- package/dist/grant.js +90 -71
- package/dist/index.d.ts +453 -215
- package/dist/index.js +709 -537
- package/dist/ingest.js +7 -2
- package/dist/ingestPolicy.js +1 -1
- package/dist/metadataError.js +8 -9
- package/dist/objectAbandon.js +15 -0
- package/dist/objectLifecycle.js +135 -102
- package/dist/objectMetadata.js +253 -96
- package/dist/objectWriter.js +51 -23
- package/dist/pathDurability.js +1 -2
- package/dist/physicalReferences.js +53 -0
- package/dist/providers.js +451 -307
- package/dist/referenceCatalogue.js +1 -2
- package/dist/renditionProof.js +81 -0
- package/dist/retainedCapture.js +390 -0
- package/dist/retainedObjects.js +189 -0
- package/dist/rpc.d.ts +1 -15
- package/dist/rpc.js +1 -2
- package/dist/scanners.js +1 -2
- package/dist/server.d.ts +153 -0
- package/dist/server.js +4 -0
- package/dist/service.js +879 -546
- package/dist/sourceIdentity.js +13 -0
- package/dist/sourcePin.js +34 -0
- package/dist/storageNamespaces.js +52 -29
- package/dist/storageNumbers.js +1 -2
- package/dist/storageObjectNamespaces.js +170 -122
- package/dist/storageReferenceInstances.js +1 -2
- package/dist/storageRequest.js +9 -0
- package/dist/storageRouting.js +45 -0
- package/dist/streamBridge.js +5 -3
- package/dist/table.js +2 -2
- package/dist/transcodeVideo.js +85 -48
- package/dist/transform.js +30 -27
- package/dist/transformCache.js +1 -2
- package/dist/types.d.ts +115 -137
- package/dist/types.js +15 -16
- package/package.json +22 -11
package/dist/objectMetadata.js
CHANGED
|
@@ -1,30 +1,35 @@
|
|
|
1
|
-
import { requireStorageReferenceScope as e } from "./storageNamespaces.js";
|
|
2
|
-
import { StorageRejected as
|
|
3
|
-
import { beginStorageObjectDeleteInTransaction as
|
|
4
|
-
import { dataStoreGrantStore as
|
|
5
|
-
import {
|
|
6
|
-
import { Effect as
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
1
|
+
import { requireStorageReferenceScope as e, storageReferenceScopeFor as t } from "./storageNamespaces.js";
|
|
2
|
+
import { StorageRejected as n, storageRefAddress as r } from "./types.js";
|
|
3
|
+
import { beginStorageObjectAbandonInTransaction as i, beginStorageObjectDeleteInTransaction as a, claimStorageObjectInTransaction as o, clearStorageObjectClaimsInTransaction as s, confirmStorageObjectDeleteInTransaction as c, confirmStorageObjectInTransaction as l, hasStorageObjectClaimInTransaction as u, lookupStorageObjectOperationInTransaction as d, readStorageObjectOperationInTransaction as f, releaseStorageObjectClaimInTransaction as p, reserveStorageObjectInTransaction as m, storageObjectOperationId as h, withStorageOperationTransaction as g } from "./objectLifecycle.js";
|
|
4
|
+
import { dataStoreGrantStore as _, dataStoreRefStore as v, toRef as y } from "./service.js";
|
|
5
|
+
import { StorageAddress as b } from "@voltro/kv/storage";
|
|
6
|
+
import { Effect as x, Schema as S } from "effect";
|
|
7
|
+
import { and as C, eq as w, json as T, table as E, text as D } from "@voltro/database";
|
|
8
|
+
// src/objectMetadata.ts
|
|
9
|
+
var O = "_voltro_storage_put_intents", k = E(O, {
|
|
10
|
+
id: D().maxLength(64),
|
|
11
|
+
refId: D().maxLength(64),
|
|
12
|
+
storageInstance: D().nullable(),
|
|
13
|
+
objectNamespace: D().maxLength(64).nullable(),
|
|
14
|
+
identity: T(),
|
|
15
|
+
ref: T()
|
|
16
|
+
}).primaryKey(["id"]).unique("storagePutRef", ["refId"]).nonReactive(), A = S.Struct({
|
|
17
|
+
storageInstance: S.String,
|
|
18
|
+
objectNamespace: S.String,
|
|
19
|
+
tenantId: S.NullOr(S.String),
|
|
20
|
+
bucket: S.String,
|
|
21
|
+
operationId: S.String,
|
|
22
|
+
fingerprint: S.String,
|
|
23
|
+
checksum: S.String,
|
|
24
|
+
logicalKey: S.String,
|
|
25
|
+
retainedSource: S.optionalKey(S.Struct({
|
|
26
|
+
refId: S.String,
|
|
27
|
+
digest: S.String
|
|
28
|
+
}))
|
|
29
|
+
}), j = async (e, t, n) => {
|
|
25
30
|
let r = await e.query({
|
|
26
|
-
table:
|
|
27
|
-
predicate:
|
|
31
|
+
table: O,
|
|
32
|
+
predicate: C(w("storageInstance", n.storageInstance), w("objectNamespace", n.objectNamespace), w("refId", t)),
|
|
28
33
|
order: [],
|
|
29
34
|
take: 2,
|
|
30
35
|
skip: void 0,
|
|
@@ -32,119 +37,271 @@ var x = "_voltro_storage_put_intents", S = _(x, {
|
|
|
32
37
|
});
|
|
33
38
|
if (r.length === 0) return;
|
|
34
39
|
if (r.length !== 1) throw Error("Storage reference has ambiguous operation ownership");
|
|
35
|
-
let i = r[0], a =
|
|
40
|
+
let i = r[0], a = S.decodeUnknownSync(A)(i.identity);
|
|
36
41
|
if (a.storageInstance !== n.storageInstance || a.objectNamespace !== n.objectNamespace) throw Error("Storage put intent does not match its bound storage scope");
|
|
37
42
|
if (typeof i.ref != "object" || i.ref === null || Array.isArray(i.ref)) throw Error("Storage operation reference is unreadable");
|
|
38
|
-
let o =
|
|
43
|
+
let o = y(i.ref);
|
|
39
44
|
if (o.id !== t || o.bucket !== a.bucket || o.tenantId !== a.tenantId || o.checksum !== a.checksum || !Number.isSafeInteger(o.size) || o.size < 0 || !Number.isFinite(o.createdAt.getTime())) throw Error("Storage operation reference does not match its identity");
|
|
40
45
|
return {
|
|
41
46
|
identity: a,
|
|
42
47
|
ref: o
|
|
43
48
|
};
|
|
44
|
-
},
|
|
45
|
-
let
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
}, M = async (e, t) => {
|
|
50
|
+
let n = h(t), r = await e.query({
|
|
51
|
+
table: O,
|
|
52
|
+
predicate: w("id", n),
|
|
53
|
+
order: [],
|
|
54
|
+
take: 1,
|
|
55
|
+
skip: void 0,
|
|
56
|
+
projection: void 0
|
|
57
|
+
});
|
|
58
|
+
if (r.length === 0) return;
|
|
59
|
+
if (typeof r[0].refId != "string") throw Error("Storage operation has no reference identity");
|
|
60
|
+
let i = await j(e, r[0].refId, t);
|
|
61
|
+
if (i === void 0 || h(i.identity) !== n) throw Error("Storage operation intent does not match its requested scope");
|
|
62
|
+
let a = await f(e, i.identity);
|
|
63
|
+
if (a === void 0 || a.refId !== i.ref.id) throw Error("Storage operation intent lost its operation");
|
|
64
|
+
return {
|
|
65
|
+
...i,
|
|
66
|
+
state: a.state
|
|
67
|
+
};
|
|
68
|
+
}, N = async (e, t) => {
|
|
69
|
+
let n = await M(e, t);
|
|
70
|
+
return n === void 0 ? { state: "missing" } : g(e, n.identity, async (e) => {
|
|
71
|
+
let n = await M(e, t);
|
|
72
|
+
if (n === void 0) throw Error("Storage operation disappeared before abandonment");
|
|
73
|
+
if (n.state === "ready") return {
|
|
74
|
+
state: "ready",
|
|
75
|
+
refId: n.ref.id
|
|
76
|
+
};
|
|
77
|
+
let r = v(e, t);
|
|
78
|
+
if (n.state === "reserved" && await x.runPromise(r.getById(n.ref.id)) !== null) throw Error("An unconfirmed operation unexpectedly has a readable reference");
|
|
79
|
+
let a = await i(e, n.identity);
|
|
80
|
+
return n.state === "reserved" && await x.runPromise(r.releaseUsage(n.identity.tenantId, {
|
|
81
|
+
bytes: n.ref.size,
|
|
82
|
+
count: 1
|
|
83
|
+
})), {
|
|
84
|
+
state: "retired",
|
|
85
|
+
identity: n.identity,
|
|
86
|
+
operation: a
|
|
87
|
+
};
|
|
88
|
+
});
|
|
89
|
+
}, P = (t, r, i) => {
|
|
90
|
+
let b = Object.freeze({ ...r });
|
|
91
|
+
e(b);
|
|
92
|
+
let S = (e) => ({
|
|
48
93
|
...e,
|
|
49
|
-
...
|
|
94
|
+
...b
|
|
50
95
|
});
|
|
51
96
|
return {
|
|
52
|
-
scope:
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
97
|
+
scope: b,
|
|
98
|
+
operationStatus: (e) => t.transactional(async (t) => {
|
|
99
|
+
let n = {
|
|
100
|
+
...e,
|
|
101
|
+
...b
|
|
102
|
+
}, r = await d(t, n);
|
|
103
|
+
if (!r) return { state: "absent" };
|
|
104
|
+
let i = await j(t, r.refId, b);
|
|
105
|
+
if (!i || i.identity.bucket !== e.bucket || i.identity.tenantId !== e.tenantId || i.identity.operationId !== e.operationId || h(i.identity) !== r.id || i.ref.key !== r.key) throw Error("Storage operation lost its matching put intent");
|
|
106
|
+
let a = await f(t, i.identity);
|
|
107
|
+
if (!a || a.refId !== r.refId || a.key !== r.key) throw Error("Storage operation identity changed during observation");
|
|
108
|
+
if (a.state !== "ready") return { state: a.state };
|
|
109
|
+
let o = await x.runPromise(v(t, b).getById(a.refId));
|
|
110
|
+
if (!o || o.id !== i.ref.id || o.bucket !== e.bucket || o.tenantId !== e.tenantId || o.key !== a.key || o.checksum !== i.identity.checksum || o.size !== i.ref.size) throw Error("Ready storage operation has no matching readable reference");
|
|
111
|
+
let s = await f(t, i.identity);
|
|
112
|
+
if (!s || s.state !== "ready" || s.key !== o.key || s.refId !== o.id) throw Error("Storage operation changed during observation");
|
|
113
|
+
return {
|
|
114
|
+
state: "ready",
|
|
115
|
+
ref: o
|
|
116
|
+
};
|
|
117
|
+
}),
|
|
118
|
+
intent: (e) => j(t, e, b),
|
|
119
|
+
lookup: async (e, n) => {
|
|
120
|
+
if (typeof n != "string" || !n.trim() || n.length > 200) throw Error("Storage operation lookup requires an explicit bounded claim");
|
|
121
|
+
let r = Object.freeze({
|
|
122
|
+
...b,
|
|
123
|
+
tenantId: e.tenantId,
|
|
124
|
+
bucket: e.bucket,
|
|
125
|
+
operationId: e.operationId
|
|
126
|
+
}), i = await d(t, r);
|
|
127
|
+
if (!i) return;
|
|
128
|
+
let a = await j(t, i.refId, b);
|
|
129
|
+
if (!a || a.identity.tenantId !== r.tenantId || a.identity.bucket !== r.bucket || a.identity.operationId !== r.operationId) throw Error("Storage operation lookup has unrelated durable intent");
|
|
130
|
+
return g(t, a.identity, async (e) => {
|
|
131
|
+
let t = await f(e, a.identity);
|
|
132
|
+
if (!t) throw Error("Storage operation lookup lost its durable identity");
|
|
133
|
+
let r = await j(e, t.refId, b);
|
|
134
|
+
if (!r) throw Error("Storage operation lookup lost its put intent");
|
|
135
|
+
return {
|
|
136
|
+
state: t.state,
|
|
137
|
+
ref: r.ref,
|
|
138
|
+
held: await u(e, t.id, n)
|
|
139
|
+
};
|
|
140
|
+
});
|
|
141
|
+
},
|
|
142
|
+
operation: (e) => M(t, {
|
|
143
|
+
...e,
|
|
144
|
+
...b
|
|
145
|
+
}),
|
|
146
|
+
reserve: (e, r, a, s) => g(t, S(e), async (t) => {
|
|
147
|
+
if (await i?.(t, e, "reserve"), r.tenantId !== e.tenantId || r.bucket !== e.bucket || r.checksum !== e.checksum || !Number.isSafeInteger(r.size) || r.size < 0) throw Error("Storage put metadata does not match its identity");
|
|
148
|
+
let c = await f(t, S(e));
|
|
57
149
|
if (c) {
|
|
58
150
|
if (c.state === "deleting" || c.state === "deleted") throw Error("Storage put identity has already been deleted");
|
|
59
|
-
let e = await
|
|
151
|
+
let e = await j(t, c.refId, b);
|
|
60
152
|
if (!e) throw Error("Storage operation lost its put intent");
|
|
61
|
-
let
|
|
62
|
-
return
|
|
153
|
+
let n = c.state === "ready";
|
|
154
|
+
return n && s !== void 0 && await o(t, c.id, s), {
|
|
63
155
|
ref: e.ref,
|
|
64
|
-
ready:
|
|
65
|
-
outcome:
|
|
156
|
+
ready: n,
|
|
157
|
+
outcome: n ? "joined" : "resumed"
|
|
66
158
|
};
|
|
67
159
|
}
|
|
68
|
-
let
|
|
69
|
-
if (!(await
|
|
70
|
-
bytes:
|
|
160
|
+
let l = await m(t, S(e)), u = v(t, b);
|
|
161
|
+
if (!(await x.runPromise(u.consumeUsage(e.tenantId, {
|
|
162
|
+
bytes: r.size,
|
|
71
163
|
count: 1
|
|
72
|
-
},
|
|
164
|
+
}, a))).allowed) throw new n({
|
|
73
165
|
reason: "quota-exceeded",
|
|
74
166
|
detail: "Storage operation exceeds tenant quota"
|
|
75
167
|
});
|
|
76
|
-
let
|
|
77
|
-
...
|
|
78
|
-
id:
|
|
79
|
-
key:
|
|
168
|
+
let d = y({
|
|
169
|
+
...r,
|
|
170
|
+
id: l.refId,
|
|
171
|
+
key: l.key
|
|
80
172
|
});
|
|
81
|
-
return await
|
|
82
|
-
id:
|
|
83
|
-
refId:
|
|
84
|
-
...
|
|
85
|
-
identity:
|
|
86
|
-
ref:
|
|
173
|
+
return await t.insert(O, {
|
|
174
|
+
id: l.id,
|
|
175
|
+
refId: d.id,
|
|
176
|
+
...b,
|
|
177
|
+
identity: S(e),
|
|
178
|
+
ref: d
|
|
87
179
|
}), {
|
|
88
|
-
ref:
|
|
180
|
+
ref: d,
|
|
89
181
|
ready: !1,
|
|
90
182
|
outcome: "created"
|
|
91
183
|
};
|
|
92
184
|
}),
|
|
93
|
-
confirm: (e,
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
185
|
+
confirm: (e, n) => g(t, S(e), async (t) => {
|
|
186
|
+
await i?.(t, e, "confirm");
|
|
187
|
+
let r = await f(t, S(e));
|
|
188
|
+
if (!r) throw Error("Storage put operation is missing");
|
|
189
|
+
let a = await j(t, r.refId, b);
|
|
97
190
|
if (!a) throw Error("Storage put intent is missing");
|
|
98
|
-
if (
|
|
99
|
-
let
|
|
100
|
-
if (!
|
|
101
|
-
return
|
|
191
|
+
if (n !== void 0 && await o(t, r.id, n), r.state === "ready") {
|
|
192
|
+
let n = await x.runPromise(v(t, b).getById(r.refId));
|
|
193
|
+
if (!n || n.key !== r.key || n.checksum !== e.checksum) throw Error("Confirmed storage operation lost its reference");
|
|
194
|
+
return n;
|
|
102
195
|
}
|
|
103
|
-
return await
|
|
196
|
+
return await l(t, S(e)), await x.runPromise(v(t, b).insert(a.ref)), a.ref;
|
|
104
197
|
}),
|
|
105
|
-
beginDelete: async (e, r,
|
|
106
|
-
let o = await
|
|
198
|
+
beginDelete: async (e, r, i) => {
|
|
199
|
+
let o = await j(t, e, b);
|
|
107
200
|
if (!o) throw Error("Storage delete operation is missing");
|
|
108
201
|
if (r !== void 0 && o.identity.tenantId !== r) throw Error("Storage delete tenant mismatch");
|
|
109
|
-
return
|
|
110
|
-
let
|
|
111
|
-
if (!
|
|
112
|
-
let
|
|
113
|
-
if (!
|
|
114
|
-
let
|
|
115
|
-
if (
|
|
116
|
-
else if (
|
|
117
|
-
let
|
|
118
|
-
if (
|
|
202
|
+
return g(t, o.identity, async (t) => {
|
|
203
|
+
let r = await j(t, e, b);
|
|
204
|
+
if (!r) throw Error("Storage delete intent disappeared");
|
|
205
|
+
let o = await f(t, r.identity);
|
|
206
|
+
if (!o) throw Error("Storage delete lost its operation");
|
|
207
|
+
let c = o.state === "ready", l = o.state !== "deleting" && o.state !== "deleted";
|
|
208
|
+
if (i === void 0) l && await s(t, o.id);
|
|
209
|
+
else if (l) {
|
|
210
|
+
let a = await p(t, o.id, i);
|
|
211
|
+
if (a.others) return {
|
|
119
212
|
released: !0,
|
|
120
|
-
identity:
|
|
213
|
+
identity: r.identity
|
|
121
214
|
};
|
|
122
|
-
if (!
|
|
215
|
+
if (!a.held) throw new n({
|
|
123
216
|
reason: "claim-not-held",
|
|
124
|
-
detail: `claim '${
|
|
217
|
+
detail: `claim '${i}' is not held on storage reference '${e}'; a reference put without a claim is deleted as a whole by a delete that names none`
|
|
125
218
|
});
|
|
126
219
|
}
|
|
127
|
-
let
|
|
128
|
-
if (
|
|
129
|
-
let
|
|
130
|
-
if (await
|
|
131
|
-
await
|
|
132
|
-
bytes:
|
|
220
|
+
let u = await a(t, r.identity);
|
|
221
|
+
if (c) {
|
|
222
|
+
let n = v(t, b);
|
|
223
|
+
if (await x.runPromise(_(t, b).deleteByRef(e)), !await x.runPromise(n.delete(e))) throw Error("Storage deletion lost its confirmed reference");
|
|
224
|
+
await x.runPromise(n.releaseUsage(r.identity.tenantId, {
|
|
225
|
+
bytes: r.ref.size,
|
|
133
226
|
count: 1
|
|
134
227
|
}));
|
|
135
228
|
}
|
|
136
|
-
return
|
|
137
|
-
|
|
229
|
+
return u.deleteKey !== null && (await t.query({
|
|
230
|
+
table: "_voltro_storage_refs",
|
|
231
|
+
predicate: C(w("objectNamespace", b.objectNamespace), w("key", u.deleteKey)),
|
|
232
|
+
order: [],
|
|
233
|
+
take: 1,
|
|
234
|
+
skip: void 0,
|
|
235
|
+
projection: ["id"]
|
|
236
|
+
})).length > 0 && (await t.update("_voltro_storage_operations", u.id, { deleteKey: null }), u = {
|
|
237
|
+
...u,
|
|
138
238
|
deleteKey: null
|
|
139
239
|
}), {
|
|
140
240
|
released: !0,
|
|
141
|
-
operation:
|
|
142
|
-
identity:
|
|
241
|
+
operation: u,
|
|
242
|
+
identity: r.identity
|
|
143
243
|
};
|
|
144
244
|
});
|
|
145
245
|
},
|
|
146
|
-
confirmDelete: (e) =>
|
|
246
|
+
confirmDelete: (e) => g(t, S(e), (t) => c(t, S(e)))
|
|
247
|
+
};
|
|
248
|
+
}, F = (n, i, a) => {
|
|
249
|
+
let o = Object.freeze({ ...i });
|
|
250
|
+
if (!o.storageInstance.trim()) throw Error("Storage operation metadata requires an explicit instance");
|
|
251
|
+
"resolveNamespace" in o || e(o);
|
|
252
|
+
let s = async (e) => {
|
|
253
|
+
if (!("resolveNamespace" in o)) return o;
|
|
254
|
+
if ("refId" in e) {
|
|
255
|
+
let t = await l(e.refId);
|
|
256
|
+
if (!t) throw Error("Storage delete operation is missing");
|
|
257
|
+
return {
|
|
258
|
+
storageInstance: t.identity.storageInstance,
|
|
259
|
+
objectNamespace: t.identity.objectNamespace
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
return x.runPromise(t(o, {
|
|
263
|
+
destination: e.bucket,
|
|
264
|
+
tenantId: e.tenantId,
|
|
265
|
+
key: "_namespace"
|
|
266
|
+
}));
|
|
267
|
+
}, c = async (e) => P(n, await s(e), a), l = async (e) => {
|
|
268
|
+
if (!("resolveNamespace" in o)) return P(n, o, a).intent(e);
|
|
269
|
+
let i = await n.query({
|
|
270
|
+
table: O,
|
|
271
|
+
predicate: C(w("storageInstance", o.storageInstance), w("refId", e)),
|
|
272
|
+
order: [],
|
|
273
|
+
take: 2,
|
|
274
|
+
skip: void 0,
|
|
275
|
+
projection: void 0
|
|
276
|
+
});
|
|
277
|
+
if (i.length === 0) return;
|
|
278
|
+
if (i.length !== 1) throw Error("Storage reference has ambiguous operation ownership");
|
|
279
|
+
let s = S.decodeUnknownSync(A)(i[0].identity), c = y(i[0].ref);
|
|
280
|
+
S.decodeUnknownSync(b)(r(c));
|
|
281
|
+
let l = await x.runPromise(t(o, r(c)));
|
|
282
|
+
if (s.storageInstance !== l.storageInstance || s.objectNamespace !== l.objectNamespace) throw Error("Storage put intent belongs to a different physical object namespace");
|
|
283
|
+
return P(n, l, a).intent(e);
|
|
284
|
+
};
|
|
285
|
+
return {
|
|
286
|
+
scopeFor: s,
|
|
287
|
+
intent: l,
|
|
288
|
+
operationStatus: async (e) => {
|
|
289
|
+
let t = await s(e);
|
|
290
|
+
return {
|
|
291
|
+
observation: await P(n, t, a).operationStatus(e),
|
|
292
|
+
scope: t
|
|
293
|
+
};
|
|
294
|
+
},
|
|
295
|
+
lookup: async (e, t) => (await c(e)).lookup(e, t),
|
|
296
|
+
operation: async (e) => (await c(e)).operation(e),
|
|
297
|
+
reserve: async (e, t, n, r) => (await c(e)).reserve(e, t, n, r),
|
|
298
|
+
confirm: async (e, t) => (await c(e)).confirm(e, t),
|
|
299
|
+
beginDelete: async (e, t, r) => {
|
|
300
|
+
let i = await l(e);
|
|
301
|
+
if (!i) throw Error("Storage delete operation is missing");
|
|
302
|
+
return P(n, i.identity, a).beginDelete(e, t, r);
|
|
303
|
+
},
|
|
304
|
+
confirmDelete: async (e) => (await c(e)).confirmDelete(e)
|
|
147
305
|
};
|
|
148
|
-
};
|
|
149
|
-
|
|
150
|
-
export { T as makeStorageObjectMetadata, S as storagePutIntentsTable };
|
|
306
|
+
}, I = (e, t, n) => F(e, t, n);
|
|
307
|
+
export { N as beginStorageObjectAbandon, I as makeAdmittedStorageObjectMetadata, F as makeStorageObjectMetadata, k as storagePutIntentsTable };
|
package/dist/objectWriter.js
CHANGED
|
@@ -1,58 +1,86 @@
|
|
|
1
1
|
import { StorageError as e, StorageRejected as t } from "./types.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { Effect as a } from "effect";
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { putObjectStream as n } from "./streamBridge.js";
|
|
3
|
+
import { storageMetadataError as r, storageRejectedCause as i } from "./metadataError.js";
|
|
4
|
+
import { Effect as a, Stream as o } from "effect";
|
|
5
|
+
import { createHash as s } from "node:crypto";
|
|
6
|
+
// src/objectWriter.ts
|
|
7
|
+
var c = (c) => {
|
|
8
|
+
let l = (t) => a.gen(function* () {
|
|
9
|
+
(yield* c.provider.objectNamespace) !== (yield* a.tryPromise({
|
|
10
|
+
try: () => c.metadata.scopeFor(t),
|
|
11
|
+
catch: (e) => r(e, "metadata")
|
|
12
|
+
})).objectNamespace && (yield* a.fail(new e({
|
|
9
13
|
provider: "metadata",
|
|
10
14
|
message: "Storage metadata is bound to another physical object namespace",
|
|
11
15
|
transient: !1,
|
|
12
16
|
status: 409
|
|
13
17
|
})));
|
|
14
|
-
}),
|
|
15
|
-
try:
|
|
16
|
-
catch: (
|
|
17
|
-
let a =
|
|
18
|
+
}), u = (t, n) => a.tryPromise({
|
|
19
|
+
try: n,
|
|
20
|
+
catch: (n) => {
|
|
21
|
+
let a = i(n);
|
|
18
22
|
if (a !== void 0) return a;
|
|
19
|
-
let o = n
|
|
23
|
+
let o = r(n, "metadata"), s = new e({
|
|
20
24
|
provider: "metadata",
|
|
21
25
|
message: `Storage ${t} was not confirmed: ${o.message}; retain the operation identity for recovery`,
|
|
22
26
|
transient: o.transient,
|
|
23
27
|
...o.status === void 0 ? {} : { status: o.status }
|
|
24
28
|
});
|
|
25
29
|
return Object.defineProperty(s, "cause", {
|
|
26
|
-
value:
|
|
30
|
+
value: n,
|
|
27
31
|
configurable: !0
|
|
28
32
|
}), s;
|
|
29
33
|
}
|
|
30
34
|
});
|
|
31
35
|
return {
|
|
32
36
|
put: (e) => a.gen(function* () {
|
|
33
|
-
if (e.bytes.byteLength !== e.ref.size ||
|
|
37
|
+
if (e.bytes.byteLength !== e.ref.size || s("sha256").update(e.bytes).digest("hex") !== e.identity.checksum) return yield* a.fail(new t({
|
|
34
38
|
reason: "operation-content-mismatch",
|
|
35
39
|
detail: "Storage operation bytes do not match their reserved identity"
|
|
36
40
|
}));
|
|
37
|
-
yield*
|
|
38
|
-
let n = yield*
|
|
41
|
+
yield* l(e.identity);
|
|
42
|
+
let n = yield* u("put reservation", () => c.metadata.reserve(e.identity, e.ref, e.quota, e.claim)), r = n.outcome;
|
|
39
43
|
return n.ready ? {
|
|
40
44
|
ref: n.ref,
|
|
41
45
|
outcome: r
|
|
42
|
-
} : (yield*
|
|
46
|
+
} : (yield* c.provider.put(n.ref.key, e.bytes, {
|
|
43
47
|
contentType: n.ref.contentType,
|
|
44
48
|
public: n.ref.visibility === "public"
|
|
45
49
|
}), {
|
|
46
|
-
ref: yield*
|
|
50
|
+
ref: yield* u("put confirmation", () => c.metadata.confirm(e.identity, e.claim)),
|
|
47
51
|
outcome: r
|
|
48
52
|
});
|
|
49
53
|
}),
|
|
54
|
+
putStream: (t) => a.gen(function* () {
|
|
55
|
+
let r = yield* u("put reservation", () => c.metadata.reserve(t.identity, t.ref, t.quota, t.claim)), i = r.outcome;
|
|
56
|
+
if (r.ready) return {
|
|
57
|
+
ref: r.ref,
|
|
58
|
+
outcome: i
|
|
59
|
+
};
|
|
60
|
+
let l = () => new e({
|
|
61
|
+
provider: "integrity",
|
|
62
|
+
message: "Storage operation stream does not match its reserved checksum and size",
|
|
63
|
+
transient: !1,
|
|
64
|
+
status: 409
|
|
65
|
+
}), d = s("sha256"), f = 0, p = !1, m = t.stream.pipe(o.mapEffect((e) => a.suspend(() => {
|
|
66
|
+
if (e.byteLength > r.ref.size - f) return a.fail(l());
|
|
67
|
+
let t = Uint8Array.from(e);
|
|
68
|
+
return f += t.byteLength, d.update(t), a.succeed(t);
|
|
69
|
+
})), o.concat(o.fromEffect(a.suspend(() => f !== r.ref.size || d.digest("hex") !== t.identity.checksum ? a.fail(l()) : (p = !0, a.succeed(/* @__PURE__ */ new Uint8Array())))))), h = yield* n(c.provider, r.ref.key, m, {
|
|
70
|
+
contentType: r.ref.contentType,
|
|
71
|
+
public: r.ref.visibility === "public",
|
|
72
|
+
totalSize: r.ref.size
|
|
73
|
+
});
|
|
74
|
+
return !p || h.size !== r.ref.size ? yield* a.fail(l()) : {
|
|
75
|
+
ref: yield* u("put confirmation", () => c.metadata.confirm(t.identity, t.claim)),
|
|
76
|
+
outcome: i
|
|
77
|
+
};
|
|
78
|
+
}),
|
|
50
79
|
delete: (e, t, n) => a.gen(function* () {
|
|
51
|
-
yield*
|
|
52
|
-
let r = yield*
|
|
53
|
-
"operation" in r && (r.operation.deleteKey !== null && (yield*
|
|
80
|
+
yield* l({ refId: e });
|
|
81
|
+
let r = yield* u("delete acceptance", () => c.metadata.beginDelete(e, t, n));
|
|
82
|
+
"operation" in r && (r.operation.deleteKey !== null && (yield* c.provider.delete(r.operation.deleteKey)), yield* u("delete confirmation", () => c.metadata.confirmDelete(r.identity)));
|
|
54
83
|
})
|
|
55
84
|
};
|
|
56
85
|
};
|
|
57
|
-
|
|
58
|
-
export { o as makeStorageObjectWriter };
|
|
86
|
+
export { c as makeStorageObjectWriter };
|
package/dist/pathDurability.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { statSync as e } from "node:fs";
|
|
2
|
-
|
|
2
|
+
// src/pathDurability.ts
|
|
3
3
|
var t = (t) => {
|
|
4
4
|
try {
|
|
5
5
|
let n = e(t), r = e("/");
|
|
@@ -12,5 +12,4 @@ var t = (t) => {
|
|
|
12
12
|
dies with it — which is the exact failure it exists for. On a development machine this is normal
|
|
13
13
|
and can be ignored.`;
|
|
14
14
|
};
|
|
15
|
-
//#endregion
|
|
16
15
|
export { n as durabilityNotice, t as pathDurability };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { StorageError as e } from "@voltro/kv/storage";
|
|
2
|
+
import { Effect as t } from "effect";
|
|
3
|
+
// src/physicalReferences.ts
|
|
4
|
+
var n = (n, r, i, a) => {
|
|
5
|
+
let o = (o, s) => t.gen(function* () {
|
|
6
|
+
let c = (yield* r.listObjectReferences()).filter((e) => !s || e.visibility === "public"), l = yield* n.objectNamespace;
|
|
7
|
+
if (!s && r.hasObjectReservation !== void 0 && (yield* r.hasObjectReservation(l, o))) return !0;
|
|
8
|
+
if (c.length === 0) return !1;
|
|
9
|
+
let u, d = !1, f = !1;
|
|
10
|
+
for (let e of c) {
|
|
11
|
+
if (e.objectNamespace === l && e.key === o) return !0;
|
|
12
|
+
let t = yield* a === void 0 ? i({
|
|
13
|
+
destination: e.bucket,
|
|
14
|
+
tenantId: e.tenantId,
|
|
15
|
+
key: e.key
|
|
16
|
+
}) : a(e);
|
|
17
|
+
if (e.objectNamespace !== void 0 && (yield* t.objectNamespace) !== e.objectNamespace) {
|
|
18
|
+
f = !0;
|
|
19
|
+
continue;
|
|
20
|
+
}
|
|
21
|
+
if (n === t) {
|
|
22
|
+
if (o === e.key) return !0;
|
|
23
|
+
continue;
|
|
24
|
+
}
|
|
25
|
+
d ||= (u = n.objectLocation === void 0 ? void 0 : yield* n.objectLocation(o), !0);
|
|
26
|
+
let r = t.objectLocation === void 0 ? void 0 : yield* t.objectLocation(e.key);
|
|
27
|
+
if (u === void 0 || r === void 0) f = !0;
|
|
28
|
+
else if (u.namespace === r.namespace && u.key === r.key) return !0;
|
|
29
|
+
}
|
|
30
|
+
return f ? yield* t.fail(new e({
|
|
31
|
+
provider: "storage",
|
|
32
|
+
message: "Physical object ownership cannot be established for every storage destination",
|
|
33
|
+
transient: !1
|
|
34
|
+
})) : !1;
|
|
35
|
+
}), s = (e, n) => n === !0 ? t.succeed(!0) : o(e, !0);
|
|
36
|
+
return {
|
|
37
|
+
...n,
|
|
38
|
+
delete: (e) => o(e, !1).pipe(t.flatMap((r) => r ? n.setObjectPublic === void 0 ? t.void : o(e, !0).pipe(t.flatMap((t) => n.setObjectPublic(e, t))) : n.delete(e))),
|
|
39
|
+
...n.setObjectPublic === void 0 ? {} : {
|
|
40
|
+
setObjectPublic: (e, r) => s(e, r).pipe(t.flatMap((t) => n.setObjectPublic(e, t))),
|
|
41
|
+
put: (e, r, i) => s(e, i.public).pipe(t.flatMap((t) => n.put(e, r, {
|
|
42
|
+
...i,
|
|
43
|
+
public: t
|
|
44
|
+
}))),
|
|
45
|
+
...n.putStream === void 0 ? {} : { putStream: (e, r, i) => s(e, i.public).pipe(t.flatMap((t) => n.putStream(e, r, {
|
|
46
|
+
...i,
|
|
47
|
+
public: t
|
|
48
|
+
}))) },
|
|
49
|
+
...n.createMultipartUpload === void 0 ? {} : { createMultipartUpload: (e, r, i) => s(e, i?.public).pipe(t.flatMap((t) => n.createMultipartUpload(e, r, { public: t }))) }
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
};
|
|
53
|
+
export { n as protectStorageReferences };
|