defuss-runtime 1.2.0 → 1.3.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.
package/dist/index.cjs CHANGED
@@ -270,42 +270,76 @@ 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
- Promise.resolve().then(async () => {
281
+ (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 = null;
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
+ }
341
+ return ref.current;
342
+ }, timeout);
309
343
  }
310
344
 
311
345
  const asString = (value) => {
package/dist/index.d.cts CHANGED
@@ -571,4 +571,5 @@ declare const isNull: ValidatorPrimitiveFn;
571
571
  type PreloadAs = "image" | "script" | "style" | "fetch" | "track" | "font";
572
572
  declare function preload(url: string | string[], as?: PreloadAs): void;
573
573
 
574
- export { type DateValue, type Dynamic, PATH_ACCESSOR_SYMBOL, type PathAccessor, type PreloadAs, type SingleValidationResult, type ValidationFnResult, type ValidationMessage, type ValidationStep, type ValidatorFn, type ValidatorPrimitiveFn, _BASE64_CHARS, _HEX_PREFIX, _base64LookupMap, _getBase64LookupMap, access, asArray, asBoolean, asDate, asInteger, asNumber, asString, base64ToBinary, binaryToBase64, binaryToHex, binaryToText, createTimeoutPromise, debounce, ensureKey, equalsJSON, getAllKeysFromPath, getByPath, getDateValue, hasDateFormat, hasPattern, hexToBinary, is, isAfter, isArray, isBefore, isBoolean, isDate, isDefined, isEmail, isEmpty, isEqual, isFalse, isFalsy, isGreaterThan, isInstanceOf, isInteger, isLessThan, isLongerThan, isNull, isObject, isOneOf, isPathAccessor, isPhoneNumber, isRequired, isSafeNumber, isSafeNumeric, isShorterThan, isSlug, isString, isTrue, isTruthy, isTypeOf, isUrl, isUrlPath, omit, pick, preload, setByPath, textToBinary, throttle, unique, wait, waitForRef, waitForWithPolling };
574
+ export { PATH_ACCESSOR_SYMBOL, _BASE64_CHARS, _HEX_PREFIX, _base64LookupMap, _getBase64LookupMap, access, asArray, asBoolean, asDate, asInteger, asNumber, asString, base64ToBinary, binaryToBase64, binaryToHex, binaryToText, createTimeoutPromise, debounce, ensureKey, equalsJSON, getAllKeysFromPath, getByPath, getDateValue, hasDateFormat, hasPattern, hexToBinary, is, isAfter, isArray, isBefore, isBoolean, isDate, isDefined, isEmail, isEmpty, isEqual, isFalse, isFalsy, isGreaterThan, isInstanceOf, isInteger, isLessThan, isLongerThan, isNull, isObject, isOneOf, isPathAccessor, isPhoneNumber, isRequired, isSafeNumber, isSafeNumeric, isShorterThan, isSlug, isString, isTrue, isTruthy, isTypeOf, isUrl, isUrlPath, omit, pick, preload, setByPath, textToBinary, throttle, unique, wait, waitForRef, waitForWithPolling };
575
+ export type { DateValue, Dynamic, PathAccessor, PreloadAs, SingleValidationResult, ValidationFnResult, ValidationMessage, ValidationStep, ValidatorFn, ValidatorPrimitiveFn };
package/dist/index.d.mts CHANGED
@@ -571,4 +571,5 @@ declare const isNull: ValidatorPrimitiveFn;
571
571
  type PreloadAs = "image" | "script" | "style" | "fetch" | "track" | "font";
572
572
  declare function preload(url: string | string[], as?: PreloadAs): void;
573
573
 
574
- export { type DateValue, type Dynamic, PATH_ACCESSOR_SYMBOL, type PathAccessor, type PreloadAs, type SingleValidationResult, type ValidationFnResult, type ValidationMessage, type ValidationStep, type ValidatorFn, type ValidatorPrimitiveFn, _BASE64_CHARS, _HEX_PREFIX, _base64LookupMap, _getBase64LookupMap, access, asArray, asBoolean, asDate, asInteger, asNumber, asString, base64ToBinary, binaryToBase64, binaryToHex, binaryToText, createTimeoutPromise, debounce, ensureKey, equalsJSON, getAllKeysFromPath, getByPath, getDateValue, hasDateFormat, hasPattern, hexToBinary, is, isAfter, isArray, isBefore, isBoolean, isDate, isDefined, isEmail, isEmpty, isEqual, isFalse, isFalsy, isGreaterThan, isInstanceOf, isInteger, isLessThan, isLongerThan, isNull, isObject, isOneOf, isPathAccessor, isPhoneNumber, isRequired, isSafeNumber, isSafeNumeric, isShorterThan, isSlug, isString, isTrue, isTruthy, isTypeOf, isUrl, isUrlPath, omit, pick, preload, setByPath, textToBinary, throttle, unique, wait, waitForRef, waitForWithPolling };
574
+ export { PATH_ACCESSOR_SYMBOL, _BASE64_CHARS, _HEX_PREFIX, _base64LookupMap, _getBase64LookupMap, access, asArray, asBoolean, asDate, asInteger, asNumber, asString, base64ToBinary, binaryToBase64, binaryToHex, binaryToText, createTimeoutPromise, debounce, ensureKey, equalsJSON, getAllKeysFromPath, getByPath, getDateValue, hasDateFormat, hasPattern, hexToBinary, is, isAfter, isArray, isBefore, isBoolean, isDate, isDefined, isEmail, isEmpty, isEqual, isFalse, isFalsy, isGreaterThan, isInstanceOf, isInteger, isLessThan, isLongerThan, isNull, isObject, isOneOf, isPathAccessor, isPhoneNumber, isRequired, isSafeNumber, isSafeNumeric, isShorterThan, isSlug, isString, isTrue, isTruthy, isTypeOf, isUrl, isUrlPath, omit, pick, preload, setByPath, textToBinary, throttle, unique, wait, waitForRef, waitForWithPolling };
575
+ export type { DateValue, Dynamic, PathAccessor, PreloadAs, SingleValidationResult, ValidationFnResult, ValidationMessage, ValidationStep, ValidatorFn, ValidatorPrimitiveFn };
package/dist/index.mjs CHANGED
@@ -268,42 +268,76 @@ 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
- Promise.resolve().then(async () => {
279
+ (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 = null;
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
+ }
339
+ return ref.current;
340
+ }, timeout);
307
341
  }
308
342
 
309
343
  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.3.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": {
@@ -44,17 +51,10 @@
44
51
  "node": "^18.17.1 || ^20.3.0 || >=21.0.0"
45
52
  },
46
53
  "devDependencies": {
47
- "pkgroll": "^2.5.1",
48
- "tsx": "^4.19.2",
49
- "typescript": "^5.6.3",
50
- "vitest": "^3.1.3",
51
- "@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"
54
+ "@vitest/coverage-v8": "^4.0.17",
55
+ "pkgroll": "^2.21.5",
56
+ "tsx": "^4.21.0",
57
+ "typescript": "^5.9.3",
58
+ "vitest": "^4.0.17"
59
59
  }
60
60
  }