defuss-runtime 1.2.0 → 1.2.1

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.
Files changed (3) hide show
  1. package/dist/index.cjs +56 -21
  2. package/dist/index.mjs +56 -21
  3. package/package.json +10 -12
package/dist/index.cjs CHANGED
@@ -270,42 +270,77 @@ function wait(ms) {
270
270
  }
271
271
  function createTimeoutPromise(timeoutMs, operation, timeoutCallback) {
272
272
  return new Promise((resolve, reject) => {
273
+ let completed = false;
273
274
  const timeoutId = setTimeout(() => {
274
- timeoutCallback?.(timeoutMs);
275
- reject(new Error(`Timeout after ${timeoutMs}ms`));
275
+ if (!completed) {
276
+ completed = true;
277
+ timeoutCallback?.(timeoutMs);
278
+ reject(new Error(`Timeout after ${timeoutMs}ms`));
279
+ }
276
280
  }, timeoutMs);
277
281
  Promise.resolve().then(async () => {
278
282
  try {
279
283
  const result = await operation();
280
- clearTimeout(timeoutId);
281
- resolve(result);
284
+ if (!completed) {
285
+ completed = true;
286
+ clearTimeout(timeoutId);
287
+ resolve(result);
288
+ }
282
289
  } catch (error) {
283
- clearTimeout(timeoutId);
284
- reject(error);
290
+ if (!completed) {
291
+ completed = true;
292
+ clearTimeout(timeoutId);
293
+ reject(error);
294
+ }
285
295
  }
286
296
  });
287
297
  });
288
298
  }
