@vicin/sigil 2.2.1 → 3.1.0

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.mjs CHANGED
@@ -1,9 +1,6 @@
1
- import { createId } from '@paralleldrive/cuid2';
2
-
3
- // src/core/options.ts
1
+ // src/options.ts
4
2
  var OPTIONS = {
5
3
  labelValidation: null,
6
- skipLabelInheritanceCheck: false,
7
4
  autofillLabels: true
8
5
  };
9
6
  var updateSigilOptions = (opts) => {
@@ -12,11 +9,6 @@ var updateSigilOptions = (opts) => {
12
9
  throw new Error("'updateSigilOptions.autofillLabels' must be boolean");
13
10
  OPTIONS.autofillLabels = opts.autofillLabels;
14
11
  }
15
- if ("skipLabelInheritanceCheck" in opts) {
16
- if (typeof opts.skipLabelInheritanceCheck !== "boolean")
17
- throw new Error("'updateSigilOptions.skipLabelInheritanceCheck' must be boolean");
18
- OPTIONS.skipLabelInheritanceCheck = opts.skipLabelInheritanceCheck;
19
- }
20
12
  if ("labelValidation" in opts) {
21
13
  const val = opts.labelValidation;
22
14
  if (val !== null && typeof val !== "function" && !(val instanceof RegExp))
@@ -26,218 +18,191 @@ var updateSigilOptions = (opts) => {
26
18
  };
27
19
  var DEFAULT_LABEL_REGEX = /^@[\w-]+(?:\/[\w-]+)*\.[A-Z][A-Za-z0-9]*$/;
28
20
 
29
- // src/core/symbols.ts
30
- var __SIGIL__ = /* @__PURE__ */ Symbol.for("@Sigil.__SIGIL__");
31
- var __SIGIL_BASE__ = /* @__PURE__ */ Symbol.for("@Sigil.__SIGIL_BASE__");
32
- var __DECORATED__ = /* @__PURE__ */ Symbol.for("@Sigil.__DECORATED__");
33
- var __INHERITANCE_CHECKED__ = /* @__PURE__ */ Symbol.for("@Sigil.__INHERITANCE_CHECKED__");
34
- var __LABEL__ = /* @__PURE__ */ Symbol.for("@Sigil.__LABEL__");
35
- var __EFFECTIVE_LABEL__ = /* @__PURE__ */ Symbol.for("@Sigil.__EFFECTIVE_LABEL__");
36
- var __LABEL_LINEAGE__ = /* @__PURE__ */ Symbol.for("@Sigil.__LABEL_LINEAGE__");
37
- var __LABEL_SET__ = /* @__PURE__ */ Symbol.for("@Sigil.__LABEL_SET__");
38
- function decorateCtor(ctor, label, runtime) {
39
- if (process.env.NODE_ENV !== "production") {
40
- if (isDecorated(ctor))
41
- throw new Error(
42
- `Constructor ${ctor} is already decorated. if you are using 'withSigilTyped()' & '@WithSigil()' at the same time remove one of them.`
43
- );
44
- }
45
- Object.defineProperty(ctor, __LABEL__, {
46
- value: label,
47
- configurable: true,
48
- enumerable: false,
49
- writable: false
50
- });
51
- if (!(runtime == null ? void 0 : runtime.isInheritanceCheck))
52
- Object.defineProperty(ctor, __EFFECTIVE_LABEL__, {
53
- value: label,
54
- configurable: true,
55
- enumerable: false,
56
- writable: false
57
- });
58
- const parent = Object.getPrototypeOf(ctor);
59
- const parentChain = parent && parent[__LABEL_LINEAGE__] ? parent[__LABEL_LINEAGE__] : [];
60
- const ctorChain = (runtime == null ? void 0 : runtime.isMixin) && label !== "Sigil" ? ["Sigil", ...parentChain, label] : [...parentChain, label];
61
- Object.defineProperty(ctor, __LABEL_LINEAGE__, {
62
- value: ctorChain,
63
- configurable: true,
64
- enumerable: false,
65
- writable: false
66
- });
67
- Object.defineProperty(ctor, __LABEL_SET__, {
68
- value: new Set(ctorChain),
69
- configurable: true,
70
- enumerable: false,
71
- writable: false
72
- });
73
- if (!(runtime == null ? void 0 : runtime.isInheritanceCheck)) markDecorated(ctor);
21
+ // src/symbols.ts
22
+ var __SIGIL__ = /* @__PURE__ */ Symbol.for("@vicin/sigil.__SIGIL__");
23
+ var __LABEL__ = /* @__PURE__ */ Symbol.for("@vicin/sigil.__LABEL__");
24
+ var __EFFECTIVE_LABEL__ = /* @__PURE__ */ Symbol.for("@vicin/sigil.__EFFECTIVE_LABEL__");
25
+ var __LINEAGE__ = /* @__PURE__ */ Symbol.for("@vicin/sigil.__LINEAGE__");
26
+
27
+ // src/helpers.ts
28
+ var AUTO_LABEL_PREFEX = "@Sigil-auto";
29
+ var handledCtors = /* @__PURE__ */ new WeakSet();
30
+ function handleSigil(ctor, label, opts) {
31
+ if (handledCtors.has(ctor)) return;
32
+ handledCtors.add(ctor);
33
+ verifyLabel(ctor, label, opts);
34
+ const ancLabelsMap = handleAncestors(ctor, opts);
35
+ if (label && ancLabelsMap.has(label))
36
+ throw new Error(
37
+ `[Sigil Error] Attempt to assign label '${label}' to ${ctor.name} but label is already used by parent '${ancLabelsMap.get(label)}', Make sure that every class has a unique label`
38
+ );
39
+ sigilify(ctor, label != null ? label : generateRandomLabel(ctor));
74
40
  }
75
- function checkInheritance(ctor, opts) {
76
- var _a, _b;
77
- if (isInheritanceChecked(ctor) || ((_a = opts == null ? void 0 : opts.skipLabelInheritanceCheck) != null ? _a : OPTIONS.skipLabelInheritanceCheck))
78
- return;
79
- const ctors = [ctor];
80
- let ancestor = Object.getPrototypeOf(ctor);
81
- while (isSigilCtor(ancestor)) {
82
- ctors.push(ancestor);
83
- ancestor = Object.getPrototypeOf(ancestor);
41
+ function handleAncestors(ctor, opts) {
42
+ var _a;
43
+ const autofillLabels = (_a = opts == null ? void 0 : opts.autofillLabels) != null ? _a : OPTIONS.autofillLabels;
44
+ const ancestors = [];
45
+ let a = Object.getPrototypeOf(ctor);
46
+ while (a && typeof a === "function" && a.prototype[__SIGIL__]) {
47
+ ancestors.unshift(a);
48
+ a = Object.getPrototypeOf(a);
84
49
  }
85
50
  const labelOwner = /* @__PURE__ */ new Map();
86
- for (let i = ctors.length - 1; i >= 0; i--) {
87
- const ctor2 = ctors[i];
88
- if (!ctor2) continue;
89
- let label = ctor2[__LABEL__];
90
- if (labelOwner.has(label)) {
91
- if (process.env.NODE_ENV !== "production") {
92
- if (isDecorated(ctor2) || !((_b = opts == null ? void 0 : opts.autofillLabels) != null ? _b : OPTIONS.autofillLabels))
93
- throw new Error(
94
- `[Sigil Error] Class "${ctor2.name}" re-uses Sigil label "${label}" from ancestor "${labelOwner.get(label)}". Each Sigil subclass must use a unique label. Did you forget to use "WithSigil(newLabel)" on the subclass?`
95
- );
96
- }
97
- label = generateRandomLabel();
98
- decorateCtor(ctor2, label, { isInheritanceCheck: true });
99
- }
100
- labelOwner.set(label, ctor2.name);
101
- }
102
- markInheritanceChecked(ctor);
103
- }
104
- function verifyLabel(label, opts) {
105
- var _a;
106
- const labelValidation = (_a = opts == null ? void 0 : opts.labelValidation) != null ? _a : OPTIONS.labelValidation;
107
- if (labelValidation) {
108
- let valid;
109
- if (labelValidation instanceof RegExp) valid = labelValidation.test(label);
110
- else valid = labelValidation(label);
111
- if (process.env.NODE_ENV !== "production") {
112
- if (!valid)
51
+ for (const a2 of ancestors) {
52
+ const l = a2.prototype[__LABEL__];
53
+ if (labelOwner.has(l)) {
54
+ if (!autofillLabels)
113
55
  throw new Error(
114
- `[Sigil] Invalid identity label "${label}". Make sure that supplied label matches validation regex or function.`
56
+ `[Sigil Error] Class '${a2.name}' is not sigilified with 'autofillLabels' setted to 'false', Make sure to sigilify all Sigil classes or set 'autofillLabels' to 'true'`
115
57
  );
58
+ sigilify(a2, generateRandomLabel(a2));
116
59
  }
60
+ labelOwner.set(labelOf(a2), a2.name);
117
61
  }
62
+ return labelOwner;
118
63
  }
119
- function generateRandomLabel() {
120
- let label = createId();
121
- return `@Sigil.auto-${label}`;
122
- }
123
- function markSigil(ctor) {
124
- Object.defineProperty(ctor, __SIGIL__, {
125
- value: true,
64
+ function sigilify(ctor, label) {
65
+ var _a;
66
+ const sym = Symbol.for(label);
67
+ Object.defineProperty(ctor.prototype, __SIGIL__, {
68
+ value: sym,
126
69
  configurable: false,
127
70
  enumerable: false,
128
71
  writable: false
129
72
  });
130
- }
131
- function markSigilBase(ctor) {
132
- Object.defineProperty(ctor, __SIGIL_BASE__, {
73
+ Object.defineProperty(ctor.prototype, sym, {
133
74
  value: true,
134
75
  configurable: false,
135
76
  enumerable: false,
136
77
  writable: false
137
78
  });
138
- }
139
- function markDecorated(ctor) {
140
- Object.defineProperty(ctor, __DECORATED__, {
141
- value: true,
79
+ Object.defineProperty(ctor.prototype, __LABEL__, {
80
+ value: label,
142
81
  configurable: false,
143
82
  enumerable: false,
144
83
  writable: false
145
84
  });
146
- }
147
- function markInheritanceChecked(ctor) {
148
- Object.defineProperty(ctor, __INHERITANCE_CHECKED__, {
149
- value: true,
85
+ if (!label.startsWith(AUTO_LABEL_PREFEX))
86
+ Object.defineProperty(ctor.prototype, __EFFECTIVE_LABEL__, {
87
+ value: label,
88
+ configurable: false,
89
+ enumerable: false,
90
+ writable: false
91
+ });
92
+ Object.defineProperty(ctor.prototype, __LINEAGE__, {
93
+ value: /* @__PURE__ */ new Set(["Sigil", ...(_a = lineageOf(ctor)) != null ? _a : [], label]),
150
94
  configurable: false,
151
95
  enumerable: false,
152
96
  writable: false
153
97
  });
98
+ const sigilSym = /* @__PURE__ */ Symbol.for("Sigil");
99
+ if (ctor.prototype[sigilSym] !== true)
100
+ Object.defineProperty(ctor.prototype, sigilSym, {
101
+ value: true,
102
+ configurable: false,
103
+ enumerable: false,
104
+ writable: false
105
+ });
154
106
  }
155
107
  function isSigilCtor(ctor) {
156
- return typeof ctor === "function" && ctor[__SIGIL__] === true;
108
+ return typeof ctor === "function" && __SIGIL__ in ctor.prototype;
157
109
  }
158
110
  function isSigilInstance(inst) {
159
- if (!inst || typeof inst !== "object") return false;
160
- const ctor = getConstructor(inst);
161
- return isSigilCtor(ctor);
111
+ return !!inst && typeof inst === "object" && __SIGIL__ in inst;
162
112
  }
163
- function isSigilBaseCtor(ctor) {
164
- return Object.hasOwn(ctor, __SIGIL_BASE__);
113
+ function hasOwnSigil(ctor) {
114
+ return typeof ctor === "function" && Object.hasOwn(ctor.prototype, __SIGIL__);
165
115
  }
166
- function isSigilBaseInstance(inst) {
167
- if (!inst || typeof inst !== "object") return false;
168
- const ctor = getConstructor(inst);
169
- return isSigilBaseCtor(ctor);
116
+ function labelOf(ctor) {
117
+ return ctor.prototype[__LABEL__];
170
118
  }
171
- function isDecorated(ctor) {
172
- return Object.hasOwn(ctor, __DECORATED__);
119
+ function lineageOf(ctor) {
120
+ return ctor.prototype[__LINEAGE__];
173
121
  }
174
- function isInheritanceChecked(ctor) {
175
- return Object.hasOwn(ctor, __INHERITANCE_CHECKED__);
122
+ function verifyLabel(ctor, label, opts) {
123
+ var _a, _b;
124
+ const labelValidation = (_a = opts == null ? void 0 : opts.labelValidation) != null ? _a : OPTIONS.labelValidation;
125
+ const autofillLabels = (_b = opts == null ? void 0 : opts.autofillLabels) != null ? _b : OPTIONS.autofillLabels;
126
+ if (!label) {
127
+ if (!autofillLabels)
128
+ throw new Error(
129
+ `[Sigil Error] Class '${ctor.name}' is not sigilified with 'autofillLabels' setted to 'false', Make sure to sigilify all Sigil classes or set 'autofillLabels' to 'true'`
130
+ );
131
+ return;
132
+ }
133
+ if (label.startsWith(AUTO_LABEL_PREFEX))
134
+ throw new Error(`'${AUTO_LABEL_PREFEX}' is a prefex reserved by the library`);
135
+ if (labelValidation) {
136
+ let valid;
137
+ if (labelValidation instanceof RegExp) valid = labelValidation.test(label);
138
+ else valid = labelValidation(label);
139
+ if (process.env.NODE_ENV !== "production") {
140
+ if (!valid)
141
+ throw new Error(
142
+ `[Sigil Error] Invalid identity label "${label}". Make sure that supplied label matches validation regex or function`
143
+ );
144
+ }
145
+ }
176
146
  }
177
- function getConstructor(obj) {
178
- var _a, _b, _c;
179
- if (!obj || typeof obj !== "object") return null;
180
- return (_c = (_b = obj.constructor) != null ? _b : (_a = Object.getPrototypeOf(obj)) == null ? void 0 : _a.constructor) != null ? _c : null;
147
+ if (!globalThis.__SigilabelCounter) globalThis.__SigilabelCounter = 0;
148
+ function generateRandomLabel(ctor) {
149
+ const namePart = ctor && typeof ctor.name === "string" && ctor.name.length ? ctor.name : "C";
150
+ const counter = globalThis.__SigilabelCounter++;
151
+ const time = Date.now().toString(36);
152
+ const rand = Math.random().toString(36).slice(2, 6);
153
+ return `${AUTO_LABEL_PREFEX}:${namePart}:${time}:${counter.toString(36)}:${rand}`;
181
154
  }
182
155
 
183
- // src/core/mixin.ts
156
+ // src/mixin.ts
184
157
  function Sigilify(Base, label, opts) {
185
- if (isSigilCtor(Base)) throw new Error(`[Sigil Error] 'Sigilify(${label})' already sigilified.`);
186
- let l;
187
- if (label) {
188
- verifyLabel(label, opts);
189
- l = label;
190
- } else l = generateRandomLabel();
158
+ if (hasOwnSigil(Base))
159
+ throw new Error(
160
+ `[Sigil Error] Class '${Base.name}' with label '${Base.SigilLabel}' is already sigilified`
161
+ );
191
162
  class Sigilified extends Base {
192
163
  /**
193
164
  * Class-level identity label constant for this sigil constructor.
194
165
  */
195
166
  static get SigilLabel() {
196
- if (!isInheritanceChecked(this)) checkInheritance(this);
197
- return this[__LABEL__];
167
+ var _a;
168
+ handleSigil(this);
169
+ return (_a = this.prototype) == null ? void 0 : _a[__LABEL__];
198
170
  }
199
171
  /**
200
172
  * Class-level human-readable label constant for this sigil constructor, last passed label in 'Sigil' chain by developer.
201
173
  */
202
174
  static get SigilEffectiveLabel() {
203
- return this[__EFFECTIVE_LABEL__];
175
+ var _a;
176
+ handleSigil(this);
177
+ return (_a = this.prototype) == null ? void 0 : _a[__EFFECTIVE_LABEL__];
204
178
  }
205
179
  /**
206
- * Copy of the linearized sigil type label chain for the current constructor.
180
+ * Linearized sigil type label chain for the current constructor.
207
181
  *
208
182
  * Useful for debugging and performing strict lineage comparisons.
209
183
  *
210
184
  * @returns An array of labels representing parent → child type labels.
211
185
  */
212
186
  static get SigilLabelLineage() {
213
- var _a;
214
- if (!isInheritanceChecked(this)) checkInheritance(this);
215
- return [...(_a = this[__LABEL_LINEAGE__]) != null ? _a : []];
187
+ var _a, _b;
188
+ handleSigil(this);
189
+ return [...(_b = (_a = this.prototype) == null ? void 0 : _a[__LINEAGE__]) != null ? _b : []];
216
190
  }
217
191
  /**
218
- * Copy of the sigil type label set for the current constructor.
219
- *
220
- * Useful for quick membership checks (O(1) lookups) and debugging.
192
+ * Sigil type label set for the current constructor.
193
+ * Useful for debugging.
221
194
  *
222
195
  * @returns A Readonly Set of labels that represent the type lineage.
223
196
  */
224
197
  static get SigilLabelSet() {
225
- if (!isInheritanceChecked(this)) checkInheritance(this);
226
- const set = /* @__PURE__ */ new Set();
227
- for (const s of this[__LABEL_SET__]) set.add(s);
228
- return set;
198
+ var _a;
199
+ handleSigil(this);
200
+ return (_a = this.prototype) == null ? void 0 : _a[__LINEAGE__];
229
201
  }
230
202
  constructor(...args) {
231
203
  super(...args);
232
- if (Object.getPrototypeOf(this) !== new.target.prototype)
233
- Object.setPrototypeOf(this, new.target.prototype);
234
- const ctor = getConstructor(this);
235
- if (!ctor) {
236
- if (process.env.NODE_ENV !== "production")
237
- throw new Error(`[Sigil Error] 'Sigilify(${label})' instance without constructor`);
238
- return;
239
- }
240
- checkInheritance(ctor);
204
+ const ctor = new.target;
205
+ handleSigil(ctor);
241
206
  }
242
207
  /**
243
208
  * Runtime predicate indicating whether `obj` is an instance produced by a sigil class.
@@ -249,99 +214,86 @@ function Sigilify(Base, label, opts) {
249
214
  return isSigilInstance(obj);
250
215
  }
251
216
  /**
252
- * Check whether `other` is (or inherits from) the type represented by the calling constructor.
217
+ * Check whether `other` is (or inherits from) the instance represented by the
218
+ * calling constructor.
253
219
  *
254
220
  * This replaces `instanceof` so that checks remain valid across bundles/realms
255
221
  * and when subclassing.
256
222
  *
257
- * @typeParam T - The calling constructor type (narrowing the returned instance type).
258
- * @param this - The constructor performing the check.
223
+ * @typeParam T - The specific sigil constructor (`this`).
224
+ * @param this - The constructor performing the type check.
259
225
  * @param other - The object to test.
260
- * @returns `true` if `other` is an instance of this type or a subtype.
226
+ * @returns A type guard asserting `other` is an instance of the constructor.
261
227
  */
262
228
  static isOfType(other) {
263
229
  var _a;
264
- if (!isSigilInstance(other)) return false;
265
- const otherSet = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_SET__];
266
- const thisType = this[__LABEL__];
267
- return !!otherSet && otherSet.has(thisType);
230
+ handleSigil(this);
231
+ if (other == null || typeof other !== "object") return false;
232
+ return other[(_a = this.prototype) == null ? void 0 : _a[__SIGIL__]] === true;
268
233
  }
269
234
  /**
270
- * Strict lineage check: compares the type label lineage arrays element-by-element.
235
+ * Check whether `other` is exactly the same instance represented by the
236
+ * calling constructor.
271
237
  *
272
- * @typeParam T - The calling constructor type.
273
- * @param this - The constructor performing the check.
238
+ * @typeParam T - The specific sigil constructor (`this`).
239
+ * @param this - The constructor performing the type check.
274
240
  * @param other - The object to test.
275
- * @returns `true` if `other` has an identical lineage up to the length of this constructor's lineage.
241
+ * @returns A type guard asserting `other` is an instance of the constructor.
276
242
  */
277
- static isOfTypeStrict(other) {
278
- var _a;
279
- if (!isSigilInstance(other)) return false;
280
- const otherLineage = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_LINEAGE__];
281
- const thisLineage = this[__LABEL_LINEAGE__];
282
- return !!otherLineage && thisLineage.every((s, i) => s === otherLineage[i]);
243
+ static isExactType(other) {
244
+ var _a, _b, _c;
245
+ handleSigil(this);
246
+ if (other == null || typeof other !== "object") return false;
247
+ if (((_a = this.prototype) == null ? void 0 : _a[__LINEAGE__].size) !== ((_b = other[__LINEAGE__]) == null ? void 0 : _b.size))
248
+ return false;
249
+ return other[(_c = this.prototype) == null ? void 0 : _c[__SIGIL__]] === true;
283
250
  }
284
251
  /**
285
- * Check whether `other` is (or inherits from) the type instance.
252
+ * Check whether `other` is (or inherits from) the instance represented by the
253
+ * calling constructor.
286
254
  *
287
- * Allows 'instanceof' like checks but in instances.
255
+ * This replaces `instanceof` so that checks remain valid across bundles/realms
256
+ * and when subclassing.
288
257
  *
289
- * @typeParam T - The instance type.
290
- * @param this - The instance performing the check.
258
+ * @typeParam T - The specific sigil constructor (`this`).
259
+ * @param this - The constructor performing the type check.
291
260
  * @param other - The object to test.
292
- * @returns `true` if `other` is the same instance of this type or a subtype.
261
+ * @returns A type guard asserting `other` is an instance of the constructor.
293
262
  */
294
263
  isOfType(other) {
295
- var _a;
296
- if (!isSigilInstance(other)) return false;
297
- const otherSet = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_SET__];
298
- const thisType = getConstructor(this)[__LABEL__];
299
- return !!otherSet && otherSet.has(thisType);
264
+ if (other == null || typeof other !== "object") return false;
265
+ return other[this[__SIGIL__]] === true;
300
266
  }
301
267
  /**
302
- * Strict lineage check: compares the type label lineage arrays element-by-element.
268
+ * Check whether `other` is exactly the same instance represented by the
269
+ * calling constructor.
303
270
  *
304
- * Allows 'instanceof' like checks but in instances.
305
- *
306
- * @typeParam T - The instance type.
307
- * @param this - The instance performing the check.
271
+ * @typeParam T - The specific sigil constructor (`this`).
272
+ * @param this - The constructor performing the type check.
308
273
  * @param other - The object to test.
309
- * @returns `true` if `other` has an identical lineage up to the length of this instance's lineage.
274
+ * @returns A type guard asserting `other` is an instance of the constructor.
310
275
  */
311
- isOfTypeStrict(other) {
312
- var _a, _b;
313
- if (!isSigilInstance(other)) return false;
314
- const otherLineage = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_LINEAGE__];
315
- const thisLineage = (_b = getConstructor(this)) == null ? void 0 : _b[__LABEL_LINEAGE__];
316
- return !!otherLineage && thisLineage.every((s, i) => s === otherLineage[i]);
276
+ isExactType(other) {
277
+ var _a;
278
+ if (other == null || typeof other !== "object") return false;
279
+ if (this[__LINEAGE__].size !== ((_a = other[__LINEAGE__]) == null ? void 0 : _a.size)) return false;
280
+ return other[this[__SIGIL__]] === true;
317
281
  }
318
282
  /**
319
283
  * Returns the identity sigil label of this instance's constructor.
320
284
  *
321
- * @returns The label string if passed (e.g. '@scope/pkg.ClassName'), random label if not passed (e.g. '@Sigil.auto-dq62ib6jnvmmlfbjhxh2937h') or '@Sigil.unknown' if constructor is missing.
285
+ * @returns The label string if passed (e.g. '@scope/pkg.ClassName'), random label if not passed (e.g. '@Sigil-auto:ClassName:mm2gkdwn:0:g1sq').
322
286
  */
323
287
  getSigilLabel() {
324
- const ctor = getConstructor(this);
325
- if (!ctor) {
326
- if (process.env.NODE_ENV !== "production")
327
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
328
- return "@Sigil.unknown";
329
- }
330
- return ctor.SigilLabel;
288
+ return this[__LABEL__];
331
289
  }
332
290
  /**
333
291
  * Returns the human-readable sigil label of this instance's constructor.
334
292
  *
335
- * @returns The last passed label string (e.g. '@scope/pkg.ClassName') or '@Sigil.unknown' if constructor is missing.
293
+ * @returns The last passed label string (e.g. '@scope/pkg.ClassName').
336
294
  */
337
295
  getSigilEffectiveLabel() {
338
- const ctor = getConstructor(this);
339
- if (!ctor) {
340
- if (process.env.NODE_ENV !== "production")
341
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
342
- return "@Sigil.unknown";
343
- }
344
- return ctor.SigilEffectiveLabel;
296
+ return this[__EFFECTIVE_LABEL__];
345
297
  }
346
298
  /**
347
299
  * Returns a copy of the sigil type label lineage for this instance's constructor.
@@ -349,91 +301,69 @@ function Sigilify(Base, label, opts) {
349
301
  * @returns readonly array of labels representing the type lineage.
350
302
  */
351
303
  getSigilLabelLineage() {
352
- const ctor = getConstructor(this);
353
- if (!ctor) {
354
- if (process.env.NODE_ENV !== "production")
355
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
356
- return ["@Sigil.unknown"];
357
- }
358
- return ctor.SigilLabelLineage;
304
+ return [...this[__LINEAGE__]];
359
305
  }
360
306
  /**
361
- * Returns a readonly copy of the sigil type label set for this instance's constructor.
307
+ * Returns a copy of the sigil type label lineage set for this instance's constructor.
362
308
  *
363
- * @returns A Readonly Set of labels representing the type lineage for O(1) membership tests.
309
+ * @returns readonly array of labels representing the type lineage.
364
310
  */
365
311
  getSigilLabelSet() {
366
- const ctor = getConstructor(this);
367
- if (!ctor) {
368
- if (process.env.NODE_ENV !== "production")
369
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
370
- return /* @__PURE__ */ new Set(["@Sigil.unknown"]);
371
- }
372
- return ctor.SigilLabelSet;
312
+ return this[__LINEAGE__];
373
313
  }
374
314
  }
375
- decorateCtor(Sigilified, l, { isMixin: true });
376
- markSigil(Sigilified);
377
- markSigilBase(Sigilified);
315
+ handleSigil(Sigilified, label, opts);
378
316
  return Sigilified;
379
317
  }
380
318
  function SigilifyAbstract(Base, label, opts) {
381
- if (isSigilCtor(Base)) throw new Error(`[Sigil Error] 'Sigilify(${label})' already sigilified.`);
382
- let l;
383
- if (label) {
384
- verifyLabel(label, opts);
385
- l = label;
386
- } else l = generateRandomLabel();
319
+ if (hasOwnSigil(Base))
320
+ throw new Error(
321
+ `[Sigil Error] Base class '${Base.name}' with label '${Base.SigilLabel}' is already sigilified`
322
+ );
387
323
  class Sigilified extends Base {
388
324
  /**
389
325
  * Class-level identity label constant for this sigil constructor.
390
326
  */
391
327
  static get SigilLabel() {
392
- if (!isInheritanceChecked(this)) checkInheritance(this);
393
- return this[__LABEL__];
328
+ var _a;
329
+ handleSigil(this);
330
+ return (_a = this.prototype) == null ? void 0 : _a[__LABEL__];
394
331
  }
395
332
  /**
396
333
  * Class-level human-readable label constant for this sigil constructor, last passed label in 'Sigil' chain by developer.
397
334
  */
398
335
  static get SigilEffectiveLabel() {
399
- return this[__EFFECTIVE_LABEL__];
336
+ var _a;
337
+ handleSigil(this);
338
+ return (_a = this.prototype) == null ? void 0 : _a[__EFFECTIVE_LABEL__];
400
339
  }
401
340
  /**
402
- * Copy of the linearized sigil type label chain for the current constructor.
341
+ * Linearized sigil type label chain for the current constructor.
403
342
  *
404
343
  * Useful for debugging and performing strict lineage comparisons.
405
344
  *
406
345
  * @returns An array of labels representing parent → child type labels.
407
346
  */
408
347
  static get SigilLabelLineage() {
409
- var _a;
410
- if (!isInheritanceChecked(this)) checkInheritance(this);
411
- return [...(_a = this[__LABEL_LINEAGE__]) != null ? _a : []];
348
+ var _a, _b;
349
+ handleSigil(this);
350
+ return [...(_b = (_a = this.prototype) == null ? void 0 : _a[__LINEAGE__]) != null ? _b : []];
412
351
  }
413
352
  /**
414
- * Copy of the sigil type label set for the current constructor.
415
- *
416
- * Useful for quick membership checks (O(1) lookups) and debugging.
353
+ * Sigil type label set for the current constructor.
354
+ * Useful for debugging.
417
355
  *
418
356
  * @returns A Readonly Set of labels that represent the type lineage.
419
357
  */
420
358
  static get SigilLabelSet() {
421
- if (!isInheritanceChecked(this)) checkInheritance(this);
422
- const set = /* @__PURE__ */ new Set();
423
- for (const s of this[__LABEL_SET__]) set.add(s);
424
- return set;
359
+ var _a;
360
+ handleSigil(this);
361
+ return (_a = this.prototype) == null ? void 0 : _a[__LINEAGE__];
425
362
  }
426
363
  constructor(...args) {
427
364
  super(...args);
428
- if (Object.getPrototypeOf(this) !== new.target.prototype)
429
- Object.setPrototypeOf(this, new.target.prototype);
430
- const ctor = getConstructor(this);
431
- if (!ctor) {
432
- if (process.env.NODE_ENV !== "production")
433
- throw new Error(`[Sigil Error] 'Sigilify(${label})' instance without constructor`);
434
- return;
435
- }
436
- checkInheritance(ctor);
365
+ const ctor = new.target;
366
+ handleSigil(ctor);
437
367
  }
438
368
  /**
439
369
  * Runtime predicate indicating whether `obj` is an instance produced by a sigil class.
@@ -445,107 +375,84 @@ function SigilifyAbstract(Base, label, opts) {
445
375
  return isSigilInstance(obj);
446
376
  }
447
377
  /**
448
- * Check whether `other` is (or inherits from) the type represented by the calling constructor.
449
- *
450
- * Implementation detail:
451
- * - Uses the other instance's `__LABEL_SET__` for O(1) membership test.
452
- * - O(1) and reliable as long as `OPTIONS.skipLabelInheritanceCheck` is `false`.
378
+ * Check whether `other` is (or inherits from) the instance represented by the
379
+ * calling constructor.
453
380
  *
454
381
  * This replaces `instanceof` so that checks remain valid across bundles/realms
455
382
  * and when subclassing.
456
383
  *
457
- * @typeParam T - The calling constructor type (narrowing the returned instance type).
458
- * @param this - The constructor performing the check.
384
+ * @typeParam T - The specific sigil constructor (`this`).
385
+ * @param this - The constructor performing the type check.
459
386
  * @param other - The object to test.
460
- * @returns `true` if `other` is an instance of this type or a subtype.
387
+ * @returns A type guard asserting `other` is an instance of the constructor.
461
388
  */
462
389
  static isOfType(other) {
463
390
  var _a;
464
- if (!isSigilInstance(other)) return false;
465
- const otherSet = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_SET__];
466
- const thisType = this[__LABEL__];
467
- return !!otherSet && otherSet.has(thisType);
391
+ if (other == null || typeof other !== "object") return false;
392
+ return other[(_a = this.prototype) == null ? void 0 : _a[__SIGIL__]] === true;
468
393
  }
469
394
  /**
470
- * Strict lineage check: compares the type label lineage arrays element-by-element.
395
+ * Check whether `other` is exactly the same instance represented by the
396
+ * calling constructor.
471
397
  *
472
- * Implementation detail:
473
- * - Works in O(n) time where n is the depth of the lineage.
474
- * - Reliable when `OPTIONS.skipLabelInheritanceCheck` is `false`.
475
- *
476
- * @typeParam T - The calling constructor type.
477
- * @param this - The constructor performing the check.
398
+ * @typeParam T - The specific sigil constructor (`this`).
399
+ * @param this - The constructor performing the type check.
478
400
  * @param other - The object to test.
479
- * @returns `true` if `other` has an identical lineage up to the length of this constructor's lineage.
401
+ * @returns A type guard asserting `other` is an instance of the constructor.
480
402
  */
481
- static isOfTypeStrict(other) {
482
- var _a;
483
- if (!isSigilInstance(other)) return false;
484
- const otherLineage = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_LINEAGE__];
485
- const thisLineage = this[__LABEL_LINEAGE__];
486
- return !!otherLineage && thisLineage.every((s, i) => s === otherLineage[i]);
403
+ static isExactType(other) {
404
+ var _a, _b, _c;
405
+ if (other == null || typeof other !== "object") return false;
406
+ if (((_a = this.prototype) == null ? void 0 : _a[__LINEAGE__].size) !== ((_b = other[__LINEAGE__]) == null ? void 0 : _b.size))
407
+ return false;
408
+ return other[(_c = this.prototype) == null ? void 0 : _c[__SIGIL__]] === true;
487
409
  }
488
410
  /**
489
- * Check whether `other` is (or inherits from) the type instance.
411
+ * Check whether `other` is (or inherits from) the instance represented by the
412
+ * calling constructor.
490
413
  *
491
- * Allows 'instanceof' like checks but in instances.
414
+ * This replaces `instanceof` so that checks remain valid across bundles/realms
415
+ * and when subclassing.
492
416
  *
493
- * @typeParam T - The instance type.
494
- * @param this - The instance performing the check.
417
+ * @typeParam T - The specific sigil constructor (`this`).
418
+ * @param this - The constructor performing the type check.
495
419
  * @param other - The object to test.
496
- * @returns `true` if `other` is the same instance of this type or a subtype.
420
+ * @returns A type guard asserting `other` is an instance of the constructor.
497
421
  */
498
422
  isOfType(other) {
499
- var _a;
500
- if (!isSigilInstance(other)) return false;
501
- const otherSet = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_SET__];
502
- const thisType = getConstructor(this)[__LABEL__];
503
- return !!otherSet && otherSet.has(thisType);
423
+ if (other == null || typeof other !== "object") return false;
424
+ return other[this[__SIGIL__]] === true;
504
425
  }
505
426
  /**
506
- * Strict lineage check: compares the type label lineage arrays element-by-element.
427
+ * Check whether `other` is exactly the same instance represented by the
428
+ * calling constructor.
507
429
  *
508
- * Allows 'instanceof' like checks but in instances.
509
- *
510
- * @typeParam T - The instance type.
511
- * @param this - The instance performing the check.
430
+ * @typeParam T - The specific sigil constructor (`this`).
431
+ * @param this - The constructor performing the type check.
512
432
  * @param other - The object to test.
513
- * @returns `true` if `other` has an identical lineage up to the length of this instance's lineage.
433
+ * @returns A type guard asserting `other` is an instance of the constructor.
514
434
  */
515
- isOfTypeStrict(other) {
516
- var _a, _b;
517
- if (!isSigilInstance(other)) return false;
518
- const otherLineage = (_a = getConstructor(other)) == null ? void 0 : _a[__LABEL_LINEAGE__];
519
- const thisLineage = (_b = getConstructor(this)) == null ? void 0 : _b[__LABEL_LINEAGE__];
520
- return !!otherLineage && thisLineage.every((s, i) => s === otherLineage[i]);
435
+ isExactType(other) {
436
+ var _a;
437
+ if (other == null || typeof other !== "object") return false;
438
+ if (this[__LINEAGE__].size !== ((_a = other[__LINEAGE__]) == null ? void 0 : _a.size)) return false;
439
+ return other[this[__SIGIL__]] === true;
521
440
  }
522
441
  /**
523
442
  * Returns the identity sigil label of this instance's constructor.
524
443
  *
525
- * @returns The label string if passed (e.g. '@scope/pkg.ClassName'), random label if not passed (e.g. '@Sigil.auto-dq62ib6jnvmmlfbjhxh2937h') or '@Sigil.unknown' if constructor is missing.
444
+ * @returns The label string if passed (e.g. '@scope/pkg.ClassName'), random label if not passed (e.g. '@Sigil-auto:ClassName:mm2gkdwn:0:g1sq').
526
445
  */
527
446
  getSigilLabel() {
528
- const ctor = getConstructor(this);
529
- if (!ctor) {
530
- if (process.env.NODE_ENV !== "production")
531
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
532
- return "@Sigil.unknown";
533
- }
534
- return ctor.SigilLabel;
447
+ return this[__LABEL__];
535
448
  }
536
449
  /**
537
450
  * Returns the human-readable sigil label of this instance's constructor.
538
451
  *
539
- * @returns The last passed label string (e.g. '@scope/pkg.ClassName') or '@Sigil.unknown' if constructor is missing.
452
+ * @returns The last passed label string (e.g. '@scope/pkg.ClassName').
540
453
  */
541
454
  getSigilEffectiveLabel() {
542
- const ctor = getConstructor(this);
543
- if (!ctor) {
544
- if (process.env.NODE_ENV !== "production")
545
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
546
- return "@Sigil.unknown";
547
- }
548
- return ctor.SigilEffectiveLabel;
455
+ return this[__EFFECTIVE_LABEL__];
549
456
  }
550
457
  /**
551
458
  * Returns a copy of the sigil type label lineage for this instance's constructor.
@@ -553,92 +460,57 @@ function SigilifyAbstract(Base, label, opts) {
553
460
  * @returns readonly array of labels representing the type lineage.
554
461
  */
555
462
  getSigilLabelLineage() {
556
- const ctor = getConstructor(this);
557
- if (!ctor) {
558
- if (process.env.NODE_ENV !== "production")
559
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
560
- return ["@Sigil.unknown"];
561
- }
562
- return ctor.SigilLabelLineage;
463
+ return [...this[__LINEAGE__]];
563
464
  }
564
465
  /**
565
- * Returns a readonly copy of the sigil type label set for this instance's constructor.
466
+ * Returns a copy of the sigil type label lineage set for this instance's constructor.
566
467
  *
567
- * @returns A Readonly Set of labels representing the type lineage for O(1) membership tests.
468
+ * @returns readonly array of labels representing the type lineage.
568
469
  */
569
470
  getSigilLabelSet() {
570
- const ctor = getConstructor(this);
571
- if (!ctor) {
572
- if (process.env.NODE_ENV !== "production")
573
- throw new Error(`[Sigil Error] Sigil class instance without constructor`);
574
- return /* @__PURE__ */ new Set(["@Sigil.unknown"]);
575
- }
576
- return ctor.SigilLabelSet;
471
+ return this[__LINEAGE__];
577
472
  }
578
473
  }
579
- decorateCtor(Sigilified, l, { isMixin: true });
580
- markSigil(Sigilified);
581
- markSigilBase(Sigilified);
474
+ handleSigil(Sigilified, label, opts);
582
475
  return Sigilified;
583
476
  }
584
477
 
585
- // src/core/classes.ts
478
+ // src/classes.ts
586
479
  var Sigil = Sigilify(class {
587
480
  }, "Sigil");
588
481
  var SigilError = Sigilify(Error, "SigilError");
589
482
 
590
- // src/core/decorator.ts
483
+ // src/decorator.ts
591
484
  function WithSigil(label, opts) {
592
- let l;
593
- if (label) {
594
- verifyLabel(label, opts);
595
- l = label;
596
- } else l = generateRandomLabel();
597
485
  return function(value, context) {
598
486
  if (context.kind !== "class") return;
599
487
  if (!isSigilCtor(value))
600
488
  throw new Error(
601
489
  `[Sigil Error] 'WithSigil' decorator accept only Sigil classes but used on class ${value.name}`
602
490
  );
603
- decorateCtor(value, l);
604
- checkInheritance(value, opts);
491
+ if (hasOwnSigil(value))
492
+ throw new Error(
493
+ `[Sigil Error] Class '${value.name}' with label '${value.SigilLabel}' is already sigilified`
494
+ );
495
+ handleSigil(value, label, opts);
605
496
  };
606
497
  }
607
498
 
608
- // src/core/hof.ts
499
+ // src/hof.ts
609
500
  function withSigil(Class, label, opts) {
610
501
  var _a;
611
502
  if (!isSigilCtor(Class))
612
503
  throw new Error(
613
504
  `[Sigil Error] 'withSigil' HOF accept only Sigil classes but used on class ${(_a = Class == null ? void 0 : Class.name) != null ? _a : "unknown"}`
614
505
  );
615
- let l;
616
- if (label) {
617
- verifyLabel(label, opts);
618
- l = label;
619
- } else l = generateRandomLabel();
620
- const ctor = Class;
621
- decorateCtor(ctor, l);
622
- checkInheritance(ctor, opts);
623
- return Class;
624
- }
625
- function withSigilTyped(Class, label, opts) {
626
- var _a;
627
- if (!isSigilCtor(Class))
506
+ if (hasOwnSigil(Class))
628
507
  throw new Error(
629
- `[Sigil Error] 'withSigilTyped' HOF accept only Sigil classes but used on class ${(_a = Class == null ? void 0 : Class.name) != null ? _a : "unknown"}`
508
+ `[Sigil Error] Class '${Class.name}' with label '${Class.SigilLabel}' is already sigilified`
630
509
  );
631
- let l;
632
- if (label) {
633
- verifyLabel(label, opts);
634
- l = label;
635
- } else l = generateRandomLabel();
636
- const ctor = Class;
637
- decorateCtor(ctor, l);
638
- checkInheritance(ctor, opts);
510
+ handleSigil(Class, label, opts);
639
511
  return Class;
640
512
  }
641
513
 
642
- export { DEFAULT_LABEL_REGEX, Sigil, SigilError, Sigilify, SigilifyAbstract, WithSigil, isDecorated, isInheritanceChecked, isSigilBaseCtor, isSigilBaseInstance, isSigilCtor, isSigilInstance, updateSigilOptions, withSigil, withSigilTyped };
514
+ export { DEFAULT_LABEL_REGEX, Sigil, SigilError, Sigilify, SigilifyAbstract, WithSigil, isSigilCtor, isSigilInstance, updateSigilOptions, withSigil };
643
515
  //# sourceMappingURL=index.mjs.map
644
516
  //# sourceMappingURL=index.mjs.map