cursedbelt 5.99.1 → 5.99.2

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 +1 @@
1
- {"version":3,"file":"beaconClient.d.ts","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAYD,8DAA8D;AAC9D,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AAyBD;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,OAAO,CAAC,CA+BlB;AAED,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC9D;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBtG;AAED,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAIpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAehF"}
1
+ {"version":3,"file":"beaconClient.d.ts","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,2EAA2E;AAC3E,eAAO,MAAM,oBAAoB,oBAAoB,CAAC;AAEtD;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,sBAAsB,CAAC;AAEhD,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iDAAiD;IACjD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;OAOG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAaD;;;;;;GAMG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAYD,8DAA8D;AAC9D,wBAAgB,qBAAqB,IAAI,IAAI,CAG5C;AA6CD;;;;;GAKG;AACH,wBAAsB,WAAW,CAChC,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,kBAAuB,GAC9B,OAAO,CAAC,OAAO,CAAC,CAgClB;AAED,MAAM,WAAW,mBAAoB,SAAQ,kBAAkB;IAC9D;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,YAAY,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBtG;AAED,8DAA8D;AAC9D,MAAM,MAAM,UAAU,GAAG,MAAM,IAAI,CAAC;AAIpC;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,kBAAuB,GAAG,UAAU,CAehF"}
@@ -97,6 +97,23 @@ export function resetEngagementBeacon() {
97
97
  lastReported = null;
98
98
  sessionAnswer = null;
99
99
  }
