@memberjunction/global 5.48.0 → 5.50.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.
@@ -25,12 +25,54 @@ export declare class ClassRegistration {
25
25
  */
26
26
  Metadata?: Record<string, unknown>;
27
27
  }
28
+ /**
29
+ * The outcome of a {@link ClassFactory.TryCreateInstance} call — an EXPLICIT resolution result
30
+ * so callers can distinguish "a registered subclass was found and instantiated" from "no
31
+ * registration matched the key and we fell back to the anchor base class".
32
+ *
33
+ * ## Why this type exists
34
+ * {@link ClassFactory.CreateInstance} has NEVER returned `null` for an unregistered key — it
35
+ * falls back to `new BaseClass(...)`. Call sites written as `const x = CreateInstance(Base, key);
36
+ * if (x) { use it } else { error }` therefore have a DEAD else-branch and silently install a
37
+ * hollow base-class object. That failure mode is invisible until something calls a method the
38
+ * base does not implement. `TryCreateInstance` makes the distinction explicit and checkable.
39
+ */
40
+ export type ClassResolutionResult<T> = {
41
+ /**
42
+ * `true` only when a REGISTERED subclass matched the requested key. `false` means the key did
43
+ * not resolve — check {@link Instance} to see whether a base-class fallback was produced.
44
+ */
45
+ Resolved: boolean;
46
+ /**
47
+ * The instance to use, or `null`.
48
+ *
49
+ * - `Resolved: true` → the registered subclass instance.
50
+ * - `Resolved: false` and the anchor base is marked `@RequiresSubclass()` → `null`
51
+ * (the base cannot function standalone, so no fallback is produced).
52
+ * - `Resolved: false` and no marker → the base-class fallback instance. This is a legitimate,
53
+ * long-standing pattern (e.g. `BaseEntity`, which is fully functional standalone).
54
+ */
55
+ Instance: T | null;
56
+ /** Human-readable explanation, present whenever `Resolved` is `false`. */
57
+ Reason?: string;
58
+ };
59
+ /**
60
+ * Shape of a base class that opts in to the "I cannot be instantiated standalone" contract.
61
+ *
62
+ * TypeScript's `abstract` keyword is ERASED at runtime — there is no marker property, and plain
63
+ * JS will happily `new` an abstract class — so abstractness cannot be introspected. Bases that
64
+ * genuinely cannot function without a subclass therefore declare this static marker explicitly.
65
+ */
28
66
  /**
29
67
  * ClassFactory is used to register and create instances of classes. It is a singleton class that can be used to register a sub-class for a given base class and key. Do NOT directly attempt to instantiate this class,
30
68
  * instead use the static Instance property of the MJGlobal class to get the instance of the ClassFactory for your application.
31
69
  */
