@netlify/spark-ui 1.31.0-alpha.6 → 1.31.0-alpha.8

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.
@@ -160,6 +160,8 @@ function ne({
160
160
  return /* @__PURE__ */ e(o, { label: "Site’s live — taking you to claim it…" });
161
161
  case "dashboard":
162
162
  return /* @__PURE__ */ e(o, { label: "Site’s live — taking you to your new project…" });
163
+ default:
164
+ return null;
163
165
  }
164
166
  case "uploading": {
165
167
  const c = r.total ? Math.round(r.uploaded / r.total * 100) : 0;
@@ -1,5 +1,5 @@
1
- import { d as R, A as S, y as nt } from "../../../chunks/hooks.module.DRcxknIz.js";
2
- import { humanizeDropError as rt, isNotAuthenticatedError as O } from "../../../drop-core/errors.js";
1
+ import { d as R, A as _, y as nt } from "../../../chunks/hooks.module.DRcxknIz.js";
2
+ import { humanizeDropError as rt, isNotAuthenticatedError as v } from "../../../drop-core/errors.js";
3
3
  import { DROPZONE_EVENTS as c } from "../../../drop-core/analytics.js";
4
4
  import { renameSingleNonIndexHtmlToIndex as at, getSingleNonIndexHtmlFileName as ot, hasMultipleHtmlFilesWithoutIndex as st } from "../../../drop-core/readFiles.js";
5
5
  import { detectBuild as dt } from "../../../drop-core/detectBuild.js";
@@ -7,9 +7,9 @@ import { zipFiles as lt } from "../../../drop-core/zip.js";
7
7
  import { AnonymousDropClient as ut } from "../../../drop-core/client.js";
8
8
  import { AuthenticatedDropClient as ct } from "../../../drop-core/authedDropClient.js";
9
9
  import { AuthenticatedBuildClient as mt } from "../../../drop-core/buildClient.js";
10
- import { deployZippedBuild as ft, deployFiles as v } from "../../../drop-core/deploy.js";
11
- import { hasDropStashMarker as gt, loadDropStash as ht, clearDropStash as E, saveDropStash as pt } from "../../../drop-core/buildStash.js";
12
- function I(l) {
10
+ import { deployZippedBuild as ft, deployFiles as z } from "../../../drop-core/deploy.js";
11
+ import { hasDropStashMarker as gt, loadDropStash as ht, clearDropStash as I, saveDropStash as pt } from "../../../drop-core/buildStash.js";
12
+ function N(l) {
13
13
  switch (l.phase) {
14
14
  case "zipping":
15
15
  return { kind: "zipping" };
@@ -34,63 +34,64 @@ function St(l, m) {
34
34
  } catch {
35
35
  }
36
36
  }
37
- function Pt({
37
+ function Ft({
38
38
  apiBase: l,
39
39
  client: m,
40
- claimUrl: z,
40
+ claimUrl: Y,
41
41
  siteDashboardUrl: H,
42
42
  buildSignupUrl: W,
43
- buildClient: Y,
44
- authenticatedDropClient: M,
45
- getUploadToken: p,
46
- proxyBase: N,
47
- accountSlug: A,
43
+ buildClient: M,
44
+ authenticatedDropClient: Z,
45
+ getUploadToken: w,
46
+ proxyBase: A,
47
+ accountSlug: L,
48
48
  buildDeployUrl: C,
49
- waitForBuild: Z,
50
- onBuildRequired: L,
49
+ waitForBuild: $,
50
+ onBuildRequired: F,
51
51
  onBuildSignupHandoff: P,
52
- resumeStashedBuilds: $ = !0,
52
+ resumeStashedBuilds: q = !0,
53
53
  onDeploy: k,
54
54
  onBuildDeploy: f,
55
55
  onError: g,
56
- track: q
56
+ track: U
57
57
  }) {
58
58
  const u = (n, t) => (
59
59
  // The event interfaces carry no index signature, hence the cast to TrackFn's record.
60
- q(n, t)
61
- ), [b, a] = R({ kind: "idle" }), [U, _] = R(null), j = S(m ?? new ut(l)).current, w = S(
62
- Y ?? (p ? new mt({ proxyBase: N, getUploadToken: p, accountSlug: A }) : null)
63
- ).current, y = S(
64
- M ?? (p ? new ct({ proxyBase: N, getUploadToken: p, accountSlug: A }) : null)
65
- ).current, J = b.kind !== "idle" && b.kind !== "error";
60
+ U(n, t)
61
+ ), [b, o] = R({ kind: "idle" }), [j, D] = R(null), J = _(m ?? new ut(l)).current, S = _(
62
+ M ?? (w ? new mt({ proxyBase: A, getUploadToken: w, accountSlug: L }) : null)
63
+ ).current, E = _(
64
+ Z ?? (w ? new ct({ proxyBase: A, getUploadToken: w, accountSlug: L }) : null)
65
+ ).current, Q = b.kind !== "idle" && b.kind !== "error";
66
66
  async function x(n, t) {
67
67
  try {
68
- const { site: i, build: r, buildSettings: o, url: e } = await ft(n, t, {
69
- onProgress: (s) => a(I(s)),
70
- waitForBuild: Z
68
+ const { site: i, build: r, buildSettings: s, url: a } = await ft(n, t, {
69
+ onProgress: (e) => o(N(e)),
70
+ waitForBuild: $
71
71
  });
72
72
  return {
73
- url: e,
73
+ url: a,
74
74
  siteName: i.name,
75
75
  siteId: i.id,
76
76
  buildId: r.id,
77
77
  deployId: r.deploy_id,
78
- buildSettings: o
78
+ buildSettings: s
79
79
  };
80
80
  } catch (i) {
81
- if (O(i)) return null;
81
+ if (v(i)) return null;
82
82
  throw i;
83
83
  }
84
84
  }
85
- async function Q(n, t, i) {
86
- _(null), a({ kind: "reading" });
87
- const r = i.length ? { file_types: i } : {}, o = (e, s, d) => {
88
- a({ kind: "error", message: e }), u(c.DEPLOY_FAILED, { method: t, reason: s, ...r, ...d }), g == null || g({ message: e, reason: s });
85
+ async function T(n, t, i) {
86
+ D(null), o({ kind: "reading" });
87
+ const r = i.length ? { file_types: i } : {}, s = (e, d, h) => {
88
+ o({ kind: "error", message: e }), u(c.DEPLOY_FAILED, { method: t, reason: d, ...r, ...h }), g == null || g({ message: e, reason: d });
89
89
  };
90
+ let a;
90
91
  try {
91
92
  const e = at(await n());
92
- if (!e.length) {
93
- o("No files found to deploy.", "No files found to deploy.", { file_count: 0 });
93
+ if (a = e.length, !e.length) {
94
+ s("No files found to deploy.", "No files found to deploy.", { file_count: 0 });
94
95
  return;
95
96
  }
96
97
  t === "drag" && u(c.FILES_DROPPED, {
@@ -98,118 +99,127 @@ function Pt({
98
99
  file_count: e.length,
99
100
  ...r
100
101
  });
101
- const s = { source: t, fileCount: e.length, typeProps: r }, d = dt(e);
102
- d.buildRequired ? await T(e, d, s) : await G(e, s);
102
+ const d = { source: t, fileCount: e.length, typeProps: r }, h = dt(e);
103
+ h.buildRequired ? await V(e, h, d) : await K(e, d);
103
104
  } catch (e) {
104
- const s = e instanceof Error ? e.message : String(e);
105
- o(rt(e), s);
105
+ const d = e instanceof Error ? e.message : String(e);
106
+ s(
107
+ rt(e),
108
+ d,
109
+ a !== void 0 ? { file_count: a } : void 0
110
+ );
106
111
  }
107
112
  }
108
- async function T(n, t, { source: i, fileCount: r, typeProps: o }) {
113
+ async function V(n, t, { source: i, fileCount: r, typeProps: s }) {
109
114
  if (u(c.BUILD_REQUIRED, {
110
115
  method: i,
111
116
  reason: t.reason,
112
117
  file_count: r,
113
- ...o
114
- }), L) {
115
- a({ kind: "idle" }), L(t);
118
+ ...s
119
+ }), F) {
120
+ o({ kind: "idle" }), F(t);
116
121
  return;
117
122
  }
118
- let e = !1;
119
- if (w) {
120
- a({ kind: "zipping" });
121
- const s = await lt(n), d = await x(w, s);
123
+ let a = !1;
124
+ if (S) {
125
+ o({ kind: "zipping" });
126
+ const e = await lt(n), d = await x(S, e);
122
127
  if (d) {
123
- a({ kind: "redirecting", target: "build" }), u(c.BUILD_DEPLOY_SUCCEEDED, {
128
+ o({ kind: "redirecting", target: "build" }), u(c.BUILD_DEPLOY_SUCCEEDED, {
124
129
  method: i,
125
130
  reason: t.reason,
126
131
  site_name: d.siteName,
127
132
  file_count: r,
128
133
  ...d.buildSettings ? { framework: d.buildSettings.framework } : {},
129
- ...o
134
+ ...s
130
135
  }), f == null || f(d), window.location.assign(C(d));
131
136
  return;
132
137
  }
133
- e = await pt(s.file, s.buildSettings), e && u(c.PROJECT_STASHED, {
138
+ a = await pt(e.file, e.buildSettings), a && u(c.PROJECT_STASHED, {
134
139
  method: i,
135
140
  reason: t.reason,
136
141
  file_count: r,
137
- ...o
142
+ ...s
138
143
  });
139
144
  }
140
- if (P) {
141
- a({ kind: "idle" }), P({ stashed: e, detection: t });
145
+ if (a || u(c.DEPLOY_FAILED, {
146
+ method: i,
147
+ reason: "anonymous_build_not_supported",
148
+ file_count: r,
149
+ ...s
150
+ }), P) {
151
+ o({ kind: "idle" }), P({ stashed: a, detection: t });
142
152
  return;
143
153
  }
144
- a({ kind: "redirecting", target: "signup" }), window.location.assign(W);
154
+ o({ kind: "redirecting", target: "signup" }), window.location.assign(W);
145
155
  }
146
- async function V(n, t) {
156
+ async function G(n, t) {
147
157
  try {
148
- return await v(n, t, {
149
- onProgress: (i) => a(I(i))
158
+ return await z(n, t, {
159
+ onProgress: (i) => o(N(i))
150
160
  });
151
161
  } catch (i) {
152
- if (O(i)) return null;
162
+ if (v(i)) return null;
153
163
  throw i;
154
164
  }
155
165
  }
156
- async function G(n, { source: t, fileCount: i, typeProps: r }) {
157
- _(wt(n));
158
- const o = y ? await V(y, n) : null, e = o !== null, s = y !== null && !e, d = o ?? await v(j, n, {
159
- onProgress: (it) => a(I(it))
160
- }), { url: et, token: D, deploy: h } = d;
161
- e || St(D, h.subdomain), a({ kind: "redirecting", target: e ? "dashboard" : "claim" }), u(c.DEPLOY_SUCCEEDED, {
166
+ async function K(n, { source: t, fileCount: i, typeProps: r }) {
167
+ D(wt(n));
168
+ const s = E ? await G(E, n) : null, a = s !== null, e = E !== null && !a, d = s ?? await z(J, n, {
169
+ onProgress: (et) => o(N(et))
170
+ }), { url: h, token: y, deploy: p } = d;
171
+ a || St(y, p.subdomain), o({ kind: "redirecting", target: a ? "dashboard" : "claim" }), u(c.DEPLOY_SUCCEEDED, {
162
172
  method: t,
163
- site_name: h.subdomain,
173
+ site_name: p.subdomain,
164
174
  file_count: i,
165
- authenticated: e,
166
- ...s ? { auth_fallback: !0 } : {},
175
+ authenticated: a,
176
+ ...e ? { auth_fallback: !0 } : {},
167
177
  ...r
168
178
  }), k == null || k({
169
- url: et,
170
- ...e ? {} : { token: D },
171
- siteName: h.subdomain,
172
- siteId: h.id,
173
- authenticated: e
174
- }), K(e, h.subdomain, D);
179
+ url: h,
180
+ ...a ? {} : { token: y },
181
+ siteName: p.subdomain,
182
+ siteId: p.id,
183
+ authenticated: a
184
+ }), X(a, p.subdomain, y);
175
185
  }
176
- function K(n, t, i) {
177
- n ? window.location.assign(H(t)) : window.location.assign(`${z(t)}#drop_token=${i}`);
186
+ function X(n, t, i) {
187
+ n ? window.location.assign(H(t)) : window.location.assign(`${Y(t)}#drop_token=${i}`);
178
188
  }
179
- async function X(n) {
189
+ async function B(n) {
180
190
  const t = await ht();
181
191
  if (!t) {
182
- await E();
192
+ await I();
183
193
  return;
184
194
  }
185
- u(c.RESUMED, {}), a({ kind: "creating" });
195
+ o({ kind: "creating" });
186
196
  const i = { file: t.zipFile, buildSettings: t.buildSettings };
187
197
  let r;
188
198
  try {
189
199
  r = await x(n, i);
190
- } catch (o) {
191
- await E(), B(o instanceof Error ? o.message : String(o));
200
+ } catch (s) {
201
+ await I(), tt(s instanceof Error ? s.message : String(s));
192
202
  return;
193
203
  }
194
204
  if (!r) {
195
- a({ kind: "idle" });
205
+ o({ kind: "idle" });
196
206
  return;
197
207
  }
198
- await E(), a({ kind: "redirecting", target: "build" }), f == null || f(r), window.location.assign(C(r));
208
+ u(c.RESUMED, {}), await I(), o({ kind: "redirecting", target: "build" }), f == null || f(r), window.location.assign(C(r));
199
209
  }
200
- function B(n) {
210
+ function tt(n) {
201
211
  const t = "We couldn’t automatically deploy your project. Drop it again to publish it.";
202
- a({ kind: "error", message: t }), u(c.DEPLOY_FAILED, { reason: "resume_failed" }), g == null || g({ message: t, reason: n });
212
+ o({ kind: "error", message: t }), u(c.DEPLOY_FAILED, { reason: "resume_failed" }), g == null || g({ message: t, reason: n });
203
213
  }
204
- const F = S(!1);
214
+ const O = _(!1);
205
215
  nt(() => {
206
- F.current || !$ || !w || !gt() || (F.current = !0, X(w));
216
+ O.current || !q || !S || !gt() || (O.current = !0, B(S));
207
217
  }, []);
208
- function tt() {
209
- _(null), a({ kind: "idle" });
218
+ function it() {
219
+ D(null), o({ kind: "idle" });
210
220
  }
211
- return { status: b, warning: U, busy: J, deploy: Q, reset: tt };
221
+ return { status: b, warning: j, busy: Q, deploy: T, reset: it };
212
222
  }
213
223
  export {
214
- Pt as useDropDeploy
224
+ Ft as useDropDeploy
215
225
  };
@@ -1,4 +1,6 @@
1
1
  import { BuildSite } from './types';
2
+ import { SettledDeploy } from './pollDeploy';
3
+ export type { SettledDeploy } from './pollDeploy';
2
4
  /**
3
5
  * Transport shared by both authenticated clients: JSON rides the consumer's
4
6
  * access-control rewrite on the session cookie. Uploads are each client's own
@@ -10,19 +12,9 @@ import { BuildSite } from './types';
10
12
  * fallback is still safe, hence NotAuthenticatedError.
11
13
  */
12
14
  export declare function createSiteInAccount(proxyBase: string, accountSlug?: string): Promise<BuildSite>;
13
- /** How a watched deploy ended. `errorMessage` is the API's own explanation, when it gave one. */
14
- export type SettledDeploy = {
15
- outcome: 'ready';
16
- } | {
17
- outcome: 'failed';
18
- errorMessage?: string;
19
- } | {
20
- outcome: 'timed-out';
21
- };
22
15
  /**
23
- * Polls the deploy on the session cookie and reports the terminal outcome —
24
- * callers map it onto their own error vocabulary. Non-ok reads are skipped,
25
- * not fatal: a proxy hiccup shouldn't kill a progressing deploy.
16
+ * Polls a deploy over the session-cookie proxy — the shared `pollUntilSettled`
17
+ * loop with the cookie transport bound in. A non-ok read is skipped, not fatal.
26
18
  */
27
19
  export declare function pollDeployUntilSettled(options: {
28
20
  proxyBase: string;
@@ -1,30 +1,29 @@
1
- import { NotAuthenticatedError as d, SiteCreateError as l } from "./errors.js";
2
- async function f(r, o) {
3
- const s = o ? `/${o}/sites` : "/sites", e = await fetch(`${r}${s}`, {
1
+ import { NotAuthenticatedError as a, SiteCreateError as l } from "./errors.js";
2
+ import { pollUntilSettled as c } from "./pollDeploy.js";
3
+ async function u(o, e) {
4
+ const n = e ? `/${e}/sites` : "/sites", t = await fetch(`${o}${n}`, {
4
5
  method: "POST",
5
6
  credentials: "include",
6
7
  headers: { "Content-Type": "application/json" },
7
8
  body: JSON.stringify({ created_via: "drop" })
8
9
  });
9
- if (e.status === 401 || e.status === 403) throw new d();
10
- if (!e.ok) throw new l(e.status);
11
- return e.json();
10
+ if (t.status === 401 || t.status === 403) throw new a();
11
+ if (!t.ok) throw new l(t.status);
12
+ return t.json();
12
13
  }
13
- const u = /* @__PURE__ */ new Set(["ready", "error", "rejected"]);
14
- async function y(r) {
15
- const { proxyBase: o, deployId: s, pollIntervalMs: e, timeoutMs: i } = r, c = i / e;
16
- for (let n = 0; n < c; n++) {
17
- const a = await fetch(`${o}/deploys/${s}`, { credentials: "include" });
18
- if (a.ok) {
19
- const t = await a.json();
20
- if (t.state && u.has(t.state))
21
- return t.state === "ready" ? { outcome: "ready" } : { outcome: "failed", errorMessage: t.error_message };
14
+ function f(o) {
15
+ const { proxyBase: e, deployId: n, pollIntervalMs: t, timeoutMs: s } = o;
16
+ return c({
17
+ deployId: n,
18
+ pollIntervalMs: t,
19
+ timeoutMs: s,
20
+ readState: async (i) => {
21
+ const r = await fetch(`${e}/deploys/${i}`, { credentials: "include" });
22
+ return r.ok ? r.json() : null;
22
23
  }
23
- await new Promise((t) => setTimeout(t, e));
24
- }
25
- return { outcome: "timed-out" };
24
+ });
26
25
  }
27
26
  export {
28
- f as createSiteInAccount,
29
- y as pollDeployUntilSettled
27
+ u as createSiteInAccount,
28
+ f as pollDeployUntilSettled
30
29
  };
@@ -1,17 +1,20 @@
1
- const f = "netlify-drop";
1
+ const l = "netlify-drop";
2
2
  const s = "build-stash", c = "latest", i = "dropBuildStash";
3
- const S = (e) => Promise.race([
3
+ const f = (e) => Promise.race([
4
4
  e,
5
5
  new Promise((r, t) => {
6
6
  setTimeout(() => t(new Error("IndexedDB operation timed out")), 3e3);
7
7
  })
8
- ]), d = () => new Promise((e, r) => {
9
- const t = indexedDB.open(f, 1);
8
+ ]), S = () => new Promise((e, r) => {
9
+ const t = indexedDB.deleteDatabase(l);
10
+ t.onsuccess = () => e(), t.onblocked = () => e(), t.onerror = () => r(t.error);
11
+ }), p = () => new Promise((e, r) => {
12
+ const t = indexedDB.open(l, 1);
10
13
  t.onupgradeneeded = () => {
11
14
  t.result.createObjectStore(s);
12
15
  }, t.onsuccess = () => e(t.result), t.onerror = () => r(t.error);
13
- }), u = (e, r) => S(
14
- d().then(
16
+ }), u = (e, r) => f(
17
+ p().then(
15
18
  (t) => new Promise((o, a) => {
16
19
  const n = r(t.transaction(s, e).objectStore(s));
17
20
  n.onsuccess = () => {
@@ -21,33 +24,42 @@ const S = (e) => Promise.race([
21
24
  };
22
25
  })
23
26
  )
24
- ), p = async (e) => {
27
+ ), y = async (e) => {
25
28
  const { quota: r, usage: t } = await navigator.storage.estimate();
26
29
  return r !== void 0 && t !== void 0 && r - t > e * 2;
27
30
  }, T = () => {
28
- localStorage.setItem(i, JSON.stringify({ expiresAt: Date.now() + 864e5 }));
29
- }, l = () => {
31
+ localStorage.setItem(
32
+ i,
33
+ JSON.stringify({ value: "true", expiry: Date.now() + 864e5 })
34
+ );
35
+ }, d = () => {
30
36
  localStorage.removeItem(i);
31
37
  };
32
- async function A(e, r = null) {
38
+ async function O(e, r = null) {
33
39
  var t;
34
40
  try {
35
- if (typeof indexedDB > "u" || !((t = navigator.storage) != null && t.estimate) || e.size > 209715200 || !await p(e.size))
41
+ if (typeof indexedDB > "u" || !((t = navigator.storage) != null && t.estimate) || e.size > 209715200 || !await y(e.size))
36
42
  return !1;
37
- const o = { zipFile: e, buildSettings: r, createdAt: Date.now() };
43
+ const o = {
44
+ // Round-trip through JSON so an injected detector's richer object can't
45
+ // fail the structured clone the put() below performs.
46
+ buildSettings: r && JSON.parse(JSON.stringify(r)),
47
+ zipFile: e,
48
+ createdAt: Date.now()
49
+ };
38
50
  return await u("readwrite", (a) => a.put(o, c)), T(), !0;
39
51
  } catch {
40
52
  return !1;
41
53
  }
42
54
  }
43
- async function D() {
55
+ async function w() {
44
56
  try {
45
57
  if (typeof indexedDB > "u") return null;
46
58
  const e = await u(
47
59
  "readonly",
48
60
  (t) => t.get(c)
49
61
  ), r = e && _(e.zipFile);
50
- return !e || !r ? null : Date.now() - e.createdAt > 864e5 ? (await y(), null) : { ...e, zipFile: r };
62
+ return !e || !r ? null : Date.now() - e.createdAt > 864e5 ? (await D(), null) : { ...e, zipFile: r };
51
63
  } catch {
52
64
  return null;
53
65
  }
@@ -55,30 +67,30 @@ async function D() {
55
67
  function _(e) {
56
68
  return e instanceof File && e.name ? e : e instanceof Blob || e && typeof e.arrayBuffer == "function" ? new File([e], "source.zip", { type: "application/zip" }) : null;
57
69
  }
58
- async function y() {
70
+ async function D() {
59
71
  try {
60
- l();
72
+ d();
61
73
  } catch {
62
74
  }
63
75
  try {
64
76
  if (typeof indexedDB > "u") return;
65
- await u("readwrite", (e) => e.delete(c));
77
+ await u("readwrite", (e) => e.delete(c)), await f(S());
66
78
  } catch {
67
79
  }
68
80
  }
69
- function O() {
81
+ function E() {
70
82
  try {
71
83
  const e = localStorage.getItem(i);
72
84
  if (!e) return !1;
73
- const { expiresAt: r } = JSON.parse(e);
74
- return typeof r != "number" || Date.now() > r ? (l(), !1) : !0;
85
+ const { value: r, expiry: t } = JSON.parse(e);
86
+ return r !== "true" || typeof t != "number" || Date.now() > t ? (d(), !1) : !0;
75
87
  } catch {
76
88
  return !1;
77
89
  }
78
90
  }
79
91
  export {
80
- y as clearDropStash,
81
- O as hasDropStashMarker,
82
- D as loadDropStash,
83
- A as saveDropStash
92
+ D as clearDropStash,
93
+ E as hasDropStashMarker,
94
+ w as loadDropStash,
95
+ O as saveDropStash
84
96
  };
@@ -1,15 +1,16 @@
1
- import { DEFAULT_API_BASE as p, DEFAULT_POLL_INTERVAL_MS as l, DEFAULT_TIMEOUT_MS as h } from "./constants.js";
2
- import { DeployTimeoutError as d } from "./errors.js";
3
- function i(r, t) {
4
- return Object.assign(new Error(`${r} failed: ${t}`), { status: t });
1
+ import { DEFAULT_API_BASE as n, DEFAULT_POLL_INTERVAL_MS as l, DEFAULT_TIMEOUT_MS as p } from "./constants.js";
2
+ import { DeployFailedError as d, DeployTimeoutError as c } from "./errors.js";
3
+ import { pollUntilSettled as h } from "./pollDeploy.js";
4
+ function a(i, t) {
5
+ return Object.assign(new Error(`${i} failed: ${t}`), { status: t });
5
6
  }
6
- class y {
7
- constructor(t = p, o = l, e = h) {
7
+ class m {
8
+ constructor(t = n, o = l, e = p) {
8
9
  this.apiBase = t, this.pollIntervalMs = o, this.timeoutMs = e;
9
10
  }
10
11
  async getToken() {
11
12
  const t = await fetch(`${this.apiBase}/drop/token`, { method: "POST" });
12
- if (!t.ok) throw i("drop/token", t.status);
13
+ if (!t.ok) throw a("drop/token", t.status);
13
14
  return (await t.json()).token;
14
15
  }
15
16
  async createDeploy(t, o) {
@@ -18,30 +19,37 @@ class y {
18
19
  headers: { "Content-Type": "application/json" },
19
20
  body: JSON.stringify({ files: t, token: o })
20
21
  });
21
- if (!e.ok) throw i("drop", e.status);
22
+ if (!e.ok) throw a("drop", e.status);
22
23
  return e.json();
23
24
  }
24
- async uploadFile(t, o, e, a) {
25
- const s = await fetch(`${this.apiBase}/deploys/${t}/files${o}`, {
25
+ async uploadFile(t, o, e, s) {
26
+ const r = await fetch(`${this.apiBase}/deploys/${t}/files${o}`, {
26
27
  method: "PUT",
27
- headers: { "Content-Type": "application/octet-stream", Authorization: `Bearer ${a}` },
28
+ headers: { "Content-Type": "application/octet-stream", Authorization: `Bearer ${s}` },
28
29
  body: e
29
30
  });
30
- if (!s.ok) throw i(`upload ${o}`, s.status);
31
+ if (!r.ok) throw a(`upload ${o}`, r.status);
31
32
  }
32
33
  async waitUntilReady(t, o) {
33
- const e = this.timeoutMs / this.pollIntervalMs;
34
- for (let a = 0; a < e; a++) {
35
- const s = await fetch(`${this.apiBase}/deploys/${t.deploy_id}`, {
36
- headers: { Authorization: `Bearer ${o}` }
37
- });
38
- if (s.ok && (await s.json()).state === "ready") return;
39
- await new Promise((n) => setTimeout(n, this.pollIntervalMs));
40
- }
41
- throw new d();
34
+ const e = await h({
35
+ deployId: t.deploy_id,
36
+ pollIntervalMs: this.pollIntervalMs,
37
+ timeoutMs: this.timeoutMs,
38
+ // `/deploys/{id}` expects the deploy_id (BSON), not the site id (UUID) that
39
+ // lives at `deploy.id`. See drop_controller.rb; Deploy.find(uuid) is nil and
40
+ // the request 401s misleadingly via require_current_actor!.
41
+ readState: async (s) => {
42
+ const r = await fetch(`${this.apiBase}/deploys/${s}`, {
43
+ headers: { Authorization: `Bearer ${o}` }
44
+ });
45
+ return r.ok ? r.json() : null;
46
+ }
47
+ });
48
+ if (e.outcome !== "ready")
49
+ throw e.outcome === "failed" ? new d(e.errorMessage) : new c();
42
50
  }
43
51
  }
44
52
  export {
45
- y as AnonymousDropClient,
46
- i as apiError
53
+ m as AnonymousDropClient,
54
+ a as apiError
47
55
  };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,31 @@
1
+ /**
2
+ * The single deploy poller both drop clients share. The loop and its
3
+ * terminal-state policy live here once; transport (cookie proxy vs bearer) is
4
+ * injected via `readState`, so the anonymous and authenticated paths can't
5
+ * drift on what "done" means.
6
+ */
7
+ /** How a watched deploy ended. `errorMessage` is the API's own explanation, when it gave one. */
8
+ export type SettledDeploy = {
9
+ outcome: 'ready';
10
+ } | {
11
+ outcome: 'failed';
12
+ errorMessage?: string;
13
+ } | {
14
+ outcome: 'timed-out';
15
+ };
16
+ /** The slice of a deploy record the poller reads; `null` = a read that failed and should be skipped. */
17
+ export interface DeployState {
18
+ state?: string;
19
+ error_message?: string;
20
+ }
21
+ /**
22
+ * Poll until the deploy reaches a terminal state or the timeout elapses.
23
+ * A `null` read is skipped, not fatal — a transient hiccup shouldn't kill a
24
+ * progressing deploy. Callers map the outcome onto their own error vocabulary.
25
+ */
26
+ export declare function pollUntilSettled(options: {
27
+ deployId: string;
28
+ pollIntervalMs: number;
29
+ timeoutMs: number;
30
+ readState: (deployId: string) => Promise<DeployState | null>;
31
+ }): Promise<SettledDeploy>;
@@ -0,0 +1,14 @@
1
+ const c = /* @__PURE__ */ new Set(["ready", "error", "rejected"]);
2
+ async function l(r) {
3
+ const { deployId: a, pollIntervalMs: t, timeoutMs: s, readState: n } = r, i = s / t;
4
+ for (let o = 0; o < i; o++) {
5
+ const e = await n(a);
6
+ if (e != null && e.state && c.has(e.state))
7
+ return e.state === "ready" ? { outcome: "ready" } : { outcome: "failed", errorMessage: e.error_message };
8
+ await new Promise((d) => setTimeout(d, t));
9
+ }
10
+ return { outcome: "timed-out" };
11
+ }
12
+ export {
13
+ l as pollUntilSettled
14
+ };
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@netlify/spark-ui",
3
3
  "description": "Assets, design tokens, components, and utilities",
4
- "version": "1.31.0-alpha.6",
4
+ "version": "1.31.0-alpha.8",
5
5
  "type": "module",
6
6
  "main": "dist/components/preact/index.js",
7
7
  "types": "dist/components/preact/index.d.ts",