100
+ /**
101
+ * Read an answer to its end, and drop it.
102
+ *
103
+ * 🔴 Chromium reports a fetch whose body nobody reads as STILL LOADING, so Playwright's
104
+ * `networkidle` never comes on a page that fired the beacon. flix's desktop design audit waited
105
+ * out its 15 s cap at every place it visited — 60 s of a 98 s gate (forge task 3884); the resume
106
+ * client learned the same thing in task 2574 (`deep-link/resume.ts`). Every answer this file
107
+ * receives — the probe's refusal, the recorder's reply — is read through here.
108
+ */
109
+ async function drain(res) {
110
+ try {
111
+ await res.text();
112
+ }
113
+ catch {
114
+ // The request was made; an answer that cannot be read changes nothing it reports.
115
+ }
116
+ }
100
117
  /**
101
118
  * Is there a session? Silent, cached, and false on any doubt.
102
119
  *
@@ -113,8 +130,10 @@ async function hasSession(options) {
113
130
  const res = await doFetch(options.sessionPath ?? SESSION_PATH, {
114
131
  credentials: "same-origin",
115
132
  });
116
- if (!res.ok)
133
+ if (!res.ok) {
134
+ await drain(res);
117
135
  return false;
136
+ }
118
137
  const body = (await res.json());
119
138
  return body?.authenticated === true;
120
139
  }
@@ -147,7 +166,7 @@ export async function reportPlace(place, options = {}) {
147
166
  return false;
148
167
  lastReported = place;
149
168
  try {
150
- await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
169
+ const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
151
170
  method: "POST",
152
171
  headers: { "content-type": "application/json" },
153
172
  // Same-origin credentials: the session cookie is the only identity
@@ -156,6 +175,7 @@ export async function reportPlace(place, options = {}) {
156
175
  body: JSON.stringify({ place }),
157
176
  keepalive: true,
158
177
  });
178
+ await drain(res);
159
179
  return true;
160
180
  }
161
181
  catch {
@@ -195,13 +215,14 @@ export async function reportAction(action, options = {}) {
195
215
  }
196
216
  const place = options.place ?? (typeof window === "undefined" ? "/" : currentLocationPlace());
197
217
  try {
198
- await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
218
+ const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
199
219
  method: "POST",
200
220
  headers: { "content-type": "application/json" },
201
221
  credentials: "same-origin",
202
222
  body: JSON.stringify({ place, action }),
203
223
  keepalive: true,
204
224
  });
225
+ await drain(res);
205
226
  return true;
206
227
  }
207
228
  catch {
@@ -1 +1 @@
1
- {"version":3,"file":"beaconClient.js","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmDG;AAEH,2EAA2E;AAC3E,MAAM,CAAC,MAAM,oBAAoB,GAAG,iBAAiB,CAAC;AAEtD;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,mBAAmB,CAAC;AAmBhD;;;;;;;;GAQG;AACH,IAAI,YAAY,GAAkB,IAAI,CAAC;AAEvC;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB;IACnC,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,IAAI,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,QAAQ,CAAC;IACnD,OAAO,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,CAAC;AACjC,CAAC;AAED;;;;;;;GAOG;AACH,IAAI,aAAa,GAA4B,IAAI,CAAC;AAElD,8DAA8D;AAC9D,MAAM,UAAU,qBAAqB;IACpC,YAAY,GAAG,IAAI,CAAC;IACpB,aAAa,GAAG,IAAI,CAAC;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,KAAK,UAAU,UAAU,CAAC,OAA2B;IACpD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACtD,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,CAAC;QACJ,MAAM,GAAG,GAAG,MAAM,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,YAAY,EAAE;YAC9D,WAAW,EAAE,aAAa;SAC1B,CAAC,CAAC;QACH,IAAI,CAAC,GAAG,CAAC,EAAE;YAAE,OAAO,KAAK,CAAC;QAC1B,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAuC,CAAC;QACtE,OAAO,IAAI,EAAE,aAAa,KAAK,IAAI,CAAC;IACrC,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,KAAa,EACb,UAA8B,EAAE;IAEhC,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,YAAY;QAAE,OAAO,KAAK,CAAC;IACnD,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACtD,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAEhD,6EAA6E;IAC7E,6EAA6E;IAC7E,0EAA0E;IAC1E,4CAA4C;IAC5C,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QACrC,aAAa,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC;YAAE,OAAO,KAAK,CAAC;IAC1C,CAAC;IAED,IAAI,KAAK,KAAK,YAAY;QAAE,OAAO,KAAK,CAAC;IACzC,YAAY,GAAG,KAAK,CAAC;IACrB,IAAI,CAAC;QACJ,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,oBAAoB,OAAO,EAAE;YACjE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,mEAAmE;YACnE,6DAA6D;YAC7D,WAAW,EAAE,aAAa;YAC1B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,CAAC;YAC/B,SAAS,EAAE,IAAI;SACf,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,8DAA8D;QAC9D,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAUD;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,MAAc,EAAE,UAA+B,EAAE;IACnF,IAAI,CAAC,MAAM;QAAE,OAAO,KAAK,CAAC;IAC1B,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC;IACtD,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,OAAO,KAAK,CAAC;IAChD,IAAI,OAAO,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;QACrC,aAAa,KAAK,UAAU,CAAC,OAAO,CAAC,CAAC;QACtC,IAAI,CAAC,CAAC,MAAM,aAAa,CAAC;YAAE,OAAO,KAAK,CAAC;IAC1C,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,CAAC,OAAO,MAAM,KAAK,WAAW,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,oBAAoB,EAAE,CAAC,CAAC;IAC9F,IAAI,CAAC;QACJ,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,QAAQ,IAAI,oBAAoB,SAAS,EAAE;YACnE,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,WAAW,EAAE,aAAa;YAC1B,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;YACvC,SAAS,EAAE,IAAI;SACf,CAAC,CAAC;QACH,OAAO,IAAI,CAAC;IACb,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,KAAK,CAAC;IACd,CAAC;AACF,CAAC;AAKD,IAAI,OAAO,GAAsB,IAAI,CAAC;AAEtC;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,UAAU,mBAAmB,CAAC,UAA8B,EAAE;IACnE,OAAO,EAAE,EAAE,CAAC;IACZ,MAAM,IAAI,GAAG,GAAS,EAAE;QACvB,KAAK,WAAW,CAAC,oBAAoB,EAAE,EAAE,OAAO,CAAC,CAAC;IACnD,CAAC,CAAC;IACF,IAAI,EAAE,CAAC;IACP,MAAM,CAAC,gBAAgB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAe,GAAG,EAAE;QAC7B,MAAM,CAAC,mBAAmB,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;QAC/C,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC7C,IAAI,OAAO,KAAK,IAAI;YAAE,OAAO,GAAG,IAAI,CAAC;IACtC,CAAC,CAAC;IACF,OAAO,GAAG,IAAI,CAAC;IACf,OAAO,IAAI,CAAC;AACb,CAAC"}
1
+ {"version":3,"file":"beaconClient.js","sourceRoot":"","sources":["../../../src/react/engagement/beaconClient.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cursedbelt",
3
- "version": "5.99.1",
3
+ "version": "5.99.2",
4
4
  "license": "ISC",
5
5
  "type": "module",
6
6
  "description": "The React design system of the cursedbelt split — components, styles, theme. cursedbelt-core below it; server tier in cursedbelt-server.",
@@ -965,7 +965,7 @@
965
965
  "@vidstack/react": "1.15.6",
966
966
  "@vitejs/plugin-react": "^5.2.0",
967
967
  "cursedbelt-server": "^4.43.1",
968
- "cursedops": "^0.21.0",
968
+ "cursedops": "^0.22.0",
969
969
  "diff": "^9.0.0",
970
970
  "emoji-mart": "^5.6.0",
971
971
  "hls.js": "^1.5.0",
@@ -15,21 +15,19 @@
15
15
  import { beforeEach, describe, expect, test } from "bun:test";
16
16
  import { reportAction, reportPlace, resetEngagementBeacon, SESSION_PATH } from "./beaconClient.js";
17
17
 
18
- /** A `fetch` that records every call and answers from a script. */
18
+ /** A `fetch` that records every call, and every answer it handed out, and answers from a script. */
19
19
  function recordingFetch(answers: Record<string, { status?: number; body?: unknown }>) {
20
20
  const calls: string[] = [];
21
+ const responses: Response[] = [];
21
22
  const impl = (async (input: string) => {
22
23
  const url = String(input);
23
24
  calls.push(url);
24
25
  const answer = answers[url] ?? { status: 404 };
25
- const status = answer.status ?? 200;
26
- return {
27
- ok: status >= 200 && status < 300,
28
- status,
29
- json: async () => answer.body ?? {},
30
- };
26
+ const response = new Response(JSON.stringify(answer.body ?? {}), { status: answer.status ?? 200 });
27
+ responses.push(response);
28
+ return response;
31
29
  }) as unknown as typeof fetch;
32
- return { impl, calls };
30
+ return { impl, calls, responses };
33
31
  }