32
70
  export declare class ClassFactory {
33
71
  private _registrations;
72
+ /** Per-base fallback-warning counter, backing the volume cap in reportResolutionFailure. */
73
+ private _fallbackCountByBase;
74
+ /** Fallback warnings emitted per base class before summarising and going quiet. */
75
+ private static readonly MAX_FALLBACK_REPORTS_PER_BASE;
34
76
  /**
35
77
  * Memoized results of {@link GetRegistration}, keyed by `baseClassName|normalizedKey`.
36
78
  * GetRegistration is on extremely hot paths (every `CreateInstance`, including one call
@@ -51,6 +93,11 @@ export declare class ClassFactory {
51
93
  * successfully loaded the module containing the requested class registration.
52
94
  */
53
95
  private _lazyLoaders;
96
+ /**
97
+ * `baseClassName|normalizedKey` pairs whose base-class-fallback diagnostic has already been
98
+ * emitted, so a hot-path resolution failure logs once instead of on every call.
99
+ */
100
+ private _reportedResolutionFailures;
54
101
  /**
55
102
  * Registers a lazy loader callback that will be called when a class registration cannot
56
103
  * be found synchronously. Multiple loaders can be registered and will be called in order
@@ -81,9 +128,15 @@ export declare class ClassFactory {
81
128
  * retrying and creating the instance.
82
129
  *
83
130
  * Falls back to instantiating the base class directly if no registration is found even
84
- * after lazy loading (same behavior as the sync CreateInstance).
131
+ * after lazy loading (same behavior as the sync CreateInstance) — including throwing when the
132
+ * anchor base is marked `@RequiresSubclass()`.
85
133
  */
86
134
  CreateInstanceAsync<T>(baseClass: unknown, key?: string | null, ...params: unknown[]): Promise<T | null>;
135
+ /**
136
+ * Explicit-result, lazy-loading-aware sibling of {@link TryCreateInstance}. Never throws for
137
+ * an unresolved key.
138
+ */
139
+ TryCreateInstanceAsync<T>(baseClass: unknown, key?: string | null, ...params: unknown[]): Promise<ClassResolutionResult<T>>;
87
140
  /**
88
141
  * Use this method or the @RegisterClass decorator to register a sub-class for a given base class.
89
142
  * @param baseClass A reference to the base class you are registering a sub-class for
@@ -96,9 +149,50 @@ export declare class ClassFactory {
96
149
  Register(baseClass: unknown, subClass: unknown, key?: string | null, priority?: number, skipNullKeyWarning?: boolean, autoRegisterWithRootClass?: boolean, metadata?: Record<string, unknown>): void;
97
150
  /**
98
151
  * Creates an instance of the class registered for the given base class and key.
99
- * If no registration is found, will return an instance of the base class.
152
+ *
153
+ * If no registration is found, falls back to instantiating the base class itself — a
154
+ * long-standing, deliberate behavior that legitimate consumers (notably `BaseEntity`) rely on.
155
+ * **This method therefore does NOT return `null` for an unregistered key**, so `if (instance)`
156
+ * is not a valid resolution-failure test. Use {@link TryCreateInstance} when you need to know
157
+ * whether the key actually resolved.
158
+ *
159
+ * @throws when the key does not resolve AND the anchor base class declares
160
+ * `@RequiresSubclass()` (i.e. it cannot function standalone). Bases without
161
+ * that marker keep the historical fallback behavior and only emit a structured warning.
100
162
  */
101
163
  CreateInstance<T>(baseClass: unknown, key?: string | null, ...params: unknown[]): T | null;
164
+ /**
165
+ * Explicit-result sibling of {@link CreateInstance}. Never throws for an unresolved key —
166
+ * returns a {@link ClassResolutionResult} so the caller can branch on `Resolved`.
167
+ *
168
+ * ```typescript
169
+ * const res = MJGlobal.Instance.ClassFactory.TryCreateInstance<MyProvider>(MyProviderBase, key);
170
+ * if (!res.Resolved || !res.Instance) {
171
+ * LogError(`provider '${key}' did not resolve: ${res.Reason}`);
172
+ * return; // skip — do NOT install a hollow base instance
173
+ * }
174
+ * use(res.Instance);
175
+ * ```
176
+ */
177
+ TryCreateInstance<T>(baseClass: unknown, key?: string | null, ...params: unknown[]): ClassResolutionResult<T>;
178
+ /**
179
+ * Single shared resolution path behind `CreateInstance`, `TryCreateInstance`, and
180
+ * `CreateInstanceAsync` — so the sync and async surfaces (and the throwing and non-throwing
181
+ * surfaces) can never drift apart in how they treat a fallback.
182
+ */
183
+ private resolveAndInstantiate;
184
+ /**
185
+ * Builds the diagnostic message for a failed key resolution. The registered-key list is the
186
+ * highest-value part: a typo'd or tree-shaken key is immediately obvious next to the keys the
187
+ * factory actually knows about.
188
+ */
189
+ private describeResolutionFailure;
190
+ /**
191
+ * Emits the fallback diagnostic exactly once per (baseClass, key) pair — resolution happens on
192
+ * very hot paths (once per entity-field hydration), so an un-deduped log would be a firehose.
193
+ * A captured stack is included so the offending call site is identifiable.
194
+ */
195
+ private reportResolutionFailure;
102
196
  /**
103
197
  * Returns all registrations for a given base class and key. If key is not provided, will return all registrations for the base class.
104
198
  * @param baseClass
@@ -1 +1 @@
1
- {"version":3,"file":"ClassFactory.d.ts","sourceRoot":"","sources":["../src/ClassFactory.ts"],"names":[],"mappings":"AAAA;;;;;;wGAMwG;AASxG;;GAEG;AACH,qBAAa,iBAAiB;IAE1B,SAAS,EAAE,GAAG,CAAC;IAEf,QAAQ,EAAE,GAAG,CAAC;IAEd,SAAS,EAAE,GAAG,CAAC;IACf,GAAG,EAAE,MAAM,GAAG,IAAI,CAAQ;IAE1B,QAAQ,EAAE,MAAM,CAAK;IACrB;;;;;;;;OAQG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACtC;AAGD;;;GAGG;AACH,qBAAa,YAAY;IACrB,OAAO,CAAC,cAAc,CAA2B;IAEjD;;;;;;;;OAQG;IACH,OAAO,CAAC,kBAAkB,CAAoD;IAE9E;;;;;;;;OAQG;IACH,OAAO,CAAC,YAAY,CAAoE;IAExF;;;;;;;OAOG;IACI,kBAAkB,CAAC,MAAM,EAAE,CAAC,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,IAAI;IAIjG;;;OAGG;YACW,WAAW;IAWzB;;;;;;;;OAQG;IACU,oBAAoB,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC,iBAAiB,GAAG,IAAI,CAAC;IAW7G;;;;;;;OAOG;IACU,mBAAmB,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC;IAmB3H;;;;;;;;OAQG;IACI,QAAQ,CAAC,SAAS,EAAE,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW,EAAE,QAAQ,GAAE,MAAU,EAAE,kBAAkB,GAAE,OAAe,EAAE,yBAAyB,GAAE,OAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;IA4DlO;;;OAGG;IACI,cAAc,CAAC,CAAC,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG,GAAE,MAAM,GAAG,IAAW,EAAE,GAAG,MAAM,EAAE,OAAO,EAAE,GAAG,CAAC,GAAG,IAAI;IAuBvG;;;;;OAKG;IACI,mBAAmB,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,EAAE;IAaxF;;;;;;;OAOG;IACI,8BAA8B,CAAC,SAAS,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAWjG;;;;OAIG;IACI,+BAA+B,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,iBAAiB,EAAE;IAUhG;;;;;;;;OAQG;IACI,6BAA6B,CAChC,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAAE,YAAY,EAAE,iBAAiB,KAAK,OAAO,GACvG,iBAAiB,EAAE;IAUtB;;OAEG;IACI,eAAe,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,GAAG,IAAI;IAazF;;;;OAIG;IACH,OAAO,CAAC,mBAAmB;IAoB3B;;;;;;OAMG;IACI,2BAA2B,CAAC,SAAS,EAAE,OAAO,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,iBAAiB,EAAE;CAWnG"}
1
+ {"version":3,"file":"ClassFactory.d.ts","sourceRoot":"","sources":["../src/ClassFactory.ts"],"names":[],"mappings":"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"}
@@ -6,6 +6,8 @@
6
6
  * and we will dynamically instantiate that sub-class from that point forward
7
7
  ******************************************************************************************************/
8
8
  import { GetRootClass } from './ClassUtils.js';
9
+ import { ClassRequiresSubclass } from './RequiresSubclass.js';
10
+ import { ClassIsOptionalKeyedSpecialization } from './OptionalKeyedSpecialization.js';
9
11
  /**
10
12
  * Data structure to track the class registrations
11
13
  */
@@ -16,6 +18,17 @@ export class ClassRegistration {
16
18
  this.Priority = 0; // if there are multiple entries for a given combination of baseClass and subClass and key, we will use the priority to determine which one to use. The higher the number, the higher the priority
17
19
  }
18
20
  }
