@owlmeans/error 0.1.18-rc.38 → 0.1.18-rc.39

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/README.md CHANGED
@@ -12,7 +12,7 @@ framework packages already ship: authentication and authorization failures from
12
12
  ## Installation
13
13
 
14
14
  ```bash
15
- bun add @owlmeans/error@^0.1.18-rc.38
15
+ bun add @owlmeans/error@^0.1.18-rc.39
16
16
  ```
17
17
 
18
18
  ## Concepts
@@ -272,7 +272,7 @@ This package ships embedded agent skills under `agent-meta/`. After installing y
272
272
  your project's skill store (`.agents/skills/`):
273
273
 
274
274
  ```sh
275
- npx @owlmeans/agent-skills@^0.1.18-rc.49
275
+ npx @owlmeans/agent-skills@^0.1.18-rc.57
276
276
  ```
277
277
 
278
278
  The embedded files are version-matched to this package release. Do not edit them
@@ -1,8 +1,8 @@
1
1
  {
2
- "schemaVersion": 2,
2
+ "schemaVersion": 3,
3
3
  "package": "@owlmeans/error",
4
- "version": "0.1.18-rc.38",
5
- "generatedAt": "2026-10-05T21:03:06.410Z",
4
+ "version": "0.1.18-rc.39",
5
+ "generatedAt": "2026-10-20T23:19:58.641Z",
6
6
  "canonicalRepo": "https://github.com/owlmeans/common",
7
7
  "entries": [
8
8
  {
@@ -8,7 +8,7 @@ user-invocable: false
8
8
  # @owlmeans/error
9
9
 
10
10
  **Layer:** Core
11
- **Install:** `"@owlmeans/error": "^0.1.18-rc.38"` in `dependencies`
11
+ **Install:** `"@owlmeans/error": "^0.1.18-rc.39"` in `dependencies`
12
12
 
13
13
  ## Key Exports
14
14
 
@@ -0,0 +1,33 @@
1
+ import type { Converter, MarshalErrorOptions, ResilientErrorConstructor } from './types.js';
2
+ /**
3
+ * Whether a value is a `ResilientError` built by ANY copy of this module.
4
+ *
5
+ * Structural: the shared brand plus the `type` and `marshal` every instance carries.
6
+ */
7
+ export declare const isResilientError: (value: unknown) => value is ResilientError;
8
+ export declare class ResilientError extends Error {
9
+ static separator: string;
10
+ static typeName: string;
11
+ static converters: Converter[];
12
+ /**
13
+ * `instanceof` that holds across module copies.
14
+ *
15
+ * The native prototype check answers first. Failing that, a branded instance matches when its
16
+ * class lineage ENDS WITH this class's lineage — the same own type names, in the same order, up
17
+ * to the base. So `instanceof AuthFailedError` accepts an `AuthFailedError` (or a subclass of it)
18
+ * from another copy, and never a sibling class or a parent. A class that does not declare its
19
+ * own `typeName` cannot be told apart structurally and answers natively only.
20
+ */
21
+ static [Symbol.hasInstance]<T extends abstract new (...args: any[]) => any>(this: T, instance: unknown): instance is InstanceType<T>;
22
+ static registerErrorClass(resilientErrorClass: ResilientErrorConstructor, errorClass?: ErrorConstructor): Converter;
23
+ static ensure(err: Error | string, throwOnUnknown?: boolean): ResilientError;
24
+ static marshal(err: Error, opts?: MarshalErrorOptions): Error;
25
+ type: string;
26
+ oiriginalStack?: string;
27
+ /** Correlates a serialized boundary error with the server log entry that owns its full stack. */
28
+ incidentId?: string;
29
+ constructor(type: string, message: string, stack?: string);
30
+ marshal(opts?: MarshalErrorOptions): Error;
31
+ finalizeUnmarshal(): void;
32
+ }
33
+ //# sourceMappingURL=resilient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilient.d.ts","sourceRoot":"","sources":["../src/resilient.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,mBAAmB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAA;AAyC3F;;;;GAIG;AACH,eAAO,MAAM,gBAAgB,UAAW,OAAO,KAAG,KAAK,IAAI,cAS1D,CAAA;AAED,qBAAa,cAAe,SAAQ,KAAK;IACvC,OAAc,SAAS,EAAE,MAAM,CAAY;IAE3C,OAAc,QAAQ,EAAE,MAAM,CAAiB;IAE/C,OAAc,UAAU,EAAE,SAAS,EAAE,CAAqB;IAE1D;;;;;;;;OAQG;IACH,OAAuB,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,GAAG,EACxF,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,GACzB,QAAQ,IAAI,YAAY,CAAC,CAAC,CAAC,CAY7B;IAED,OAAc,kBAAkB,CAAC,mBAAmB,EAAE,yBAAyB,EAAE,UAAU,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAKzH;IAED,OAAc,MAAM,CAAC,GAAG,EAAE,KAAK,GAAG,MAAM,EAAE,cAAc,CAAC,EAAE,OAAO,GAAG,cAAc,CA4BlF;IAED,OAAc,OAAO,CAAC,GAAG,EAAE,KAAK,EAAE,IAAI,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAenE;IAEM,IAAI,EAAE,MAAM,CAAiB;IAE7B,cAAc,CAAC,EAAE,MAAM,CAAA;IAE9B,iGAAiG;IAC1F,UAAU,CAAC,EAAE,MAAM,CAAA;IAE1B,YAAY,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,EAQxD;IAED,OAAO,CAAC,IAAI,CAAC,EAAE,mBAAmB,GAAG,KAAK,CAEzC;IAED,iBAAiB,IAAI,IAAI,CAAI;CAC9B"}
@@ -0,0 +1,146 @@
1
+ import { CATCH_ALL_CONVERTER, CONVERTER_REGISTRY, RESILENT_ERROR, RESILIENT_BRAND, SEPARATOR } from './consts.js';
2
+ import { createErrorConverter } from './utils.js';
3
+ /**
4
+ * The one converter registry of the process.
5
+ *
6
+ * Kept on `globalThis` so every copy of this module registers into, and unmarshals from, the same
7
+ * list: a class registered by one copy is rebuilt by another. Registration order is kept across
8
+ * copies, so the last registration of a type name still wins.
9
+ */
10
+ const sharedConverters = () => {
11
+ const holder = globalThis;
12
+ holder[CONVERTER_REGISTRY] ??= [];
13
+ return holder[CONVERTER_REGISTRY];
14
+ };
15
+ /**
16
+ * The type names a class declares itself and inherits, nearest first — only names a class owns.
17
+ *
18
+ * A class that does not redeclare `typeName` inherits its parent's value, and counting that twice
19
+ * would let a check against the subclass match any instance of the parent.
20
+ */
21
+ const lineageOf = (ctor) => {
22
+ const names = [];
23
+ let current = ctor;
24
+ while (typeof current === 'function') {
25
+ if (Object.prototype.hasOwnProperty.call(current, 'typeName')) {
26
+ const name = current.typeName;
27
+ if (typeof name === 'string') {
28
+ names.push(name);
29
+ }
30
+ }
31
+ current = Object.getPrototypeOf(current);
32
+ }
33
+ return names;
34
+ };
35
+ /**
36
+ * Whether a value is a `ResilientError` built by ANY copy of this module.
37
+ *
38
+ * Structural: the shared brand plus the `type` and `marshal` every instance carries.
39
+ */
40
+ export const isResilientError = (value) => {
41
+ if (value == null || typeof value !== 'object') {
42
+ return false;
43
+ }
44
+ const candidate = value;
45
+ return candidate[RESILIENT_BRAND] === true
46
+ && typeof candidate.type === 'string'
47
+ && typeof candidate.marshal === 'function';
48
+ };
49
+ export class ResilientError extends Error {
50
+ static separator = SEPARATOR;
51
+ static typeName = RESILENT_ERROR;
52
+ static converters = sharedConverters();
53
+ /**
54
+ * `instanceof` that holds across module copies.
55
+ *
56
+ * The native prototype check answers first. Failing that, a branded instance matches when its
57
+ * class lineage ENDS WITH this class's lineage — the same own type names, in the same order, up
58
+ * to the base. So `instanceof AuthFailedError` accepts an `AuthFailedError` (or a subclass of it)
59
+ * from another copy, and never a sibling class or a parent. A class that does not declare its
60
+ * own `typeName` cannot be told apart structurally and answers natively only.
61
+ */
62
+ static [Symbol.hasInstance](instance) {
63
+ if (Function.prototype[Symbol.hasInstance].call(this, instance)) {
64
+ return true;
65
+ }
66
+ if (!isResilientError(instance) || !Object.prototype.hasOwnProperty.call(this, 'typeName')) {
67
+ return false;
68
+ }
69
+ const expected = lineageOf(this);
70
+ const actual = lineageOf(Object.getPrototypeOf(instance)?.constructor);
71
+ const offset = actual.length - expected.length;
72
+ return offset >= 0 && expected.every((name, index) => actual[offset + index] === name);
73
+ }
74
+ static registerErrorClass(resilientErrorClass, errorClass) {
75
+ const converter = createErrorConverter(resilientErrorClass, errorClass);
76
+ this.converters.push(converter);
77
+ return converter;
78
+ }
79
+ static ensure(err, throwOnUnknown) {
80
+ err = typeof err === 'string' ? new Error(err) : err;
81
+ if (isResilientError(err)) {
82
+ return err;
83
+ }
84
+ // We don't proceed SyntaxError - system should crash in this case
85
+ if (err instanceof SyntaxError) {
86
+ throw err;
87
+ }
88
+ // Umarshal marhalled error that is wrapepd to ordinary error
89
+ const unmarhaller = this.converters.toReversed().find(converter => converter.isMarshaled(err));
90
+ if (unmarhaller != null) {
91
+ return unmarhaller.unmarshal(err);
92
+ }
93
+ // Convert object of Error subtypes to ResilientError subtype
94
+ const converter = this.converters.find(converter => converter.match(err));
95
+ if (converter != null) {
96
+ return converter.convert(err);
97
+ }
98
+ if (throwOnUnknown === true) {
99
+ throw err;
100
+ }
101
+ return new ResilientError(this.typeName, err.message, err.stack);
102
+ }
103
+ static marshal(err, opts) {
104
+ const resilient = isResilientError(err);
105
+ const structuralType = err.type;
106
+ const type = resilient
107
+ ? err.type
108
+ : typeof structuralType === 'string' ? structuralType : this.typeName;
109
+ const stack = opts?.includeStack === false
110
+ ? ''
111
+ : resilient ? err.oiriginalStack : err.stack;
112
+ const fields = [type, err.message, stack];
113
+ if (opts?.incidentId != null) {
114
+ fields.push(opts.incidentId);
115
+ }
116
+ return new Error(fields.join(this.separator));
117
+ }
118
+ type = RESILENT_ERROR;
119
+ oiriginalStack;
120
+ /** Correlates a serialized boundary error with the server log entry that owns its full stack. */
121
+ incidentId;
122
+ constructor(type, message, stack) {
123
+ super(message);
124
+ this.type = type;
125
+ if (stack != null) {
126
+ this.oiriginalStack = stack;
127
+ }
128
+ else {
129
+ this.oiriginalStack = this.stack;
130
+ }
131
+ }
132
+ marshal(opts) {
133
+ return ResilientError.marshal(this, opts);
134
+ }
135
+ finalizeUnmarshal() { }
136
+ }
137
+ // On the prototype, not the instance: non-enumerable, and inherited by every subclass of this copy.
138
+ Object.defineProperty(ResilientError.prototype, RESILIENT_BRAND, { value: true });
139
+ // One catch-all per process: a second module copy finds the first copy's entry and adds none.
140
+ if (!ResilientError.converters.some(converter => converter[CATCH_ALL_CONVERTER] === true)) {
141
+ ResilientError.converters.push(Object.assign({
142
+ ...createErrorConverter(ResilientError),
143
+ match: () => true,
144
+ }, { [CATCH_ALL_CONVERTER]: true }));
145
+ }
146
+ //# sourceMappingURL=resilient.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resilient.js","sourceRoot":"","sources":["../src/resilient.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@owlmeans/error",
3
- "version": "0.1.18-rc.38",
3
+ "version": "0.1.18-rc.39",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "scripts": {
@@ -22,7 +22,7 @@
22
22
  }
23
23
  },
24
24
  "dependencies": {
25
- "@owlmeans/i18n": "^0.1.18-rc.39"
25
+ "@owlmeans/i18n": "^0.1.18-rc.40"
26
26
  },
27
27
  "devDependencies": {
28
28
  "@owlmeans/dep-config": "workspace:*",