@gershy/clearing 0.0.16 → 0.0.19

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/cmp/cjs/main.d.ts CHANGED
@@ -16,5 +16,15 @@ export declare const getCls: (i: any) => any;
16
16
  export declare const isCls: ClsCheck;
17
17
  export declare const inCls: ClsCheck;
18
18
  export declare const skip: undefined;
19
+ type Then = {
20
+ <V, R0 = V, R1 = never>(val: Promise<V>, rsv?: (v: V) => R0, rjc?: (e: any) => R1): Promise<R0 | R1>;
21
+ <V, R0 = V, R1 = never>(val: V, rsv?: (v: V) => R0, rjc?: (e: any) => R1): R0 | R1;
22
+ };
23
+ export declare const then: Then;
24
+ type Safe = {
25
+ <V, R0 = never>(fn: () => Promise<V>, rjc?: (e: any) => R0): Promise<V | R0>;
26
+ <V, R0 = never>(fn: () => V, rjc?: (e: any) => R0): Promise<V | R0>;
27
+ };
28
+ export declare const safe: Safe;
19
29
  declare const applyClearing: () => void;
20
30
  export default applyClearing;
package/cmp/cjs/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.skip = exports.inCls = exports.isCls = exports.getCls = exports.getClsName = void 0;
3
+ exports.safe = exports.then = exports.skip = exports.inCls = exports.isCls = exports.getCls = exports.getClsName = void 0;
4
4
  const getClsName = i => {
5
5
  if (i === null)
6
6
  return 'Null';
@@ -27,6 +27,30 @@ exports.isCls = isCls;
27
27
  const inCls = (i, C) => i instanceof C;
28
28
  exports.inCls = inCls;
29
29
  exports.skip = undefined;
30
+ const then = (val, rsv = (v => v), rjc = ((e) => { throw e; })) => {
31
+ // Act on `val` regardless of whether it's a Promise or immediate value; return `rsv(val)`
32
+ // either immediately or as a Promise
33
+ if ((0, exports.inCls)(val, Promise))
34
+ return val.then(rsv).catch(rjc);
35
+ try {
36
+ return rsv(val);
37
+ }
38
+ catch (err) {
39
+ return rjc(err);
40
+ }
41
+ };
42
+ exports.then = then;
43
+ const safe = (fn, rjc = e => { throw e; }) => {
44
+ // Execute a function which returns a value either synchronously or asynchronously; in both cases
45
+ // allows errors occurring from function execution to be handled
46
+ try {
47
+ return (0, exports.then)(fn(), v => v, rjc);
48
+ }
49
+ catch (err) {
50
+ return rjc(err);
51
+ }
52
+ };
53
+ exports.safe = safe;
30
54
  const applyClearing = (() => {
31
55
  const global = globalThis;
32
56
  // Prevent multiple installations...
@@ -435,7 +459,7 @@ const applyClearing = (() => {
435
459
  return Object.assign(this, (0, exports.inCls)(cause, Error) ? cause : {}, moreProps, cause ? { message, cause } : { message });
436
460
  },
437
461
  [suppress]() {
438
- this[Symbol.for('clearing.err.suppressed')] = true;
462
+ this[Symbol.for('@gershy.clearing.err.suppressed')] = true;
439
463
  if (this.cause) {
440
464
  const causes = (0, exports.inCls)(this.cause, Error) ? [this.cause] : this.cause;
441
465
  for (const err of causes)
package/cmp/mjs/main.d.ts CHANGED
@@ -16,5 +16,15 @@ export declare const getCls: (i: any) => any;
16
16
  export declare const isCls: ClsCheck;
17
17
  export declare const inCls: ClsCheck;
18
18
  export declare const skip: undefined;
19
+ type Then = {
20
+ <V, R0 = V, R1 = never>(val: Promise<V>, rsv?: (v: V) => R0, rjc?: (e: any) => R1): Promise<R0 | R1>;
21
+ <V, R0 = V, R1 = never>(val: V, rsv?: (v: V) => R0, rjc?: (e: any) => R1): R0 | R1;
22
+ };
23
+ export declare const then: Then;
24
+ type Safe = {
25
+ <V, R0 = never>(fn: () => Promise<V>, rjc?: (e: any) => R0): Promise<V | R0>;
26
+ <V, R0 = never>(fn: () => V, rjc?: (e: any) => R0): Promise<V | R0>;
27
+ };
28
+ export declare const safe: Safe;
19
29
  declare const applyClearing: () => void;
20
30
  export default applyClearing;
package/cmp/mjs/main.js CHANGED
@@ -20,6 +20,28 @@ export const isCls = (i, C) => {
20
20
  };
21
21
  export const inCls = (i, C) => i instanceof C;
22
22
  export const skip = undefined;
23
+ export const then = (val, rsv = (v => v), rjc = ((e) => { throw e; })) => {
24
+ // Act on `val` regardless of whether it's a Promise or immediate value; return `rsv(val)`
25
+ // either immediately or as a Promise
26
+ if (inCls(val, Promise))
27
+ return val.then(rsv).catch(rjc);
28
+ try {
29
+ return rsv(val);
30
+ }
31
+ catch (err) {
32
+ return rjc(err);
33
+ }
34
+ };
35
+ export const safe = (fn, rjc = e => { throw e; }) => {
36
+ // Execute a function which returns a value either synchronously or asynchronously; in both cases
37
+ // allows errors occurring from function execution to be handled
38
+ try {
39
+ return then(fn(), v => v, rjc);
40
+ }
41
+ catch (err) {
42
+ return rjc(err);
43
+ }
44
+ };
23
45
  const applyClearing = (() => {
24
46
  const global = globalThis;
25
47
  // Prevent multiple installations...
@@ -428,7 +450,7 @@ const applyClearing = (() => {
428
450
  return Object.assign(this, inCls(cause, Error) ? cause : {}, moreProps, cause ? { message, cause } : { message });
429
451
  },
430
452
  [suppress]() {
431
- this[Symbol.for('clearing.err.suppressed')] = true;
453
+ this[Symbol.for('@gershy.clearing.err.suppressed')] = true;
432
454
  if (this.cause) {
433
455
  const causes = inCls(this.cause, Error) ? [this.cause] : this.cause;
434
456
  for (const err of causes)
@@ -204,7 +204,7 @@ declare global {
204
204
 
205
205
  interface PromiseConstructor {
206
206
  [allArr]: PromiseConstructor['all'],
207
- [allObj]: <O extends { [K: string]: Promise<any> }>(obj: O) => Promise<{ [K in keyof O]: Awaited<O[K]> }>,
207
+ [allObj]: <O extends { [K: string]: Promise<any> }>(obj: O) => Promise<{ [K in keyof O]: Exclude<Awaited<O[K]>, Skip> }>,
208
208
  [later]: <T=void>() => PromiseLater<T>
209
209
  }
210
210
  interface Promise<T> {}
package/package.json CHANGED
@@ -1,6 +1,7 @@
1
1
  {
2
2
  "name": "@gershy/clearing",
3
- "version": "0.0.16",
3
+ "version": "0.0.19",
4
+ "versionCommit": "ccce646c1a4bc2ec3f349a1b02a8498a930c373e",
4
5
  "description": "Adds the features you always wish javascript had!",
5
6
  "keywords": [
6
7
  "clearing",
@@ -22,7 +23,6 @@
22
23
  "tsx": "^4.21.0",
23
24
  "typescript": "^5.9.3"
24
25
  },
25
-
26
26
  "type": "module",
27
27
  "files": [
28
28
  "cmp"
@@ -34,15 +34,14 @@
34
34
  "require": "./cmp/cjs/main.js"
35
35
  }
36
36
  },
37
-
38
37
  "scripts": {
39
38
  "test": "npm run ts.check && npx tsx ./src/main.test.ts",
40
39
  "ts.check": "npx tsc --noEmit",
41
- "build.cjs": "tsc -p ts/tsconfig.cjs.json",
42
- "build.mjs": "tsc -p ts/tsconfig.mjs.json",
43
- "build": "node ./build.js removeCmp && npm run build.cjs && npm run build.mjs && node ./build.js finalizeExportVariants",
40
+ "build.cjs": "tsc -p build/tsconfig.cjs.json",
41
+ "build.mjs": "tsc -p build/tsconfig.mjs.json",
42
+ "build": "node ./build/act.js removeCmp && npm run build.cjs && npm run build.mjs && node ./build/act.js finalizeExportVariants",
44
43
  "git.pub": "npm run test && git add --all && git commit -m \"automated\" && git push",
45
44
  "npm.login": "npm login",
46
45
  "npm.pub": "npm run test && npm run build && npm publish --access public"
47
46
  }
48
- }
47
+ }
package/readme.md CHANGED
@@ -32,6 +32,92 @@ Symbol properties maintains compatibility with the vast majority of npm modules.
32
32
  more thing - the symbols used to extend functionality are set in the global scope, so they are
33
33
  always globally available.
34
34
 
35
+ ## Exported helpers
36
+
37
+ In addition to prototype extensions, this module exports several utility helpers for direct import:
38
+
39
+ ```ts
40
+ import { isCls, inCls, getClsName, getCls, skip, then, safe } from '@gershy/clearing';
41
+ ```
42
+
43
+ ### `isCls(value, Constructor)`
44
+ Type guard for strict class/constructor matching. Handles primitives, null, undefined, and NaN correctly.
45
+
46
+ ```ts
47
+ isCls(5, Number); // true
48
+ isCls(5, NaN); // false
49
+ isCls(5, String); // false
50
+ isCls('abc', String); // true
51
+ isCls(null, null); // true
52
+ isCls(undefined, undefined); // true
53
+ isCls(null, undefined); // false
54
+ isCls(undefined, null); // false
55
+ isCls(NaN, NaN); // true
56
+ isCls({}, Object); // true
57
+ isCls([], Array); // true
58
+ isCls(new Map(), Map); // true
59
+ ```
60
+
61
+ ### `inCls(value, Constructor)`
62
+ Type guard for `instanceof` checks (including inheritance).
63
+
64
+ ```ts
65
+ inCls([], Array); // true
66
+ inCls(new (class X extends Array {})(), Array); // true
67
+ inCls({}, Object); // true
68
+ inCls(5, Number); // false (primitives are not instanceof)
69
+ ```
70
+
71
+ ### `getClsName(value)`
72
+ Returns the class/constructor name of a value, or special names for null/undefined/NaN.
73
+
74
+ ```ts
75
+ getClsName(5); // 'Number'
76
+ getClsName('abc'); // 'String'
77
+ getClsName(null); // 'Null'
78
+ getClsName(undefined); // 'Undef'
79
+ getClsName(NaN); // 'Nan'
80
+ getClsName({}); // 'Object'
81
+ getClsName(Object.create(null)); // 'Prototypeless'
82
+ ```
83
+
84
+ ### `getCls(value)`
85
+ Returns the constructor function of a value, or null if not available.
86
+
87
+ ```ts
88
+ getCls(5); // Number
89
+ getCls('abc'); // String
90
+ getCls(null); // null
91
+ getCls(undefined); // null
92
+ getCls({}); // Object
93
+ getCls(Object.create(null)); // null
94
+ ```
95
+
96
+ ### `skip`
97
+ Special exported value (undefined) used to signal omission in mapping helpers.
98
+
99
+ ```ts
100
+ import { skip } from '@gershy/clearing';
101
+ [1, 2, 3].map(v => v > 1 ? v : skip); // [skip, 2, 3]
102
+ ```
103
+
104
+ ### `then(value, onFulfilled?, onRejected?)`
105
+ Unified handler for both Promise and non-Promise values. Applies `onFulfilled`/`onRejected` as appropriate.
106
+
107
+ ```ts
108
+ then(Promise.resolve(5), v => v * 2); // Promise resolving to 10
109
+ then(5, v => v * 2); // 10
110
+ then(Promise.reject('fail'), undefined, e => 'fallback'); // Promise resolving to 'fallback'
111
+ ```
112
+
113
+ ### `safe(fn, onRejected?)`
114
+ Runs a function (sync or async), catching errors and returning a Promise. Optionally handles errors with `onRejected`.
115
+
116
+ ```ts
117
+ await safe(() => JSON.parse('{ bad }'), e => 'fallback'); // 'fallback'
118
+ await safe(async () => await fetch('bad-url'), e => null); // null if fetch throws
119
+ ```
120
+
35
121
  ## `Object` extensions
36
122
 
37
123
  There are currently no extensions on the `Object` class.