@burdenoff/fe-libs 2026.1028.9 → 2026.1028.11

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.
@@ -1,7 +1,8 @@
1
- import { classifyFilesError as e, extractErrorMessage as t, isDefinitiveFilesRefusal as n } from "../../storage/retryPolicy.js";
2
- import { FilesPortAbortError as r, FilesPortError as i } from "../../storage/filesPort.js";
1
+ import { ATTACHMENT_EDITOR_ACCESS_COPY as e } from "./attachmentAccessCopy.js";
2
+ import { classifyFilesError as t, extractErrorMessage as n, isDefinitiveFilesRefusal as r } from "../../storage/retryPolicy.js";
3
+ import { FilesPortAbortError as i, FilesPortError as a } from "../../storage/filesPort.js";
3
4
  //#region src/shared/assistant/attachmentCommit.ts
4
- var a = 5 * 1024 * 1024, o = {
5
+ var o = 5 * 1024 * 1024, s = {
5
6
  concurrency: 2,
6
7
  gatewayAttempts: 2,
7
8
  gatewayRetryDelayMs: 1500,
@@ -14,7 +15,8 @@ var a = 5 * 1024 * 1024, o = {
14
15
  discardAttempts: 2,
15
16
  finalDrainRounds: 3,
16
17
  finalDrainDelayMs: 5e3
17
- }, s = {
18
+ }, c = {
19
+ editorAccessRequired: "ATTACHMENT_EDITOR_ACCESS_REQUIRED",
18
20
  quotaNotProvisioned: "QUOTA_NOT_PROVISIONED",
19
21
  quotaExceeded: "QUOTA_EXCEEDED",
20
22
  tooLarge: "ATTACHMENT_TOO_LARGE_FOR_DIRECT_UPLOAD",
@@ -22,16 +24,19 @@ var a = 5 * 1024 * 1024, o = {
22
24
  noDownloadUrl: "ATTACHMENT_NO_DOWNLOAD_URL",
23
25
  timeout: "ATTACHMENT_SAVE_TIMEOUT",
24
26
  uploadFailed: "ATTACHMENT_UPLOAD_FAILED",
25
- folderFailed: "ATTACHMENT_FOLDER_FAILED"
26
- }, c = {
27
- [s.quotaNotProvisioned]: "This workspace has no file storage, so the attachment could not be saved.",
28
- [s.quotaExceeded]: "There is not enough file storage left for these attachments.",
29
- [s.tooLarge]: "This file is over 5 MB and cannot be saved to Files.",
30
- [s.noBytes]: "The file is empty or no longer available.",
31
- [s.noDownloadUrl]: "The file was saved but could not be linked.",
32
- [s.timeout]: "Saving took too long."
33
- }, l = () => {};
34
- function u(e, t) {
27
+ folderFailed: "ATTACHMENT_FOLDER_FAILED",
28
+ pendingUpload: "ATTACHMENT_UPLOAD_UNRESOLVED"
29
+ }, l = {
30
+ [c.editorAccessRequired]: e.fallback,
31
+ [c.quotaNotProvisioned]: "This workspace has no file storage, so the attachment could not be saved.",
32
+ [c.quotaExceeded]: "There is not enough file storage left for these attachments.",
33
+ [c.tooLarge]: "This file is over 5 MB and cannot be saved to Files.",
34
+ [c.noBytes]: "The file is empty or no longer available.",
35
+ [c.noDownloadUrl]: "The file was saved but could not be linked.",
36
+ [c.timeout]: "Saving took too long.",
37
+ [c.pendingUpload]: "The previous upload is still being checked. Try Send again shortly."
38
+ }, u = () => {};
39
+ function d(e, t) {
35
40
  return new Promise((n) => {
36
41
  if (t?.aborted) {
37
42
  n();
@@ -45,86 +50,86 @@ function u(e, t) {
45
50
  t?.addEventListener("abort", r, { once: !0 });
46
51
  });
47
52
  }
48
- function d(e) {
49
- return e instanceof r || e instanceof Error && e.name === "AbortError";
50
- }
51
53
  function f(e) {
52
- return e instanceof i ? e.source : e;
54
+ return e instanceof i || e instanceof Error && e.name === "AbortError";
53
55
  }
54
- function p(t) {
55
- return e(f(t));
56
+ function p(e) {
57
+ return e instanceof a ? e.source : e;
56
58
  }
57
59
  function m(e) {
58
- let t = f(e);
60
+ return t(p(e));
61
+ }
62
+ function h(e) {
63
+ let t = p(e);
59
64
  if (!t || typeof t != "object") return [];
60
65
  let n = t;
61
66
  return (n.errors ?? n.graphQLErrors ?? []).map((e) => e.extensions?.code).filter((e) => typeof e == "string");
62
67
  }
63
- function h(e) {
64
- return m(e)[0];
65
- }
66
68
  function g(e) {
67
- return n(f(e));
69
+ return h(e)[0];
68
70
  }
69
71
  function _(e) {
70
- return d(e) || p(e) !== null ? !0 : !g(e);
72
+ return r(p(e));
71
73
  }
72
- function v(e, n) {
73
- return e instanceof i && e.message ? e.message : t(e) ?? n;
74
+ function v(e) {
75
+ return f(e) || m(e) !== null ? !0 : !_(e);
74
76
  }
75
- function y(e, t, n) {
76
- return t.aborted ? (e.then((e) => n?.(e), l), Promise.reject(new r())) : new Promise((i, a) => {
77
+ function y(e, t) {
78
+ return e instanceof a && e.message ? e.message : n(e) ?? t;
79
+ }
80
+ function b(e, t, n) {
81
+ return t.aborted ? (e.then((e) => n?.(e), u), Promise.reject(new i())) : new Promise((r, a) => {
77
82
  let o = !1, s = () => {
78
- o || (o = !0, a(new r()));
83
+ o || (o = !0, a(new i()));
79
84
  };
80
85
  t.addEventListener("abort", s, { once: !0 }), e.then((e) => {
81
86
  if (t.removeEventListener("abort", s), o) {
82
87
  n?.(e);
83
88
  return;
84
89
  }
85
- o = !0, i(e);
90
+ o = !0, r(e);
86
91
  }, (e) => {
87
92
  t.removeEventListener("abort", s), !o && (o = !0, a(e));
88
93
  });
89
94
  });
90
95
  }
91
- function b(e) {
96
+ function x(e) {
92
97
  return e.includes(".") ? e.substring(e.lastIndexOf(".") + 1) : "";
93
98
  }
94
- function x(e, t) {
99
+ function S(e, t) {
95
100
  e.reason === "none" && (e.reason = t), e.abort();
96
101
  }
97
- function S(e) {
98
- if (e.signal.aborted) throw new r();
102
+ function C(e) {
103
+ if (e.signal.aborted) throw new i();
99
104
  }
100
- async function C(e, t, n) {
105
+ async function w(e, t, n) {
101
106
  for (let r = 1;; r += 1) {
102
- S(e);
107
+ C(e);
103
108
  try {
104
- return await y(t(), e.signal, n);
109
+ return await b(t(), e.signal, n);
105
110
  } catch (t) {
106
- if (d(t) || e.signal.aborted || r >= e.policy.gatewayAttempts || p(t) === null) throw t;
111
+ if (f(t) || e.signal.aborted || r >= e.policy.gatewayAttempts || m(t) === null) throw t;
107
112
  await e.sleep(e.policy.gatewayRetryDelayMs, e.signal);
108
113
  }
109
114
  }
110
115
  }
111
- function w(e, t) {
112
- return new Promise((n, i) => {
116
+ function T(e, t) {
117
+ return new Promise((n, r) => {
113
118
  let a = !1, o = new AbortController();
114
119
  t.then((e) => {
115
120
  a = !0, o.abort(), n(e);
116
121
  }, (e) => {
117
- a = !0, o.abort(), i(e);
122
+ a = !0, o.abort(), r(e);
118
123
  });
119
124
  let s = () => {
120
125
  e.sleep(e.policy.settleGraceMs, o.signal).then(() => {
121
- a || o.signal.aborted || (a = !0, i(new r()));
126
+ a || o.signal.aborted || (a = !0, r(new i()));
122
127
  });
123
128
  };
124
129
  e.signal.aborted ? s() : e.signal.addEventListener("abort", s, { once: !0 });
125
130
  });
126
131
  }
127
- function T(e) {
132
+ function E(e) {
128
133
  if (!e) return {
129
134
  state: "other",
130
135
  status: "MISSING"
@@ -138,61 +143,61 @@ function T(e) {
138
143
  status: t
139
144
  };
140
145
  }
141
- async function E(e, t) {
146
+ async function D(e, t) {
142
147
  for (let n = 1; n <= e.policy.lookupAttempts; n += 1) try {
143
- return T(await e.port.getSession(t));
148
+ return E(await e.port.getSession(t));
144
149
  } catch (t) {
145
- if (p(t) === null) break;
150
+ if (m(t) === null) break;
146
151
  n < e.policy.lookupAttempts && await e.sleep(e.policy.lookupRetryDelayMs);
147
152
  }
148
153
  try {
149
154
  let n = (await e.port.listSessions()).find((e) => e.id === t);
150
- return n ? T(n) : { state: "unknown" };
155
+ return n ? E(n) : { state: "unknown" };
151
156
  } catch {
152
157
  return { state: "unknown" };
153
158
  }
154
159
  }
155
- function D(e, t, n) {
160
+ function O(e, t, n) {
156
161
  let r = Math.max(0, Math.min(100, Math.round(n)));
157
162
  r !== t.lastProgress && (t.lastProgress = r, e.patch(t, { progress: r }));
158
163
  }
159
- async function O(e, t) {
164
+ async function k(e, t) {
160
165
  let { attachment: n, blob: r } = t.draft;
161
166
  if (!r) throw Error("no bytes");
162
- let a = await C(e, () => e.port.initiate({
167
+ let i = await w(e, () => e.port.initiate({
163
168
  fileName: n.filename,
164
169
  fileSize: r.size,
165
170
  mimeType: n.mimeType,
166
- extension: b(n.filename)
171
+ extension: x(n.filename)
167
172
  }), (t) => {
168
- e.port.abort(t.sessionId).catch(l);
173
+ e.port.abort(t.sessionId).catch(u);
169
174
  });
170
- if (t.sessionId = a.sessionId, !a.uploadUrl) throw new k(s.tooLarge);
171
- D(e, t, 5);
175
+ if (t.sessionId = i.sessionId, !i.uploadUrl) throw new A(c.tooLarge);
176
+ O(e, t, 5);
172
177
  for (let o = 0;; o += 1) {
173
- S(e);
178
+ C(e);
174
179
  try {
175
180
  await e.port.put({
176
- url: a.uploadUrl,
181
+ url: i.uploadUrl,
177
182
  blob: r,
178
183
  mimeType: n.mimeType,
179
184
  signal: e.signal,
180
- onProgress: (n) => D(e, t, 5 + n * 85)
185
+ onProgress: (n) => O(e, t, 5 + n * 85)
181
186
  });
182
187
  return;
183
188
  } catch (t) {
184
- if (d(t) || e.signal.aborted || !(t instanceof i && (t.httpStatus === void 0 || t.httpStatus >= 500)) || o >= e.policy.putRetries) throw t;
189
+ if (f(t) || e.signal.aborted || !(t instanceof a && (t.httpStatus === void 0 || t.httpStatus >= 500)) || o >= e.policy.putRetries) throw t;
185
190
  await e.sleep(e.policy.putRetryDelayMs, e.signal);
186
191
  }
187
192
  }
188
193
  }
189
- var k = class extends Error {
194
+ var A = class extends Error {
190
195
  code;
191
196
  constructor(e, t) {
192
- super(t ?? c[e] ?? e), this.code = e, this.name = "AttachmentCommitError";
197
+ super(t ?? l[e] ?? e), this.code = e, this.name = "AttachmentCommitError";
193
198
  }
194
199
  };
195
- async function A(e, t, n) {
200
+ async function j(e, t, n) {
196
201
  let r = t.draft.blob, i = t.sessionId;
197
202
  if (!r || !i) throw Error("not staged");
198
203
  let a = {
@@ -201,17 +206,17 @@ async function A(e, t, n) {
201
206
  folderId: n
202
207
  };
203
208
  t.completeIssued = !0;
204
- let o, c;
209
+ let o, s;
205
210
  try {
206
- o = await w(e, e.port.complete(a));
211
+ o = await T(e, e.port.complete(a));
207
212
  } catch (e) {
208
- c = e;
213
+ s = e;
209
214
  }
210
215
  let l = 0;
211
216
  for (; !o;) {
212
- if (!_(c)) throw t.completeRefused = l === 0, l > 0 && (t.unresolved = !0), c;
213
- if (e.signal.aborted) throw t.unresolved = !0, c;
214
- let r = await E(e, i);
217
+ if (!v(s)) throw t.completeRefused = l === 0, l > 0 && (t.unresolved = !0), s;
218
+ if (e.signal.aborted) throw t.unresolved = !0, s;
219
+ let r = await D(e, i);
215
220
  if (r.state === "finalized") {
216
221
  t.fileId = r.fileId, o = {
217
222
  fileId: r.fileId,
@@ -221,51 +226,44 @@ async function A(e, t, n) {
221
226
  };
222
227
  break;
223
228
  }
224
- if (r.state === "in-progress" && !e.signal.aborted && p(c) !== null && l < e.policy.completeReissues) {
229
+ if (r.state === "in-progress" && !e.signal.aborted && m(s) !== null && l < e.policy.completeReissues) {
225
230
  l += 1;
226
231
  try {
227
- o = await w(e, e.port.complete(a));
232
+ o = await T(e, e.port.complete(a));
228
233
  } catch (e) {
229
- c = e;
234
+ s = e;
230
235
  }
231
236
  continue;
232
237
  }
233
- throw (r.state === "unknown" || r.state === "in-progress" || d(c)) && (t.unresolved = !0), c;
238
+ throw (r.state === "unknown" || r.state === "in-progress" || f(s)) && (t.unresolved = !0), s;
234
239
  }
235
- t.fileId = o.fileId;
236
- let u = o.downloadUrl ?? await C(e, () => e.port.getDownloadUrl(o.fileId)).catch((e) => {
237
- if (d(e)) throw e;
240
+ t.fileId = o.fileId, M(e, t.draft.attachment.id, { fileId: t.fileId });
241
+ let u = o.downloadUrl ?? await w(e, () => e.port.getDownloadUrl(o.fileId)).catch((e) => {
242
+ if (f(e)) throw e;
238
243
  return null;
239
244
  });
240
- if (!u) throw new k(s.noDownloadUrl);
241
- t.downloadUrl = u, t.urlResolvedAt = e.now(), t.done = !0;
242
- }
243
- async function j(e, t) {
244
- for (let n = 1;; n += 1) try {
245
- return await t();
246
- } catch (t) {
247
- if (n >= e.policy.discardAttempts || p(t) === null) throw t;
248
- await e.sleep(e.policy.gatewayRetryDelayMs);
249
- }
245
+ if (!u) throw new A(c.noDownloadUrl);
246
+ t.downloadUrl = u, t.urlResolvedAt = e.now(), t.done = !0, M(e, t.draft.attachment.id, {
247
+ fileId: t.fileId,
248
+ downloadUrl: t.downloadUrl,
249
+ urlResolvedAt: t.urlResolvedAt
250
+ });
250
251
  }
251
- async function M(e, t) {
252
- try {
253
- await j(e, () => e.port.deleteFile(t)) || e.store.entries.push({
254
- kind: "file",
255
- fileId: t
256
- });
257
- } catch {
258
- e.store.entries.push({
259
- kind: "file",
260
- fileId: t
261
- });
262
- }
252
+ function M(e, t, n) {
253
+ let r = e.store.retained ??= /* @__PURE__ */ new Map(), i = {
254
+ ...r.get(t),
255
+ ...n
256
+ };
257
+ r.set(t, i);
263
258
  }
264
259
  async function N(e, t) {
265
260
  if (!t.handedOver) {
266
261
  if (t.fileId) {
267
- let n = t.fileId;
268
- t.fileId = void 0, t.done = !1, await M(e, n);
262
+ M(e, t.draft.attachment.id, {
263
+ fileId: t.fileId,
264
+ downloadUrl: t.downloadUrl,
265
+ urlResolvedAt: t.urlResolvedAt
266
+ });
269
267
  return;
270
268
  }
271
269
  if (t.sessionId) {
@@ -277,7 +275,8 @@ async function N(e, t) {
277
275
  }
278
276
  t.unresolved && (t.unresolved = !1, e.store.entries.push({
279
277
  kind: "session",
280
- sessionId: t.sessionId
278
+ sessionId: t.sessionId,
279
+ attachmentId: t.draft.attachment.id
281
280
  }));
282
281
  }
283
282
  }
@@ -298,35 +297,32 @@ async function F(e, t, n) {
298
297
  let i = {
299
298
  port: e,
300
299
  policy: {
301
- ...o,
300
+ ...s,
302
301
  ...n.policy
303
302
  },
304
- sleep: n.sleep ?? u,
303
+ sleep: n.sleep ?? d,
305
304
  store: t
306
305
  };
307
306
  for (let e of r) {
308
- if (e.kind === "file") {
309
- await M(i, e.fileId);
310
- continue;
311
- }
312
- let n = await E(i, e.sessionId);
313
- n.state === "finalized" ? await M(i, n.fileId) : (n.state === "unknown" || n.state === "in-progress") && t.entries.push(e);
307
+ if (e.kind === "file") continue;
308
+ let n = await D(i, e.sessionId);
309
+ n.state === "finalized" ? e.attachmentId && M(i, e.attachmentId, { fileId: n.fileId }) : (n.state === "unknown" || n.state === "in-progress") && t.entries.push(e);
314
310
  }
315
311
  }
316
312
  function I(e, t) {
317
- let n = t instanceof k ? t : null;
313
+ let n = t instanceof A ? t : null;
318
314
  return {
319
315
  id: e.draft.attachment.id,
320
- message: n ? n.message : v(t, "The attachment could not be saved."),
321
- code: n ? n.code : h(t) ?? s.uploadFailed
316
+ message: n ? n.message : y(t, "The attachment could not be saved."),
317
+ code: n ? n.code : g(t) ?? c.uploadFailed
322
318
  };
323
319
  }
324
320
  function L(e) {
325
- return !e.attachment.fileId && !e.attachment.inlineOnly;
321
+ return !(e.attachment.fileId && e.attachment.downloadUrl) && !e.attachment.inlineOnly;
326
322
  }
327
323
  async function R(e) {
328
324
  let t = e.mode ?? "all-or-nothing", n = {
329
- ...o,
325
+ ...s,
330
326
  ...e.policy
331
327
  }, r = e.pendingDiscard ?? { entries: [] }, i = new AbortController(), a = {
332
328
  port: e.port,
@@ -335,13 +331,19 @@ async function R(e) {
335
331
  reason: "none",
336
332
  policy: n,
337
333
  now: e.now ?? (() => Date.now()),
338
- sleep: e.sleep ?? u,
334
+ sleep: e.sleep ?? d,
339
335
  patch: (t, n) => e.onChange?.(t.draft.attachment.id, n),
340
336
  store: r
341
- }, s = [];
342
- for (let t of e.drafts) L(t) && s.push({
343
- index: s.length,
337
+ }, o = [];
338
+ for (let t of e.drafts) L(t) && o.push({
339
+ index: o.length,
344
340
  draft: t,
341
+ ...r.retained?.get(t.attachment.id),
342
+ ...t.attachment.fileId ? {
343
+ fileId: t.attachment.fileId,
344
+ downloadUrl: t.attachment.downloadUrl,
345
+ urlResolvedAt: t.attachment.urlResolvedAt
346
+ } : {},
345
347
  completeIssued: !1,
346
348
  completeRefused: !1,
347
349
  unresolved: !1,
@@ -351,84 +353,115 @@ async function R(e) {
351
353
  stopped: !1,
352
354
  lastProgress: -1
353
355
  });
354
- let c = new AbortController(), l = () => x(a, "cancelled");
356
+ let c = new AbortController(), l = () => S(a, "cancelled");
355
357
  e.signal?.aborted ? l() : e.signal?.addEventListener("abort", l, { once: !0 });
356
358
  try {
357
- s.length > 0 && await z(a, s, e, t, c);
359
+ o.length > 0 && await z(a, o, e, t, c);
358
360
  } catch (e) {
359
- for (let t of s) t.failure ??= I(t, e);
360
- x(a, "failed");
361
+ for (let t of o) t.failure ??= I(t, e);
362
+ S(a, "failed");
361
363
  } finally {
362
364
  c.abort(), e.signal?.removeEventListener("abort", l);
363
365
  }
364
- return H(a, s, e, t);
366
+ return H(a, o, e, t);
365
367
  }
366
- async function z(e, t, n, r, a) {
368
+ async function z(e, t, n, r, i) {
367
369
  let o = r === "all-or-nothing";
368
370
  for (let e of t) {
371
+ if (e.fileId) continue;
369
372
  let t = e.draft.blob;
370
- !t || t.size === 0 ? e.failure = I(e, new k(s.noBytes)) : t.size > 5242880 && (e.failure = I(e, new k(s.tooLarge)));
373
+ !t || t.size === 0 ? e.failure = I(e, new A(c.noBytes)) : t.size > 5242880 && (e.failure = I(e, new A(c.tooLarge)));
371
374
  }
372
375
  if (o && t.some((e) => e.failure)) {
373
- x(e, "failed");
376
+ S(e, "failed");
374
377
  return;
375
378
  }
376
- let c = t.filter((e) => !e.failure);
377
- if (c.length === 0) return;
378
- for (let t of c) e.patch(t, {
379
+ let s = t.filter((e) => !e.failure);
380
+ if (s.length === 0) return;
381
+ for (let t of s) e.patch(t, {
379
382
  status: "uploading",
380
383
  progress: 0,
381
384
  saveError: void 0,
385
+ saveErrorCode: void 0,
382
386
  progressNote: void 0
383
387
  }), t.lastProgress = 0;
384
- n.budgetMs !== void 0 && e.sleep(n.budgetMs, a.signal).then(() => {
385
- a.signal.aborted || x(e, "budget");
388
+ n.budgetMs !== void 0 && e.sleep(n.budgetMs, i.signal).then(() => {
389
+ i.signal.aborted || S(e, "budget");
386
390
  });
387
391
  try {
388
- await y(P(e.port, e.store, {
392
+ await b(P(e.port, e.store, {
389
393
  sleep: e.sleep,
390
394
  policy: e.policy
391
395
  }), e.signal);
392
- let t = await V(e, c, o);
393
- if (t) {
394
- for (let e of c) e.failure = I(e, t);
395
- x(e, "failed");
396
+ let t = "unknown";
397
+ try {
398
+ n.preflightAccess && (t = await b(n.preflightAccess(), e.signal));
399
+ } catch (e) {
400
+ if (f(e)) throw e;
401
+ }
402
+ if (t === "denied") {
403
+ let t = new A(c.editorAccessRequired);
404
+ for (let e of s) e.failure = I(e, t);
405
+ S(e, "failed");
406
+ return;
407
+ }
408
+ for (let t of s) if (Object.assign(t, e.store.retained?.get(t.draft.attachment.id)), t.fileId) try {
409
+ if (t.downloadUrl ??= await w(e, () => e.port.getDownloadUrl(t.fileId)) ?? void 0, !t.downloadUrl) throw new A(c.noDownloadUrl);
410
+ t.urlResolvedAt ??= e.now(), t.done = !0, M(e, t.draft.attachment.id, {
411
+ fileId: t.fileId,
412
+ downloadUrl: t.downloadUrl,
413
+ urlResolvedAt: t.urlResolvedAt
414
+ });
415
+ } catch (e) {
416
+ if (f(e)) throw e;
417
+ t.failure = I(t, e);
418
+ }
419
+ else e.store.entries.some((e) => e.kind === "session" && e.attachmentId === t.draft.attachment.id) && (t.failure = I(t, new A(c.pendingUpload)));
420
+ if (o && s.some((e) => e.failure)) {
421
+ S(e, "failed");
422
+ return;
423
+ }
424
+ if (s = s.filter((e) => !e.done && !e.failure), s.length === 0) return;
425
+ let r = await V(e, s, o);
426
+ if (r) {
427
+ for (let e of s) e.failure = I(e, r);
428
+ S(e, "failed");
396
429
  return;
397
430
  }
398
- if (c = c.filter((e) => !e.failure), c.length === 0) {
399
- x(e, "failed");
431
+ if (s = s.filter((e) => !e.failure), s.length === 0) {
432
+ S(e, "failed");
400
433
  return;
401
434
  }
402
435
  } catch (e) {
403
- if (!d(e)) throw e;
436
+ if (!f(e)) throw e;
404
437
  return;
405
438
  }
406
439
  let l = 0;
407
- if (await Promise.all(Array.from({ length: Math.min(B(e), c.length) }, async () => {
440
+ if (await Promise.all(Array.from({ length: Math.min(B(e), s.length) }, async () => {
408
441
  for (;;) {
409
442
  if (e.signal.aborted) return;
410
- let t = c[l];
443
+ let t = s[l];
411
444
  if (l += 1, !t) return;
412
445
  try {
413
- await O(e, t), t.staged = !0;
446
+ await k(e, t), t.staged = !0;
414
447
  } catch (n) {
415
- d(n) ? t.stopped = !0 : (t.failure = I(t, n), o && x(e, "failed"));
448
+ f(n) ? t.stopped = !0 : (t.failure = I(t, n), o && S(e, "failed"));
416
449
  }
417
450
  }
418
451
  })), e.signal.aborted) return;
419
- let u = c.filter((e) => e.staged && !e.failure);
452
+ let u = s.filter((e) => e.staged && !e.failure);
420
453
  if (u.length === 0) {
421
- x(e, "failed");
454
+ S(e, "failed");
422
455
  return;
423
456
  }
424
- let f;
457
+ let d;
425
458
  try {
426
- f = (await C(e, () => e.port.ensureFolder(n.folderPath))).id;
459
+ d = (await w(e, () => e.port.ensureFolder(n.folderPath))).id;
427
460
  } catch (t) {
428
- if (!d(t)) {
429
- let n = t instanceof i ? t : new k(s.folderFailed);
461
+ if (!f(t)) {
462
+ let n = t instanceof a ? t : new A(c.folderFailed);
430
463
  for (let e of u) e.failure = I(e, n);
431
- x(e, "failed");
464
+ S(e, "failed");
432
465
  }
433
466
  return;
434
467
  }
@@ -438,9 +471,9 @@ async function z(e, t, n, r, a) {
438
471
  break;
439
472
  }
440
473
  try {
441
- await A(e, t, f), D(e, t, 100);
474
+ await j(e, t, d), O(e, t, 100);
442
475
  } catch (n) {
443
- if (d(n) ? t.stopped = !0 : (t.failure = I(t, n), o && x(e, "failed")), o) break;
476
+ if (f(n) ? t.stopped = !0 : (t.failure = I(t, n), o && S(e, "failed")), o) break;
444
477
  }
445
478
  }
446
479
  }
@@ -451,16 +484,16 @@ async function V(e, t, n) {
451
484
  if (!e.port.getStorageQuota) return null;
452
485
  let r;
453
486
  try {
454
- r = await y(e.port.getStorageQuota(), e.signal);
487
+ r = await b(e.port.getStorageQuota(), e.signal);
455
488
  } catch (e) {
456
- if (d(e)) throw e;
489
+ if (f(e)) throw e;
457
490
  return null;
458
491
  }
459
- if (r.state === "not-provisioned") return new k(s.quotaNotProvisioned);
492
+ if (r.state === "not-provisioned") return new A(c.quotaNotProvisioned);
460
493
  if (r.state === "ok" && r.remainingBytes !== null) {
461
494
  let e = (e) => e.draft.blob?.size ?? 0;
462
495
  if (t.reduce((t, n) => t + e(n), 0) > r.remainingBytes) {
463
- let i = new k(s.quotaExceeded);
496
+ let i = new A(c.quotaExceeded);
464
497
  if (n) return i;
465
498
  let a = r.remainingBytes;
466
499
  for (let n of t) e(n) <= a ? a -= e(n) : n.failure = I(n, i);
@@ -470,22 +503,27 @@ async function V(e, t, n) {
470
503
  }
471
504
  async function H(e, t, n, r) {
472
505
  let i = r === "all-or-nothing";
473
- if (e.reason === "budget") for (let e of t) !e.done && !e.failure && (e.failure = I(e, new k(s.timeout)));
474
- let a = e.reason === "cancelled", o = t.some((e) => e.failure), c = t.every((e) => e.done), l = !a && (i ? c && !o : !0), u = l ? t.filter((e) => !e.done) : t;
506
+ if (e.reason === "budget") for (let e of t) !e.done && !e.failure && (e.failure = I(e, new A(c.timeout)));
507
+ let a = e.reason === "cancelled", o = t.some((e) => e.failure), s = t.every((e) => e.done), l = !a && (i ? s && !o : !0), u = l ? t.filter((e) => !e.done) : t;
475
508
  for (let t of u) await N(e, t);
476
- for (let n of t) l && n.done ? e.patch(n, {
509
+ for (let n of t) n.done && l ? e.patch(n, {
477
510
  status: "ready",
478
511
  fileId: n.fileId,
479
512
  downloadUrl: n.downloadUrl,
480
513
  urlResolvedAt: n.urlResolvedAt,
481
514
  progress: void 0,
482
515
  saveError: void 0,
516
+ saveErrorCode: void 0,
483
517
  progressNote: void 0
484
518
  }) : e.patch(n, {
485
519
  status: "ready",
520
+ fileId: void 0,
521
+ downloadUrl: void 0,
522
+ urlResolvedAt: void 0,
486
523
  progress: void 0,
487
524
  progressNote: void 0,
488
- saveError: a ? void 0 : n.failure?.message
525
+ saveError: a ? void 0 : n.failure?.message,
526
+ saveErrorCode: a ? void 0 : n.failure?.code
489
527
  });
490
528
  let d = t.flatMap((e) => e.failure ? [e.failure] : []);
491
529
  if (!l) return {
@@ -505,6 +543,7 @@ async function H(e, t, n, r) {
505
543
  urlResolvedAt: t.urlResolvedAt,
506
544
  progress: void 0,
507
545
  saveError: void 0,
546
+ saveErrorCode: void 0,
508
547
  progressNote: void 0
509
548
  }) : p.push(e.attachment);
510
549
  }
@@ -514,7 +553,7 @@ async function H(e, t, n, r) {
514
553
  attachments: p,
515
554
  dropped: d,
516
555
  handedOver: () => {
517
- for (let e of m) e.handedOver = !0;
556
+ for (let t of m) t.handedOver = !0, e.store.retained?.delete(t.draft.attachment.id);
518
557
  },
519
558
  rollback: async () => {
520
559
  for (let t of m) t.handedOver || (await N(e, t), e.patch(t, {
@@ -526,56 +565,73 @@ async function H(e, t, n, r) {
526
565
  };
527
566
  }
528
567
  function U(e) {
529
- let t = { entries: [] }, n = null, r = null, i = /* @__PURE__ */ new Set(), a = (e) => {
568
+ let t = { entries: [] }, n = e.getScopeKey?.(), r = () => {
569
+ let r = e.getScopeKey?.();
570
+ return r !== n && (n = r, t = { entries: [] }), t;
571
+ }, i = null, a = null, o = /* @__PURE__ */ new Set(), c = (e) => {
530
572
  let t = e.catch(() => void 0).then(() => {
531
- i.delete(t);
573
+ o.delete(t);
532
574
  });
533
- return i.add(t), e;
575
+ return o.add(t), e;
534
576
  };
535
577
  return {
536
- commit: (i, o = {}) => {
537
- if (n) return n;
578
+ commit: (t, o = {}) => {
579
+ if (i) return i;
538
580
  let s = new AbortController();
539
- r = s;
540
- let c = o.signal;
541
- c?.aborted ? s.abort() : c?.addEventListener("abort", () => s.abort(), { once: !0 });
542
- let l = R({
581
+ a = s;
582
+ let l = o.signal;
583
+ l?.aborted ? s.abort() : l?.addEventListener("abort", () => s.abort(), { once: !0 });
584
+ let u = r(), d = n, f = new Set(t.map((e) => e.attachment.id));
585
+ for (let e of u.retained?.keys() ?? []) f.has(e) || u.retained?.delete(e);
586
+ let p = R({
543
587
  port: e.port,
588
+ preflightAccess: e.preflightAccess,
544
589
  folderPath: e.folderPath,
545
- drafts: i,
590
+ drafts: t,
546
591
  signal: s.signal,
547
592
  mode: o.mode,
548
593
  budgetMs: o.budgetMs,
549
- onChange: e.onChange,
550
- pendingDiscard: t,
594
+ onChange: (t, n) => {
595
+ e.getScopeKey?.() === d && e.onChange?.(t, n);
596
+ },
597
+ pendingDiscard: u,
551
598
  policy: e.policy,
552
599
  now: e.now,
553
600
  sleep: e.sleep
554
- }).then((e) => e.ok ? {
555
- ...e,
556
- rollback: () => a(e.rollback())
557
- } : e).finally(() => {
558
- n = null, r = null;
601
+ }).then(async (t) => t.ok ? e.getScopeKey?.() === d ? {
602
+ ...t,
603
+ rollback: () => c(t.rollback())
604
+ } : (await t.rollback(), {
605
+ ok: !1,
606
+ cancelled: !0,
607
+ failures: [],
608
+ message: void 0
609
+ }) : t).finally(() => {
610
+ i = null, a = null;
559
611
  });
560
- return n = l, l;
612
+ return i = p, p;
561
613
  },
562
- cancel: () => r?.abort(),
614
+ cancel: () => a?.abort(),
563
615
  get isCommitting() {
564
- return n !== null;
616
+ return i !== null;
565
617
  },
566
618
  discardPending: async () => {
567
- let r = n;
568
- for (r && await r.catch(() => void 0); i.size > 0;) await Promise.all([...i]);
569
- let a = () => P(e.port, t, {
619
+ if (e.getScopeKey?.() !== n) {
620
+ r();
621
+ return;
622
+ }
623
+ let a = t, c = n, l = i;
624
+ for (l && await l.catch(() => void 0); o.size > 0;) await Promise.all([...o]);
625
+ let u = () => e.getScopeKey?.() === c ? P(e.port, a, {
570
626
  sleep: e.sleep,
571
627
  policy: e.policy
572
- });
573
- await a();
574
- let s = {
575
- ...o,
628
+ }) : Promise.resolve();
629
+ await u();
630
+ let f = {
631
+ ...s,
576
632
  ...e.policy
577
- }, c = e.sleep ?? u;
578
- for (let e = 1; e <= s.finalDrainRounds && t.entries.length > 0; e += 1) await c(s.finalDrainDelayMs * e), await a();
633
+ }, p = e.sleep ?? d;
634
+ for (let t = 1; t <= f.finalDrainRounds && a.entries.length > 0 && e.getScopeKey?.() === c; t += 1) await p(f.finalDrainDelayMs * t), await u();
579
635
  },
580
636
  get pendingDiscard() {
581
637
  return t.entries;
@@ -602,4 +658,4 @@ async function K(e, t, n = Date.now()) {
602
658
  }));
603
659
  }
604
660
  //#endregion
605
- export { s as ATTACHMENT_COMMIT_CODES, o as ATTACHMENT_COMMIT_POLICY, a as ATTACHMENT_DIRECT_UPLOAD_MAX_BYTES, W as ATTACHMENT_URL_MAX_AGE_MS, G as attachmentUrlIsStale, R as commitAttachments, U as createAttachmentCommitter, P as drainPendingDiscards, K as refreshStaleAttachmentUrls };
661
+ export { c as ATTACHMENT_COMMIT_CODES, s as ATTACHMENT_COMMIT_POLICY, o as ATTACHMENT_DIRECT_UPLOAD_MAX_BYTES, W as ATTACHMENT_URL_MAX_AGE_MS, G as attachmentUrlIsStale, R as commitAttachments, U as createAttachmentCommitter, P as drainPendingDiscards, K as refreshStaleAttachmentUrls };