21
+ /**
22
+ * Shape of a base class that opts in to the "I cannot be instantiated standalone" contract.
23
+ *
24
+ * TypeScript's `abstract` keyword is ERASED at runtime — there is no marker property, and plain
25
+ * JS will happily `new` an abstract class — so abstractness cannot be introspected. Bases that
26
+ * genuinely cannot function without a subclass therefore declare this static marker explicitly.
27
+ */
28
+ // NOTE: resolved via ClassRequiresSubclass(), which performs an OWN-property check. A plain
29
+ // `cls.RequiresSubclass` read walks the constructor prototype chain, so every SUBCLASS of a
30
+ // marked base would also report true — and resolving against a concrete subclass would then
31
+ // wrongly throw. See RequiresSubclass.ts.
19
32
  /**
20
33
  * ClassFactory is used to register and create instances of classes. It is a singleton class that can be used to register a sub-class for a given base class and key. Do NOT directly attempt to instantiate this class,
21
34
  * instead use the static Instance property of the MJGlobal class to get the instance of the ClassFactory for your application.
@@ -23,6 +36,8 @@ export class ClassRegistration {
23
36
  export class ClassFactory {
24
37
  constructor() {
25
38
  this._registrations = [];
39
+ /** Per-base fallback-warning counter, backing the volume cap in reportResolutionFailure. */
40
+ this._fallbackCountByBase = new Map();
26
41
  /**
27
42
  * Memoized results of {@link GetRegistration}, keyed by `baseClassName|normalizedKey`.
28
43
  * GetRegistration is on extremely hot paths (every `CreateInstance`, including one call
@@ -43,7 +58,14 @@ export class ClassFactory {
43
58
  * successfully loaded the module containing the requested class registration.
44
59
  */
