@primafuture/contrib-kit-react 1.0.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.
Files changed (128) hide show
  1. package/LICENSE +15 -0
  2. package/README.md +294 -0
  3. package/dist/contribution-component.d.ts +82 -0
  4. package/dist/contribution-component.d.ts.map +1 -0
  5. package/dist/contribution-component.js +12 -0
  6. package/dist/contribution-component.js.map +1 -0
  7. package/dist/extension-outlet.d.ts +155 -0
  8. package/dist/extension-outlet.d.ts.map +1 -0
  9. package/dist/extension-outlet.js +229 -0
  10. package/dist/extension-outlet.js.map +1 -0
  11. package/dist/extension-registry-provider.d.ts +26 -0
  12. package/dist/extension-registry-provider.d.ts.map +1 -0
  13. package/dist/extension-registry-provider.js +82 -0
  14. package/dist/extension-registry-provider.js.map +1 -0
  15. package/dist/index.d.ts +22 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +14 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/internal/adapter-configuration.d.ts +54 -0
  20. package/dist/internal/adapter-configuration.d.ts.map +1 -0
  21. package/dist/internal/adapter-configuration.js +89 -0
  22. package/dist/internal/adapter-configuration.js.map +1 -0
  23. package/dist/internal/adapter-context.d.ts +24 -0
  24. package/dist/internal/adapter-context.d.ts.map +1 -0
  25. package/dist/internal/adapter-context.js +23 -0
  26. package/dist/internal/adapter-context.js.map +1 -0
  27. package/dist/internal/adapter-registry-bridge.d.ts +58 -0
  28. package/dist/internal/adapter-registry-bridge.d.ts.map +1 -0
  29. package/dist/internal/adapter-registry-bridge.js +494 -0
  30. package/dist/internal/adapter-registry-bridge.js.map +1 -0
  31. package/dist/internal/adapter-registry-protocol.d.ts +53 -0
  32. package/dist/internal/adapter-registry-protocol.d.ts.map +1 -0
  33. package/dist/internal/adapter-registry-protocol.js +182 -0
  34. package/dist/internal/adapter-registry-protocol.js.map +1 -0
  35. package/dist/internal/adapter-scope.d.ts +87 -0
  36. package/dist/internal/adapter-scope.d.ts.map +1 -0
  37. package/dist/internal/adapter-scope.js +346 -0
  38. package/dist/internal/adapter-scope.js.map +1 -0
  39. package/dist/internal/implementation-classifier.d.ts +21 -0
  40. package/dist/internal/implementation-classifier.d.ts.map +1 -0
  41. package/dist/internal/implementation-classifier.js +39 -0
  42. package/dist/internal/implementation-classifier.js.map +1 -0
  43. package/dist/internal/managed-lazy-generation.d.ts +100 -0
  44. package/dist/internal/managed-lazy-generation.d.ts.map +1 -0
  45. package/dist/internal/managed-lazy-generation.js +419 -0
  46. package/dist/internal/managed-lazy-generation.js.map +1 -0
  47. package/dist/internal/outlet-commit-lease.d.ts +46 -0
  48. package/dist/internal/outlet-commit-lease.d.ts.map +1 -0
  49. package/dist/internal/outlet-commit-lease.js +137 -0
  50. package/dist/internal/outlet-commit-lease.js.map +1 -0
  51. package/dist/internal/outlet-error-pipeline.d.ts +122 -0
  52. package/dist/internal/outlet-error-pipeline.d.ts.map +1 -0
  53. package/dist/internal/outlet-error-pipeline.js +214 -0
  54. package/dist/internal/outlet-error-pipeline.js.map +1 -0
  55. package/dist/internal/outlet-input.d.ts +42 -0
  56. package/dist/internal/outlet-input.d.ts.map +1 -0
  57. package/dist/internal/outlet-input.js +86 -0
  58. package/dist/internal/outlet-input.js.map +1 -0
  59. package/dist/internal/outlet-membership-boundary.d.ts +93 -0
  60. package/dist/internal/outlet-membership-boundary.d.ts.map +1 -0
  61. package/dist/internal/outlet-membership-boundary.js +710 -0
  62. package/dist/internal/outlet-membership-boundary.js.map +1 -0
  63. package/dist/internal/outlet-membership.d.ts +31 -0
  64. package/dist/internal/outlet-membership.d.ts.map +1 -0
  65. package/dist/internal/outlet-membership.js +65 -0
  66. package/dist/internal/outlet-membership.js.map +1 -0
  67. package/dist/internal/outlet-projection.d.ts +102 -0
  68. package/dist/internal/outlet-projection.d.ts.map +1 -0
  69. package/dist/internal/outlet-projection.js +228 -0
  70. package/dist/internal/outlet-projection.js.map +1 -0
  71. package/dist/internal/outlet-reporter-boundary.d.ts +42 -0
  72. package/dist/internal/outlet-reporter-boundary.d.ts.map +1 -0
  73. package/dist/internal/outlet-reporter-boundary.js +57 -0
  74. package/dist/internal/outlet-reporter-boundary.js.map +1 -0
  75. package/dist/internal/public-input-capture.d.ts +13 -0
  76. package/dist/internal/public-input-capture.d.ts.map +1 -0
  77. package/dist/internal/public-input-capture.js +34 -0
  78. package/dist/internal/public-input-capture.js.map +1 -0
  79. package/dist/internal/resolved-contributions-query.d.ts +42 -0
  80. package/dist/internal/resolved-contributions-query.d.ts.map +1 -0
  81. package/dist/internal/resolved-contributions-query.js +203 -0
  82. package/dist/internal/resolved-contributions-query.js.map +1 -0
  83. package/dist/react-adapter-diagnostics.d.ts +199 -0
  84. package/dist/react-adapter-diagnostics.d.ts.map +1 -0
  85. package/dist/react-adapter-diagnostics.js +257 -0
  86. package/dist/react-adapter-diagnostics.js.map +1 -0
  87. package/dist/react-adapter-error.d.ts +35 -0
  88. package/dist/react-adapter-error.d.ts.map +1 -0
  89. package/dist/react-adapter-error.js +37 -0
  90. package/dist/react-adapter-error.js.map +1 -0
  91. package/dist/react-extension-point.d.ts +26 -0
  92. package/dist/react-extension-point.d.ts.map +1 -0
  93. package/dist/react-extension-point.js +100 -0
  94. package/dist/react-extension-point.js.map +1 -0
  95. package/dist/react-lazy-contribution.d.ts +40 -0
  96. package/dist/react-lazy-contribution.d.ts.map +1 -0
  97. package/dist/react-lazy-contribution.js +18 -0
  98. package/dist/react-lazy-contribution.js.map +1 -0
  99. package/dist/resolved-contributions.d.ts +90 -0
  100. package/dist/resolved-contributions.d.ts.map +1 -0
  101. package/dist/resolved-contributions.js +455 -0
  102. package/dist/resolved-contributions.js.map +1 -0
  103. package/package.json +47 -0
  104. package/src/contribution-component.ts +118 -0
  105. package/src/extension-outlet.ts +590 -0
  106. package/src/extension-registry-provider.ts +179 -0
  107. package/src/index.ts +72 -0
  108. package/src/internal/adapter-configuration.ts +181 -0
  109. package/src/internal/adapter-context.ts +43 -0
  110. package/src/internal/adapter-registry-bridge.ts +723 -0
  111. package/src/internal/adapter-registry-protocol.ts +365 -0
  112. package/src/internal/adapter-scope.ts +500 -0
  113. package/src/internal/implementation-classifier.ts +59 -0
  114. package/src/internal/managed-lazy-generation.ts +540 -0
  115. package/src/internal/outlet-commit-lease.ts +216 -0
  116. package/src/internal/outlet-error-pipeline.ts +447 -0
  117. package/src/internal/outlet-input.ts +264 -0
  118. package/src/internal/outlet-membership-boundary.ts +1048 -0
  119. package/src/internal/outlet-membership.ts +125 -0
  120. package/src/internal/outlet-projection.ts +511 -0
  121. package/src/internal/outlet-reporter-boundary.ts +105 -0
  122. package/src/internal/public-input-capture.ts +55 -0
  123. package/src/internal/resolved-contributions-query.ts +318 -0
  124. package/src/react-adapter-diagnostics.ts +457 -0
  125. package/src/react-adapter-error.ts +88 -0
  126. package/src/react-extension-point.ts +181 -0
  127. package/src/react-lazy-contribution.ts +66 -0
  128. package/src/resolved-contributions.ts +895 -0