289
299
  async function waitForWithPolling(check, timeout, interval = 1) {
290
- return createTimeoutPromise(timeout, () => {
291
- return new Promise((resolve, reject) => {
292
- const timer = setInterval(() => {
293
- try {
294
- const result = check();
295
- if (result != null) {
296
- clearInterval(timer);
297
- resolve(result);
300
+ const start = Date.now();
301
+ let timer;
302
+ const cleanup = () => {
303
+ if (timer) {
304
+ clearInterval(timer);
305
+ }
306
+ };
307
+ try {
308
+ return await createTimeoutPromise(timeout, () => {
309
+ return new Promise((resolve, reject) => {
310
+ let pollCount = 0;
311
+ timer = setInterval(() => {
312
+ pollCount++;
313
+ const elapsed = Date.now() - start;
314
+ try {
315
+ const result = check();
316
+ if (result != null) {
317
+ cleanup();
318
+ resolve(result);
319
+ }
320
+ } catch (err) {
321
+ console.log(
322
+ `\u274C waitForWithPolling() error on poll #${pollCount}:`,
323
+ err
324
+ );
325
+ cleanup();
326
+ reject(err);
298
327
  }
299
- } catch (err) {
300
- clearInterval(timer);
301
- reject(err);
302
- }
303
- }, interval);
328
+ }, interval);
329
+ });
304
330
  });
305
- });
331
+ } catch (error) {
332
+ cleanup();
333
+ throw error;
334
+ }
306
335
  }
307
336
  async function waitForRef(ref, timeout) {
308
- return waitForWithPolling(() => ref.current, timeout);
337
+ return waitForWithPolling(() => {
338
+ if (ref.orphan) {
339
+ console.log("\u26A0\uFE0F waitForRef() - ref is marked as orphaned, failing fast");
340
+ throw new Error("Ref has been orphaned from component unmount");
341
+ }
342
+ return ref.current;
343
+ }, timeout);
309
344
  }
310
345
 
311
346
  const asString = (value) => {
package/dist/index.mjs CHANGED
@@ -268,42 +268,77 @@ function wait(ms) {
268
268
  }
269
269
  function createTimeoutPromise(timeoutMs, operation, timeoutCallback) {
270
270
  return new Promise((resolve, reject) => {
271
+ let completed = false;
271
272
  const timeoutId = setTimeout(() => {
272
- timeoutCallback?.(timeoutMs);
273
- reject(new Error(`Timeout after ${timeoutMs}ms`));
273
+ if (!completed) {
274
+ completed = true;
275
+ timeoutCallback?.(timeoutMs);
276
+ reject(new Error(`Timeout after ${timeoutMs}ms`));
277
+ }
274
278
  }, timeoutMs);
275
279
  Promise.resolve().then(async () => {
276
280
  try {
277
281
  const result = await operation();
278
- clearTimeout(timeoutId);
279
- resolve(result);
282
+ if (!completed) {
283
+ completed = true;
284
+ clearTimeout(timeoutId);
285
+ resolve(result);
286
+ }
280
287
  } catch (error) {
281
- clearTimeout(timeoutId);
282
- reject(error);
288
+ if (!completed) {
289
+ completed = true;
290
+ clearTimeout(timeoutId);
291
+ reject(error);
292
+ }
283
293
  }
284
294
  });
285
295
  });
286
296
  }
287
297
  async function waitForWithPolling(check, timeout, interval = 1) {
288
- return createTimeoutPromise(timeout, () => {
289
- return new Promise((resolve, reject) => {
290
- const timer = setInterval(() => {
291
- try {
292
- const result = check();
293
- if (result != null) {
294
- clearInterval(timer);
295
- resolve(result);
298
+ const start = Date.now();
299
+ let timer;
300
+ const cleanup = () => {
301
+ if (timer) {
302
+ clearInterval(timer);
303
+ }
304
+ };
305
+ try {
306
+ return await createTimeoutPromise(timeout, () => {
307
+ return new Promise((resolve, reject) => {
308
+ let pollCount = 0;
309
+ timer = setInterval(() => {
310
+ pollCount++;
311
+ const elapsed = Date.now() - start;
312
+ try {
313
+ const result = check();
314
+ if (result != null) {
315
+ cleanup();
316
+ resolve(result);
317
+ }
318
+ } catch (err) {
319
+ console.log(
320
+ `\u274C waitForWithPolling() error on poll #${pollCount}:`,
321
+ err
322
+ );
323
+ cleanup();
324
+ reject(err);
296
325
  }
297
- } catch (err) {
298
- clearInterval(timer);
299
- reject(err);
300
- }
301
- }, interval);
326
+ }, interval);
327
+ });
302
328
  });
303
- });
329
+ } catch (error) {
330
+ cleanup();
331
+ throw error;
332
+ }
304
333
  }
305
334
  async function waitForRef(ref, timeout) {
306
- return waitForWithPolling(() => ref.current, timeout);
335
+ return waitForWithPolling(() => {
336
+ if (ref.orphan) {
337
+ console.log("\u26A0\uFE0F waitForRef() - ref is marked as orphaned, failing fast");
338
+ throw new Error("Ref has been orphaned from component unmount");
339
+ }
340
+ return ref.current;
341
+ }, timeout);
307
342
  }
308
343
 
309
344
  const asString = (value) => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "defuss-runtime",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "type": "module",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -20,6 +20,13 @@
20
20
  "url": "git+https://github.com/kyr0/defuss.git",
21
21
  "type": "git"
22
22
  },
23
+ "scripts": {
24
+ "clean": "rm -rf ./node_modules/.pnpm",
25
+ "pretest": "pnpm run build",
26
+ "prebuild": "pnpm run clean",
27
+ "build": "pkgroll",
28
+ "test": "vitest --run --coverage"
29
+ },
23
30
  "author": "Aron Homberg <info@aron-homberg.de>",
24
31
  "sideEffects": false,
25
32
  "exports": {
@@ -37,9 +44,7 @@
37
44
  "main": "./dist/index.cjs",
38
45
  "module": "./dist/index.mjs",
39
46
  "types": "./dist/index.d.cts",
40
- "files": [
41
- "dist"
42
- ],
47
+ "files": ["dist"],
43
48
  "engines": {
44
49
  "node": "^18.17.1 || ^20.3.0 || >=21.0.0"
45
50
  },
@@ -49,12 +54,5 @@
49
54
  "typescript": "^5.6.3",
50
55
  "vitest": "^3.1.3",
51
56
  "@vitest/coverage-v8": "^3.1.3"
52
- },
53
- "scripts": {
54
- "clean": "rm -rf ./node_modules/.pnpm",
55
- "pretest": "pnpm run build",
56
- "prebuild": "pnpm run clean",
57
- "build": "pkgroll",
58
- "test": "vitest --run --coverage"
59
57
  }
60
- }
58
+ }