45
60
  this._lazyLoaders = [];
61
+ /**
62
+ * `baseClassName|normalizedKey` pairs whose base-class-fallback diagnostic has already been
63
+ * emitted, so a hot-path resolution failure logs once instead of on every call.
64
+ */
65
+ this._reportedResolutionFailures = new Set();
46
66
  }
67
+ /** Fallback warnings emitted per base class before summarising and going quiet. */
68
+ static { this.MAX_FALLBACK_REPORTS_PER_BASE = 3; }
47
69
  /**
48
70
  * Registers a lazy loader callback that will be called when a class registration cannot
49
71
  * be found synchronously. Multiple loaders can be registered and will be called in order
@@ -94,23 +116,30 @@ export class ClassFactory {
94
116
  * retrying and creating the instance.
95
117
  *
96
118
  * Falls back to instantiating the base class directly if no registration is found even
97
- * after lazy loading (same behavior as the sync CreateInstance).
119
+ * after lazy loading (same behavior as the sync CreateInstance) — including throwing when the
120
+ * anchor base is marked `@RequiresSubclass()`.
98
121
  */
99
122
  async CreateInstanceAsync(baseClass, key = null, ...params) {
100
123
  if (!baseClass) {
101
124
  return null;
102
125
  }
103
126
  const reg = await this.GetRegistrationAsync(baseClass, key);
104
- if (reg) {
105
- const SubClassConstructor = reg.SubClass;
106
- if (params !== undefined) {
107
- return new SubClassConstructor(...params);
108
- }
109
- return new SubClassConstructor();
127
+ const result = this.resolveAndInstantiate(baseClass, reg, key, params);
128
+ if (!result.Resolved && result.Instance === null) {
129
+ throw new Error(result.Reason);
110
130
  }
111
- // Fallback to base class (same as sync CreateInstance)
112
- const BaseClassConstructor = baseClass;
113
- return new BaseClassConstructor(...params);
131
+ return result.Instance;
132
+ }
133
+ /**
134
+ * Explicit-result, lazy-loading-aware sibling of {@link TryCreateInstance}. Never throws for
135
+ * an unresolved key.
136
+ */
137
+ async TryCreateInstanceAsync(baseClass, key = null, ...params) {
138
+ if (!baseClass) {
139
+ return { Resolved: false, Instance: null, Reason: 'ClassFactory: no base class was provided.' };
140
+ }
141
+ const reg = await this.GetRegistrationAsync(baseClass, key);
142
+ return this.resolveAndInstantiate(baseClass, reg, key, params);
114
143
  }
115
144
  /**
116
145
  * Use this method or the @RegisterClass decorator to register a sub-class for a given base class.
@@ -171,31 +200,154 @@ export class ClassFactory {
171
200
  // Invalidate the GetRegistration memo — a new registration may change the
172
201
  // highest-priority winner for any (baseClass, key) bucket.
173
202
  this._registrationCache.clear();
203
+ // A new registration may resolve a key that previously fell back, so allow the
204
+ // diagnostic to be emitted again if it fails a second time.
205
+ this._reportedResolutionFailures.clear();
174
206
  }
175
207
  }
176
208
  /**
177
209
  * Creates an instance of the class registered for the given base class and key.
178
- * If no registration is found, will return an instance of the base class.
210
+ *
211
+ * If no registration is found, falls back to instantiating the base class itself — a
212
+ * long-standing, deliberate behavior that legitimate consumers (notably `BaseEntity`) rely on.
213
+ * **This method therefore does NOT return `null` for an unregistered key**, so `if (instance)`
214
+ * is not a valid resolution-failure test. Use {@link TryCreateInstance} when you need to know
215
+ * whether the key actually resolved.
216
+ *
217
+ * @throws when the key does not resolve AND the anchor base class declares
218
+ * `@RequiresSubclass()` (i.e. it cannot function standalone). Bases without
219
+ * that marker keep the historical fallback behavior and only emit a structured warning.
179
220
  */
180
221
  CreateInstance(baseClass, key = null, ...params) {
181
- if (baseClass) {
182
- let reg = this.GetRegistration(baseClass, key);
183
- if (reg) {
184
- const SubClassConstructor = reg.SubClass;
185
- let instance = null;
186
- if (params !== undefined)
187
- instance = new SubClassConstructor(...params);
188
- else
189
- instance = new SubClassConstructor(); // dont pass in anything if we got undefined for that parameter into our function because it is different to call a function with no params than to pass in a single null/undefined param
190
- return instance;
222
+ const result = this.resolveAndInstantiate(baseClass, this.GetRegistration(baseClass, key), key, params);
223
+ if (!result.Resolved && result.Instance === null && baseClass) {
224
+ // The base explicitly cannot stand alone — fail LOUD rather than handing back a hollow object.
225
+ throw new Error(result.Reason);
226
+ }
227
+ return result.Instance;
228
+ }
229
+ /**
230
+ * Explicit-result sibling of {@link CreateInstance}. Never throws for an unresolved key —
231
+ * returns a {@link ClassResolutionResult} so the caller can branch on `Resolved`.
232
+ *
233
+ * ```typescript
234
+ * const res = MJGlobal.Instance.ClassFactory.TryCreateInstance<MyProvider>(MyProviderBase, key);
235
+ * if (!res.Resolved || !res.Instance) {
236
+ * LogError(`provider '${key}' did not resolve: ${res.Reason}`);
237
+ * return; // skip — do NOT install a hollow base instance
238
+ * }
239
+ * use(res.Instance);
240
+ * ```
241
+ */
242
+ TryCreateInstance(baseClass, key = null, ...params) {
243
+ return this.resolveAndInstantiate(baseClass, this.GetRegistration(baseClass, key), key, params);
244
+ }
245
+ /**
246
+ * Single shared resolution path behind `CreateInstance`, `TryCreateInstance`, and
247
+ * `CreateInstanceAsync` — so the sync and async surfaces (and the throwing and non-throwing
248
+ * surfaces) can never drift apart in how they treat a fallback.
249
+ */
250
+ resolveAndInstantiate(baseClass, reg, key, params) {
251
+ if (!baseClass) {
252
+ return { Resolved: false, Instance: null, Reason: 'ClassFactory: no base class was provided.' };
253
+ }
254
+ if (reg) {
255
+ const SubClassConstructor = reg.SubClass;
256
+ return { Resolved: true, Instance: new SubClassConstructor(...params) };
257
+ }
258
+ // ── Fallback path: the requested key did not resolve to any registered subclass. ──
259
+ const requiresSubclass = ClassRequiresSubclass(baseClass);
260
+ const reason = this.describeResolutionFailure(baseClass, key, requiresSubclass);
261
+ // Only REPORT when the caller actually asked for something specific.
262
+ //
263
+ // A null/empty key means "give me the default implementation for this base" — landing on
264
+ // the base is the INTENDED outcome, not a failed lookup, so warning about it is a false
265
+ // positive. This fired on every `CreateInstance(LoggerBase, null)` and made the
266
+ // instrumentation noisy enough to obscure real resolution failures during a full repo
267
+ // build, which is the opposite of what it was added for.
268
+ //
269
+ // A marker-bearing base is always reported: there, landing on the base IS an error
270
+ // regardless of whether a key was supplied.
271
+ const keyWasSupplied = key !== null && key !== undefined && String(key).trim().length > 0;
272
+ // A base marked '@OptionalKeyedSpecialization()' declares the opposite contract for keyed
273
+ // lookups: the key is a "specialize if registered" PROBE and landing on the base is the
274
+ // designed common case (EntityField hydration probes '<Entity>.<Field>' for every field of
275
+ // every entity). Reporting there is a false positive by construction, so such bases are
276
+ // exempt. Marker-bearing (@RequiresSubclass) bases are never exempt — fallback is a hard
277
+ // error there regardless.
278
+ const fallbackIsDesigned = !requiresSubclass && ClassIsOptionalKeyedSpecialization(baseClass);
279
+ if ((keyWasSupplied && !fallbackIsDesigned) || requiresSubclass) {
280
+ this.reportResolutionFailure(baseClass, key, requiresSubclass, reason);
281
+ }
282
+ if (requiresSubclass) {
283
+ return { Resolved: false, Instance: null, Reason: reason };
284
+ }
285
+ // No marker — the base is presumed usable standalone (e.g. BaseEntity). Preserve the
286
+ // historical fallback so existing, CORRECT consumers keep working.
287
+ const BaseClassConstructor = baseClass;
288
+ return { Resolved: false, Instance: new BaseClassConstructor(...params), Reason: reason };
289
+ }
290
+ /**
291
+ * Builds the diagnostic message for a failed key resolution. The registered-key list is the
292
+ * highest-value part: a typo'd or tree-shaken key is immediately obvious next to the keys the
293
+ * factory actually knows about.
294
+ */
295
+ describeResolutionFailure(baseClass, key, requiresSubclass) {
296
+ const baseClassName = baseClass.name;
297
+ const known = this.GetAllRegistrations(baseClass)
298
+ .map(r => r.Key)
299
+ .filter((k) => k != null);
300
+ const uniqueKnown = Array.from(new Set(known)).sort();
301
+ const knownText = uniqueKnown.length > 0 ? uniqueKnown.map(k => `'${k}'`).join(', ') : '(none)';
302
+ return (`ClassFactory: no registration found for base class '${baseClassName}' with key '${key ?? '(null)'}'. ` +
303
+ `Registered keys for '${baseClassName}': ${knownText}. ` +
304
+ `RequiresSubclass=${requiresSubclass}. ` +
305
+ (requiresSubclass
306
+ ? `'${baseClassName}' is marked '@RequiresSubclass()', so it CANNOT be used as a fallback — ` +
307
+ `no instance was created. Likely causes: a typo in the key, a class that was never imported ` +
308
+ `(tree-shaken out — check the class-registration manifest), or a missing @RegisterClass decorator.`
309
+ : `Falling back to an instance of '${baseClassName}' itself. If that base cannot function standalone, ` +
310
+ `apply the '@RequiresSubclass()' decorator to it so this becomes a hard error.`));
311
+ }
312
+ /**
313
+ * Emits the fallback diagnostic exactly once per (baseClass, key) pair — resolution happens on
314
+ * very hot paths (once per entity-field hydration), so an un-deduped log would be a firehose.
315
+ * A captured stack is included so the offending call site is identifiable.
316
+ */
317
+ reportResolutionFailure(baseClass, key, requiresSubclass, reason) {
318
+ // Volume cap, PER BASE CLASS (not per base+key).
319
+ //
320
+ // The existing dedup keys on base+key, which is useless for callers whose key varies per
321
+ // item: every EntityField hydration passes '<entity>.<field>', so a full repo build
322
+ // emitted thousands of distinct warnings and buried the real ones. Suppressing by
323
+ // "base has no registrations" was tried and REVERTED — that is exactly the B34/B35 shape
324
+ // (a tree-shaken registration leaves zero registrations), so it would hide the case this
325
+ // instrumentation exists to catch.
326
+ //
327
+ // Capping keeps the signal — you still learn which base is falling back, with examples —
328
+ // while bounding the output. Marker-bearing bases are never capped: those are hard errors.
329
+ if (!requiresSubclass) {
330
+ const baseName = baseClass.name;
331
+ const seen = (this._fallbackCountByBase.get(baseName) ?? 0) + 1;
332
+ this._fallbackCountByBase.set(baseName, seen);
333
+ if (seen === ClassFactory.MAX_FALLBACK_REPORTS_PER_BASE + 1) {
334
+ console.warn(`ClassFactory: further '${baseName}' fallback warnings suppressed (${ClassFactory.MAX_FALLBACK_REPORTS_PER_BASE} shown). If fallback is by design for this base, mark it '@OptionalKeyedSpecialization()'.`);
335
+ return;
191
336
  }
192
- else {
193
- // this is a normal condition to use the base class if we can't find a registration
194
- const BaseClassConstructor = baseClass;
195
- return new BaseClassConstructor(...params); // if we can't find a registration, just return a new instance of the base class
337
+ if (seen > ClassFactory.MAX_FALLBACK_REPORTS_PER_BASE) {
338
+ return;
196
339
  }
197
340
  }
198
- return null;
341
+ const logKey = `${baseClass.name}|${key == null ? '' : key.trim().toLowerCase()}`;
342
+ if (this._reportedResolutionFailures.has(logKey))
343
+ return;
344
+ this._reportedResolutionFailures.add(logKey);
345
+ const stack = new Error().stack ?? '(stack unavailable)';
346
+ const message = `${reason}\nCall site:\n${stack}`;
347
+ if (requiresSubclass)
348
+ console.error(message);
349
+ else
350
+ console.warn(message);
199
351
  }
200
352
  /**
201
353
  * Returns all registrations for a given base class and key. If key is not provided, will return all registrations for the base class.
@@ -1 +1 @@
1
- {"version":3,"file":"ClassFactory.js","sourceRoot":"","sources":["../src/ClassFactory.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ClassFactory.js","sourceRoot":"","sources":["../src/ClassFactory.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * OptionalKeyedSpecialization.ts — marks a base class whose KEYED lookups are optional
3
+ * specialization probes, so falling back to the base is the DESIGNED common case.
4
+ *
5
+ * ## Why this exists
6
+ * The ClassFactory reports keyed lookups that land on the base class, because for most bases a
7
+ * supplied key means "I demand implementation X" — landing on the base then signals a typo'd key
8
+ * or a tree-shaken registration (the B34/B35 failure class).
9
+ *
10
+ * But some bases invert that contract. `EntityField` hydration asks the factory for
11
+ * `'<Entity>.<Field>'` on EVERY field of EVERY entity — an extension point that says "if someone
12
+ * registered a per-field subclass, give me that; otherwise the base is exactly what I want."
13
+ * There, base fallback is not a failed lookup; it is the expected outcome for ~100% of keys, and
14
+ * warning about it is pure noise that buries real resolution failures.
15
+ *
16
+ * `@OptionalKeyedSpecialization()` is the base author's explicit declaration of that contract.
17
+ * The factory still resolves keyed registrations normally when they exist — the marker ONLY
18
+ * suppresses the fallback diagnostic.
19
+ *
20
+ * ## The trade-off, stated honestly
21
+ * On a marked base, a tree-shaken keyed registration falls back silently. That is the accepted
22
+ * semantic: keyed subclasses of such bases refine behavior, they are not required for
23
+ * correctness. Bases where fallback would be a correctness bug should use `@RequiresSubclass()`
24
+ * (hard error) or no marker at all (warn-and-fall-back).
25
+ *
26
+ * ## Usage
27
+ * ```ts
28
+ * @OptionalKeyedSpecialization()
29
+ * export class EntityField { ... }
30
+ * ```
31
+ *
32
+ * Same own-property mechanics as `@RequiresSubclass()` (see that file for the full rationale):
33
+ * the marker applies to exactly the class that declared it, never to its subclasses.
34
+ */
35
+ /**
36
+ * The marker key. `__mj_`-prefixed and non-enumerable so it cannot collide with application
37
+ * fields, appear in object spreads, or show up in serialized instances.
38
+ */
39
+ export declare const OPTIONAL_KEYED_SPECIALIZATION_KEY = "__mj_OptionalKeyedSpecialization";
40
+ /**
41
+ * Class decorator declaring that keyed ClassFactory lookups against this base are optional
42
+ * specialization probes — fallback to the base is by design and must not be reported.
43
+ */
44
+ export declare function OptionalKeyedSpecialization(): (constructor: Function) => void;
45
+ /**
46
+ * True iff `target` itself is marked `@OptionalKeyedSpecialization()`.
47
+ *
48
+ * Accepts either a class (constructor) or an instance. OWN-property check — a subclass of a
49
+ * marked base returns `false`, mirroring `ClassRequiresSubclass`.
50
+ */
51
+ export declare function ClassIsOptionalKeyedSpecialization(target: unknown): boolean;
52
+ //# sourceMappingURL=OptionalKeyedSpecialization.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionalKeyedSpecialization.d.ts","sourceRoot":"","sources":["../src/OptionalKeyedSpecialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;GAGG;AACH,eAAO,MAAM,iCAAiC,qCAAqC,CAAC;AAEpF;;;GAGG;AACH,wBAAgB,2BAA2B,IAAI,CAAC,WAAW,EAAE,QAAQ,KAAK,IAAI,CAS7E;AAED;;;;;GAKG;AACH,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,CAW3E"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * OptionalKeyedSpecialization.ts — marks a base class whose KEYED lookups are optional
3
+ * specialization probes, so falling back to the base is the DESIGNED common case.
4
+ *
5
+ * ## Why this exists
6
+ * The ClassFactory reports keyed lookups that land on the base class, because for most bases a
7
+ * supplied key means "I demand implementation X" — landing on the base then signals a typo'd key
8
+ * or a tree-shaken registration (the B34/B35 failure class).
9
+ *
10
+ * But some bases invert that contract. `EntityField` hydration asks the factory for
11
+ * `'<Entity>.<Field>'` on EVERY field of EVERY entity — an extension point that says "if someone
12
+ * registered a per-field subclass, give me that; otherwise the base is exactly what I want."
13
+ * There, base fallback is not a failed lookup; it is the expected outcome for ~100% of keys, and
14
+ * warning about it is pure noise that buries real resolution failures.
15
+ *
16
+ * `@OptionalKeyedSpecialization()` is the base author's explicit declaration of that contract.
17
+ * The factory still resolves keyed registrations normally when they exist — the marker ONLY
18
+ * suppresses the fallback diagnostic.
19
+ *
20
+ * ## The trade-off, stated honestly
21
+ * On a marked base, a tree-shaken keyed registration falls back silently. That is the accepted
22
+ * semantic: keyed subclasses of such bases refine behavior, they are not required for
23
+ * correctness. Bases where fallback would be a correctness bug should use `@RequiresSubclass()`
24
+ * (hard error) or no marker at all (warn-and-fall-back).
25
+ *
26
+ * ## Usage
27
+ * ```ts
28
+ * @OptionalKeyedSpecialization()
29
+ * export class EntityField { ... }
30
+ * ```
31
+ *
32
+ * Same own-property mechanics as `@RequiresSubclass()` (see that file for the full rationale):
33
+ * the marker applies to exactly the class that declared it, never to its subclasses.
34
+ */
35
+ /**
36
+ * The marker key. `__mj_`-prefixed and non-enumerable so it cannot collide with application
37
+ * fields, appear in object spreads, or show up in serialized instances.
38
+ */
39
+ export const OPTIONAL_KEYED_SPECIALIZATION_KEY = '__mj_OptionalKeyedSpecialization';
40
+ /**
41
+ * Class decorator declaring that keyed ClassFactory lookups against this base are optional
42
+ * specialization probes — fallback to the base is by design and must not be reported.
43
+ */
44
+ export function OptionalKeyedSpecialization() {
45
+ return function (constructor) {
46
+ Object.defineProperty(constructor.prototype, OPTIONAL_KEYED_SPECIALIZATION_KEY, {
47
+ value: true,
48
+ enumerable: false, // never appear in spreads / JSON / for-in
49
+ writable: false,
50
+ configurable: true, // configurable so tests and hot-reload can redefine
51
+ });
52
+ };
53
+ }
54
+ /**
55
+ * True iff `target` itself is marked `@OptionalKeyedSpecialization()`.
56
+ *
57
+ * Accepts either a class (constructor) or an instance. OWN-property check — a subclass of a
58
+ * marked base returns `false`, mirroring `ClassRequiresSubclass`.
59
+ */
60
+ export function ClassIsOptionalKeyedSpecialization(target) {
61
+ if (target == null) {
62
+ return false;
63
+ }
64
+ const proto = typeof target === 'function'
65
+ ? target.prototype
66
+ : Object.getPrototypeOf(target);
67
+ return !!proto
68
+ && Object.prototype.hasOwnProperty.call(proto, OPTIONAL_KEYED_SPECIALIZATION_KEY)
69
+ && proto[OPTIONAL_KEYED_SPECIALIZATION_KEY] === true;
70
+ }
71
+ //# sourceMappingURL=OptionalKeyedSpecialization.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OptionalKeyedSpecialization.js","sourceRoot":"","sources":["../src/OptionalKeyedSpecialization.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AAEH;;;GAGG;AACH,MAAM,CAAC,MAAM,iCAAiC,GAAG,kCAAkC,CAAC;AAEpF;;;GAGG;AACH,MAAM,UAAU,2BAA2B;IACvC,OAAO,UAAU,WAAqB;QAClC,MAAM,CAAC,cAAc,CAAC,WAAW,CAAC,SAAS,EAAE,iCAAiC,EAAE;YAC5E,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,KAAK,EAAI,0CAA0C;YAC/D,QAAQ,EAAE,KAAK;YACf,YAAY,EAAE,IAAI,EAAG,oDAAoD;SAC5E,CAAC,CAAC;IACP,CAAC,CAAC;AACN,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kCAAkC,CAAC,MAAe;IAC9D,IAAI,MAAM,IAAI,IAAI,EAAE,CAAC;QACjB,OAAO,KAAK,CAAC;IACjB,CAAC;IACD,MAAM,KAAK,GAAG,OAAO,MAAM,KAAK,UAAU;QACtC,CAAC,CAAE,MAAiC,CAAC,SAAS;QAC9C,CAAC,CAAC,MAAM,CAAC,cAAc,CAAC,MAAgB,CAAC,CAAC;IAE9C,OAAO,CAAC,CAAC,KAAK;WACP,MAAM,CAAC,SAAS,CAAC,cAAc,CAAC,IAAI,CAAC,KAAK,EAAE,iCAAiC,CAAC;WAC7E,KAAiC,CAAC,iCAAiC,CAAC,KAAK,IAAI,CAAC;AAC1F,CAAC"}