@@ -0,0 +1,457 @@
1
+ import * as contribKitCore from "@primafuture/contrib-kit-core";
2
+
3
+ import * as adapterConfiguration from "./internal/adapter-configuration.js";
4
+ import * as reactAdapterError from "./react-adapter-error.js";
5
+ import type * as reactExtensionPoint from "./react-extension-point.js";
6
+
7
+ /** Přesné Core kódy, které smí adapter zveřejnit jako bezpečný string. */
8
+ const coreErrorCodes = new Set<contribKitCore.ContribKitErrorCode>([
9
+ "INVALID_ARGUMENT",
10
+ "INVALID_POINT_ID",
11
+ "INVALID_CONTRIBUTION_ID",
12
+ "INVALID_CONTRACT_VERSION",
13
+ "INVALID_CARDINALITY",
14
+ "INVALID_POLICY",
15
+ "FORGED_EXTENSION_POINT",
16
+ "FOREIGN_CORE_RUNTIME_POINT",
17
+ "POINT_ALREADY_REGISTERED",
18
+ "POINT_ID_COLLISION",
19
+ "POINT_NOT_REGISTERED",
20
+ "POINT_CLOSING",
21
+ "POINT_CLOSED",
22
+ "POINT_CONTRACT_VERSION_MISMATCH",
23
+ "REGISTRY_DISPOSING",
24
+ "REGISTRY_DISPOSED",
25
+ "OWNER_SCOPE_DISPOSING",
26
+ "OWNER_SCOPE_DISPOSED",
27
+ "CONTRIBUTION_ID_COLLISION",
28
+ "POINT_CARDINALITY_EXCEEDED",
29
+ "CONTRIBUTION_DATA_INVALID",
30
+ "CONTRIBUTION_IMPLEMENTATION_INVALID",
31
+ "CONTEXT_INVALID",
32
+ "REGISTRATION_CANCELLED",
33
+ "REGISTRATION_PREPARE_FAILED",
34
+ "REGISTRATION_PREPARE_TIMEOUT",
35
+ "REPLACEMENT_TARGET_NOT_FOUND",
36
+ "REPLACEMENT_TARGET_STALE",
37
+ "ORDERING_POLICY_FAILED",
38
+ "ORDERING_RESULT_INVALID",
39
+ "FILTER_POLICY_FAILED",
40
+ "SELECTION_POLICY_FAILED",
41
+ "SELECTION_RESULT_INVALID",
42
+ "CLEANUP_FAILED",
43
+ "CLEANUP_TIMEOUT",
44
+ "HOT_KEY_COLLISION",
45
+ "INCOMPATIBLE_HOT_UPDATE",
46
+ ]);
47
+
48
+ /** Stabilní seznam adapter fází přijímaných z vlastní bezpečné chyby. */
49
+ const reactAdapterErrorPhases = new Set<reactAdapterError.ReactAdapterErrorPhase>([
50
+ "configuration",
51
+ "resolve",
52
+ "load",
53
+ "render",
54
+ "customRender",
55
+ "fallback",
56
+ "policy",
57
+ "projection",
58
+ "callback",
59
+ "lifecycle",
60
+ ]);
61
+
62
+ /**
63
+ * Bezpečná metadata jedné aktivní Core registrace bez business hodnot.
64
+ *
65
+ * @public
66
+ */
67
+ export interface ReadonlyContributionMetadata {
68
+ /** Stabilní contribution identita uvnitř pointu. */
69
+ readonly contributionId: string;
70
+ /** Volitelná identita přispívajícího modulu. */
71
+ readonly contributorId?: string;
72
+ /** Volitelný lidsky čitelný label. */
73
+ readonly label?: string;
74
+ /** Volitelný lokální název pro diagnostiku. */
75
+ readonly localName?: string;
76
+ /** Opaque identita konkrétní Core activation. */
77
+ readonly registrationId: string;
78
+ }
79
+
80
+ /**
81
+ * Bezpečná public metadata extension pointu bez runtime capabilities.
82
+ *
83
+ * @public
84
+ */
85
+ export interface ReadonlyPointMetadata {
86
+ /** Cardinalita katalogu daného pointu. */
87
+ readonly cardinality: "single" | "many";
88
+ /** Contract verze diagnostikované generation. */
89
+ readonly contractVersion: number;
90
+ /** Volitelný lidsky čitelný label. */
91
+ readonly label?: string;
92
+ /** Volitelný lokální název pro diagnostiku. */
93
+ readonly localName?: string;
94
+ /** Volitelná stabilní identita vlastníka pointu. */
95
+ readonly ownerId?: string;
96
+ /** Veřejná logická identita pointu. */
97
+ readonly pointId: string;
98
+ }
99
+
100
+ /**
101
+ * Frozen strukturovaná chyba určená host sinku a budoucí outlet policy.
102
+ *
103
+ * @public
104
+ */
105
+ export interface ReactAdapterErrorEvent {
106
+ /** Opaque identita budoucí contribution boundary. */
107
+ readonly boundaryId?: string;
108
+ /** Přesný zachycený throwable nebo bezpečná syntetická chyba. */
109
+ readonly cause: unknown;
110
+ /** Stabilní adapterová klasifikace. */
111
+ readonly code: import("./react-adapter-error.js").ReactAdapterErrorCode;
112
+ /** Hostem výslovně projektovaný bezpečný context fragment. */
113
+ readonly contextProjection?: unknown;
114
+ /** Volitelná bezpečná metadata příslušné contribution. */
115
+ readonly contribution?: ReadonlyContributionMetadata;
116
+ /** Volitelný původní Core code bez přenosu Core error objektu. */
117
+ readonly coreCode?: string;
118
+ /** Opaque identita budoucí outlet instance. */
119
+ readonly outletId?: string;
120
+ /** Fáze adapter pipeline, ve které chyba vznikla. */
121
+ readonly phase: import("./react-adapter-error.js").ReactAdapterErrorPhase;
122
+ /** Volitelná bezpečná metadata příslušného pointu. */
123
+ readonly point?: ReadonlyPointMetadata;
124
+ /** Normalizovaný React component stack budoucí boundary. */
125
+ readonly reactComponentStack?: string;
126
+ /** Retry generation budoucí contribution boundary. */
127
+ readonly retryGeneration?: number;
128
+ }
129
+
130
+ /**
131
+ * Command-free event doručovaný best-effort diagnostickému sinku.
132
+ *
133
+ * @public
134
+ */
135
+ export type ReactAdapterDiagnosticEvent =
136
+ | {
137
+ /** Rozlišuje strukturovanou chybu od late loader výsledku. */
138
+ readonly kind: "error";
139
+ /** Stejný frozen error event, který nese veřejný failed state. */
140
+ readonly error: ReactAdapterErrorEvent;
141
+ }
142
+ | {
143
+ /** Rozlišuje pozdní settlement budoucí managed-lazy generace. */
144
+ readonly kind: "lateLazyResult";
145
+ /** Opaque identita ukončené boundary. */
146
+ readonly boundaryId: string;
147
+ /** Bezpečná metadata contribution vlastnící loader. */
148
+ readonly contribution: ReadonlyContributionMetadata;
149
+ /** Druh pozdního settlementu. */
150
+ readonly outcome: "resolved" | "rejected";
151
+ /** Opaque identita outletu vlastnícího boundary. */
152
+ readonly outletId: string;
153
+ /** Volitelná bezpečná metadata pointu. */
154
+ readonly point?: ReadonlyPointMetadata;
155
+ /** Generation, které settlement původně patřil. */
156
+ readonly retryGeneration: number;
157
+ };
158
+
159
+ /** Interní bezpečný vstup jednoho managed-lazy late-result eventu. */
160
+ export interface ReactLateLazyResultDiagnosticInput {
161
+ /** Opaque committed boundary identita původního attemptu. */
162
+ readonly boundaryId: string;
163
+ /** Již projektovaná metadata bez contribution dat nebo implementation. */
164
+ readonly contribution: ReadonlyContributionMetadata;
165
+ /** Rozlišuje fulfillment od rejection bez přenosu business hodnoty či cause. */
166
+ readonly outcome: "resolved" | "rejected";
167
+ /** Opaque committed outlet identita původního attemptu. */
168
+ readonly outletId: string;
169
+ /** Volitelná bezpečná point metadata bez runtime capability. */
170
+ readonly point?: ReadonlyPointMetadata;
171
+ /** Retry generation, ve které loader skutečně začal. */
172
+ readonly retryGeneration: number;
173
+ }
174
+
175
+ /**
176
+ * Non-blocking best-effort cíl adapter diagnostiky.
177
+ *
178
+ * @public
179
+ */
180
+ export interface ReactAdapterSink {
181
+ /** Přijme jeden frozen event; adapter návrat nikdy neawaituje. */
182
+ readonly report: (event: ReactAdapterDiagnosticEvent) => void | Promise<void>;
183
+ }
184
+
185
+ /**
186
+ * Výsledek synchronní budoucí contribution error policy.
187
+ *
188
+ * @public
189
+ */
190
+ export type ReactErrorAction = "hide" | "renderFallback" | "escalate";
191
+
192
+ /**
193
+ * Host policy rozhodující o budoucí izolaci contribution render chyby.
194
+ *
195
+ * @public
196
+ */
197
+ export type ReactErrorPolicy = (error: ReactAdapterErrorEvent) => ReactErrorAction;
198
+
199
+ /** Vstup bezpečného public error eventu bez raw registry nebo business hodnot. */
200
+ export interface ReactAdapterErrorEventInput {
201
+ /** Opaque identita contribution boundary. */
202
+ readonly boundaryId?: string;
203
+ /** Stabilní adapterový code. */
204
+ readonly code: reactAdapterError.ReactAdapterErrorCode;
205
+ /** Přesný zachycený nebo syntetický cause. */
206
+ readonly cause: unknown;
207
+ /** Bezpečná metadata contribution bez business dat. */
208
+ readonly contribution?: ReadonlyContributionMetadata;
209
+ /** Fáze adapter pipeline. */
210
+ readonly phase: reactAdapterError.ReactAdapterErrorPhase;
211
+ /** Bezpečný původní Core code. */
212
+ readonly coreCode?: string;
213
+ /** Opaque identita outlet instance. */
214
+ readonly outletId?: string;
215
+ /** Bezpečná metadata pointu. */
216
+ readonly point?: ReadonlyPointMetadata;
217
+ /** Normalizovaný React component stack. */
218
+ readonly reactComponentStack?: string;
219
+ /** Monotonická retry generation contribution boundary. */
220
+ readonly retryGeneration?: number;
221
+ /** Hostem projektovaný context. */
222
+ readonly contextProjection?: unknown;
223
+ /** Rozlišuje projekci hodnoty undefined od absence projekce. */
224
+ readonly hasContextProjection?: boolean;
225
+ }
226
+
227
+ /**
228
+ * Přečte bezpečný Core code i z cizí fyzické Core runtime bez úniku accessor chyby.
229
+ */
230
+ export function readCoreErrorCode(cause: unknown): contribKitCore.ContribKitErrorCode | undefined {
231
+ if (cause instanceof contribKitCore.ContribKitError) {
232
+ return cause.code;
233
+ }
234
+ if (typeof cause !== "object" || cause === null) {
235
+ return undefined;
236
+ }
237
+
238
+ try {
239
+ const code = Reflect.get(cause, "code", cause) as unknown;
240
+ return typeof code === "string" && coreErrorCodes.has(code as contribKitCore.ContribKitErrorCode)
241
+ ? code as contribKitCore.ContribKitErrorCode
242
+ : undefined;
243
+ } catch {
244
+ return undefined;
245
+ }
246
+ }
247
+
248
+ /**
249
+ * Odvodí závazný React code z adapter chyby nebo bezpečné Core klasifikace.
250
+ */
251
+ export function resolveReactErrorCode(
252
+ cause: unknown,
253
+ coreCode: contribKitCore.ContribKitErrorCode | undefined,
254
+ ): reactAdapterError.ReactAdapterErrorCode {
255
+ if (cause instanceof reactAdapterError.ReactAdapterError) {
256
+ return cause.code;
257
+ }
258
+ if (coreCode === "POINT_NOT_REGISTERED"
259
+ || coreCode === "POINT_CLOSING"
260
+ || coreCode === "POINT_CLOSED") {
261
+ return "REACT_POINT_UNAVAILABLE";
262
+ }
263
+ if (coreCode === "REGISTRY_DISPOSING" || coreCode === "REGISTRY_DISPOSED") {
264
+ return "REACT_REGISTRY_UNAVAILABLE";
265
+ }
266
+
267
+ return "REACT_RESOLVE_FAILED";
268
+ }
269
+
270
+ /**
271
+ * Zachová bezpečnou adapter phase, ostatní query failures zařadí do resolve.
272
+ */
273
+ export function resolveReactErrorPhase(
274
+ cause: unknown,
275
+ ): reactAdapterError.ReactAdapterErrorPhase {
276
+ if (cause instanceof reactAdapterError.ReactAdapterError) {
277
+ const phase = cause.details.phase;
278
+ if (typeof phase === "string"
279
+ && reactAdapterErrorPhases.has(phase as reactAdapterError.ReactAdapterErrorPhase)) {
280
+ return phase as reactAdapterError.ReactAdapterErrorPhase;
281
+ }
282
+ }
283
+
284
+ return "resolve";
285
+ }
286
+
287
+ /**
288
+ * Projektuje pouze známá scalar point metadata a při getter failure raději nic.
289
+ */
290
+ export function createPointMetadata(
291
+ point: reactExtensionPoint.AnyReactExtensionPoint | undefined,
292
+ ): ReadonlyPointMetadata | undefined {
293
+ if (point === undefined) {
294
+ return undefined;
295
+ }
296
+
297
+ try {
298
+ const pointId = point.pointId;
299
+ const contractVersion = point.contractVersion;
300
+ const cardinality = point.cardinality;
301
+ const ownerId = point.ownerId;
302
+ const localName = point.localName;
303
+ const label = point.label;
304
+ if (typeof pointId !== "string"
305
+ || pointId.length === 0
306
+ || typeof contractVersion !== "number"
307
+ || !Number.isSafeInteger(contractVersion)
308
+ || contractVersion < 1
309
+ || (cardinality !== "single" && cardinality !== "many")
310
+ || (ownerId !== undefined && typeof ownerId !== "string")
311
+ || (localName !== undefined && typeof localName !== "string")
312
+ || (label !== undefined && typeof label !== "string")) {
313
+ return undefined;
314
+ }
315
+ return Object.freeze({
316
+ pointId,
317
+ contractVersion,
318
+ cardinality,
319
+ ...(ownerId === undefined ? {} : { ownerId }),
320
+ ...(localName === undefined ? {} : { localName }),
321
+ ...(label === undefined ? {} : { label }),
322
+ });
323
+ } catch {
324
+ return undefined;
325
+ }
326
+ }
327
+
328
+ /**
329
+ * Projektuje contribution metadata bez jediného čtení dat nebo implementation.
330
+ */
331
+ export function createContributionMetadata<Point extends contribKitCore.AnyExtensionPoint>(
332
+ contribution: contribKitCore.RegisteredContribution<Point> | undefined,
333
+ ): ReadonlyContributionMetadata | undefined {
334
+ if (contribution === undefined) {
335
+ return undefined;
336
+ }
337
+
338
+ try {
339
+ const registrationId = contribution.registrationId;
340
+ const contributionId = contribution.contributionId;
341
+ const contributorId = contribution.contributorId;
342
+ const localName = contribution.localName;
343
+ const label = contribution.label;
344
+ return Object.freeze({
345
+ registrationId,
346
+ contributionId,
347
+ ...(contributorId === undefined ? {} : { contributorId }),
348
+ ...(localName === undefined ? {} : { localName }),
349
+ ...(label === undefined ? {} : { label }),
350
+ });
351
+ } catch {
352
+ return undefined;
353
+ }
354
+ }
355
+
356
+ /**
357
+ * Vytvoří shallow-frozen veřejný event bez raw contextu nebo registry capability.
358
+ */
359
+ export function createReactAdapterErrorEvent(
360
+ input: ReactAdapterErrorEventInput,
361
+ ): ReactAdapterErrorEvent {
362
+ return Object.freeze({
363
+ code: input.code,
364
+ phase: input.phase,
365
+ cause: input.cause,
366
+ ...(input.boundaryId === undefined ? {} : { boundaryId: input.boundaryId }),
367
+ ...(input.contribution === undefined ? {} : { contribution: input.contribution }),
368
+ ...(input.coreCode === undefined ? {} : { coreCode: input.coreCode }),
369
+ ...(input.outletId === undefined ? {} : { outletId: input.outletId }),
370
+ ...(input.point === undefined ? {} : { point: input.point }),
371
+ ...(input.reactComponentStack === undefined
372
+ ? {}
373
+ : { reactComponentStack: input.reactComponentStack }),
374
+ ...(input.retryGeneration === undefined
375
+ ? {}
376
+ : { retryGeneration: input.retryGeneration }),
377
+ ...(input.hasContextProjection === true
378
+ ? { contextProjection: input.contextProjection }
379
+ : {}),
380
+ });
381
+ }
382
+
383
+ /**
384
+ * Zabalí veřejnou chybu do frozen diagnostic union větve.
385
+ */
386
+ export function createErrorDiagnostic(
387
+ error: ReactAdapterErrorEvent,
388
+ ): ReactAdapterDiagnosticEvent {
389
+ return Object.freeze({ kind: "error", error });
390
+ }
391
+
392
+ /**
393
+ * Vytvoří frozen late-result event bez raw settlement hodnoty, cause nebo contextu.
394
+ */
395
+ export function createLateLazyResultDiagnostic(
396
+ input: ReactLateLazyResultDiagnosticInput,
397
+ ): ReactAdapterDiagnosticEvent {
398
+ return Object.freeze({
399
+ kind: "lateLazyResult",
400
+ boundaryId: input.boundaryId,
401
+ contribution: input.contribution,
402
+ outcome: input.outcome,
403
+ outletId: input.outletId,
404
+ ...(input.point === undefined ? {} : { point: input.point }),
405
+ retryGeneration: input.retryGeneration,
406
+ });
407
+ }
408
+
409
+ /**
410
+ * Pohltí Promise, cizí thenable i jejich pozdní rejection bez diagnostické rekurze.
411
+ */
412
+ export function normalizeSinkResult(result: unknown): void {
413
+ try {
414
+ /** Sink rejection nemá business ani další diagnostickou autoritu. */
415
+ function ignoreSinkRejection(): void {
416
+ // Best-effort sink záměrně končí bez dalšího eventu.
417
+ }
418
+ void Promise.resolve(result).catch(ignoreSinkRejection);
419
+ } catch {
420
+ // Throwing then getter nesmí opustit diagnostickou hranici.
421
+ }
422
+ }
423
+
424
+ /**
425
+ * Doručí command-free diagnostiku custom sinku nebo bezpečnému console fallbacku.
426
+ */
427
+ export function reportReactAdapterDiagnostic(
428
+ event: ReactAdapterDiagnosticEvent,
429
+ configuration: adapterConfiguration.AdapterScopeConfiguration,
430
+ development = true,
431
+ ): void {
432
+ if (configuration.sink !== undefined) {
433
+ try {
434
+ normalizeSinkResult(adapterConfiguration.callCapturedReactAdapterSink(
435
+ configuration.sink,
436
+ event,
437
+ ));
438
+ } catch {
439
+ // Sync sink throw nesmí změnit committed React stav.
440
+ }
441
+ return;
442
+ }
443
+ if (event.kind !== "error" && !development) {
444
+ return;
445
+ }
446
+
447
+ try {
448
+ const consoleReceiver = globalThis.console;
449
+ const method = event.kind === "error" ? "error" : "warn";
450
+ const report = Reflect.get(consoleReceiver, method, consoleReceiver) as unknown;
451
+ if (typeof report === "function") {
452
+ normalizeSinkResult(Reflect.apply(report, consoleReceiver, [event]));
453
+ }
454
+ } catch {
455
+ // Chybějící nebo rozbitý console fallback je bezpečný no-op.
456
+ }
457
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Stable public code for expected React adapter errors.
3
+ *
4
+ * @public
5
+ */
6
+ export type ReactAdapterErrorCode =
7
+ | "REACT_INVALID_ARGUMENT"
8
+ | "REACT_REGISTRY_NOT_PROVIDED"
9
+ | "REACT_REGISTRY_INVALID"
10
+ | "REACT_REGISTRY_UNAVAILABLE"
11
+ | "REACT_ADAPTER_DISPOSED"
12
+ | "REACT_POINT_IMPLEMENTATION_INVALID"
13
+ | "REACT_POINT_UNAVAILABLE"
14
+ | "REACT_RESOLVE_FAILED"
15
+ | "REACT_LAZY_LOAD_FAILED"
16
+ | "REACT_RENDER_FAILED"
17
+ | "REACT_ERROR_POLICY_FAILED"
18
+ | "REACT_CONTEXT_PROJECTION_FAILED"
19
+ | "REACT_CALLBACK_FAILED";
20
+
21
+ /**
22
+ * Stable phase in which the React adapter captured an error.
23
+ *
24
+ * @public
25
+ */
26
+ export type ReactAdapterErrorPhase =
27
+ | "configuration"
28
+ | "resolve"
29
+ | "load"
30
+ | "render"
31
+ | "customRender"
32
+ | "fallback"
33
+ | "policy"
34
+ | "projection"
35
+ | "callback"
36
+ | "lifecycle";
37
+
38
+ /**
39
+ * Vytvoří vlastní shallow-frozen kopii bezpečných detailů chyby.
40
+ */
41
+ function copyErrorDetails(
42
+ details: Readonly<Record<string, unknown>> | undefined,
43
+ ): Readonly<Record<string, unknown>> {
44
+ return Object.freeze(details === undefined ? {} : { ...details });
45
+ }
46
+
47
+ /**
48
+ * Stable public React adapter error with safe immutable details.
49
+ *
50
+ * @public
51
+ */
52
+ export class ReactAdapterError extends Error {
53
+ /** Machine-readable classification of the adapter error. */
54
+ public readonly code: ReactAdapterErrorCode;
55
+
56
+ /** Shallow-frozen safe metadata without raw contribution values. */
57
+ public readonly details: Readonly<Record<string, unknown>>;
58
+
59
+ /** Original throwable preserved when wrapping a foreign error. */
60
+ public override readonly cause?: unknown;
61
+
62
+ /**
63
+ * Creates a public error with a stable code and its own copy of details.
64
+ */
65
+ public constructor(
66
+ code: ReactAdapterErrorCode,
67
+ message: string,
68
+ options?: {
69
+ /** Original throwable that caused the stable wrapper. */
70
+ readonly cause?: unknown;
71
+ /** Safe scalar metadata for the specific failure phase. */
72
+ readonly details?: Readonly<Record<string, unknown>>;
73
+ },
74
+ ) {
75
+ super(message);
76
+ this.name = "ReactAdapterError";
77
+ this.code = code;
78
+ this.details = copyErrorDetails(options?.details);
79
+ if (options !== undefined && Object.hasOwn(options, "cause")) {
80
+ Object.defineProperty(this, "cause", {
81
+ configurable: true,
82
+ enumerable: false,
83
+ value: options.cause,
84
+ writable: false,
85
+ });
86
+ }
87
+ }
88
+ }