34
32
 
35
33
  const SIGNED_IN = { body: { authenticated: true } };
@@ -116,18 +114,31 @@ describe("the probe fails CLOSED", () => {
116
114
  const impl = (async (input: string) => {
117
115
  if (answer === null) throw new Error("network down");
118
116
  const status = (answer as { status?: number }).status ?? 200;
119
- return {
120
- ok: status >= 200 && status < 300,
121
- status,
122
- json: async () => (answer as { body?: unknown }).body ?? {},
123
- _url: input,
124
- };
117
+ return new Response(JSON.stringify((answer as { body?: unknown }).body ?? {}), { status, headers: { "x-url": input } });
125
118
  }) as unknown as typeof fetch;
126
119
 
127
120
  expect(await reportPlace("/#/hub", { fetchImpl: impl })).toBe(false);
128
121
  });
129
122
  });
130
123
 
124
+ describe("every answer is read to its end (forge task 3884)", () => {
125
+ // Chromium reports a fetch whose body nobody reads as still loading, so Playwright's
126
+ // `networkidle` never came on a page that fired the beacon: flix's desktop audit waited out a
127
+ // 15 s cap at every place — 60 s of its 98 s gate.
128
+ test.each([
129
+ ["a signed-in view", { [SESSION_PATH]: SIGNED_IN, "/api/engagement/view": { status: 204 } }],
130
+ ["the recorder refuses", { [SESSION_PATH]: SIGNED_IN, "/api/engagement/view": { status: 404 } }],
131
+ ["the probe refuses", { [SESSION_PATH]: { status: 500 } }],
132
+ ["signed out", { [SESSION_PATH]: SIGNED_OUT }],
133
+ ])("%s — no response is left unread", async (_name, answers) => {
134
+ const { impl, responses } = recordingFetch(answers);
135
+ await reportPlace("/#/hub", { fetchImpl: impl });
136
+ await reportAction("search", { fetchImpl: impl, place: "/#/hub" });
137
+ expect(responses.length).toBeGreaterThan(0);
138
+ expect(responses.map((r) => r.bodyUsed)).toEqual(responses.map(() => true));
139
+ });
140
+ });
141
+
131
142
  describe("a caller that already knows may skip the probe", () => {
132
143
  test("assumeSignedIn reports with no second answer to the same question", async () => {
133
144
  const { impl, calls } = recordingFetch({ "/api/engagement/view": { status: 200 } });
@@ -121,6 +121,23 @@ export function resetEngagementBeacon(): void {
121
121
  sessionAnswer = null;
122
122
  }
123
123
 
124
+ /**
125
+ * Read an answer to its end, and drop it.
126
+ *
127
+ * 🔴 Chromium reports a fetch whose body nobody reads as STILL LOADING, so Playwright's
128
+ * `networkidle` never comes on a page that fired the beacon. flix's desktop design audit waited
129
+ * out its 15 s cap at every place it visited — 60 s of a 98 s gate (forge task 3884); the resume
130
+ * client learned the same thing in task 2574 (`deep-link/resume.ts`). Every answer this file
131
+ * receives — the probe's refusal, the recorder's reply — is read through here.
132
+ */
133
+ async function drain(res: Response): Promise<void> {
134
+ try {
135
+ await res.text();
136
+ } catch {
137
+ // The request was made; an answer that cannot be read changes nothing it reports.
138
+ }
139
+ }
140
+
124
141
  /**
125
142
  * Is there a session? Silent, cached, and false on any doubt.
126
143
  *
@@ -136,7 +153,10 @@ async function hasSession(options: ReportPlaceOptions): Promise<boolean> {
136
153
  const res = await doFetch(options.sessionPath ?? SESSION_PATH, {
137
154
  credentials: "same-origin",
138
155
  });
139
- if (!res.ok) return false;
156
+ if (!res.ok) {
157
+ await drain(res);
158
+ return false;
159
+ }
140
160
  const body = (await res.json()) as { authenticated?: unknown } | null;
141
161
  return body?.authenticated === true;
142
162
  } catch {
@@ -170,7 +190,7 @@ export async function reportPlace(
170
190
  if (place === lastReported) return false;
171
191
  lastReported = place;
172
192
  try {
173
- await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
193
+ const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/view`, {
174
194
  method: "POST",
175
195
  headers: { "content-type": "application/json" },
176
196
  // Same-origin credentials: the session cookie is the only identity
@@ -179,6 +199,7 @@ export async function reportPlace(
179
199
  body: JSON.stringify({ place }),
180
200
  keepalive: true,
181
201
  });
202
+ await drain(res);
182
203
  return true;
183
204
  } catch {
184
205
  // See the header: telemetry never becomes the user's problem.
@@ -223,13 +244,14 @@ export async function reportAction(action: string, options: ReportActionOptions
223
244
  }
224
245
  const place = options.place ?? (typeof window === "undefined" ? "/" : currentLocationPlace());
225
246
  try {
226
- await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
247
+ const res = await doFetch(`${options.basePath ?? ENGAGEMENT_BASE_PATH}/action`, {
227
248
  method: "POST",
228
249
  headers: { "content-type": "application/json" },
229
250
  credentials: "same-origin",
230
251
  body: JSON.stringify({ place, action }),
231
252
  keepalive: true,
232
253
  });
254
+ await drain(res);
233
255
  return true;
234
256
  } catch {
235
257
  return false;