@kosdev-code/kos-ui-plugin 2.1.17 → 2.1.19

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (58) hide show
  1. package/documentation-generator-CAlVz5vA.cjs +266 -0
  2. package/documentation-generator-CAlVz5vA.cjs.map +1 -0
  3. package/documentation-generator-Di4c9D9P.js +2337 -0
  4. package/documentation-generator-Di4c9D9P.js.map +1 -0
  5. package/index.cjs +69 -69
  6. package/index.cjs.map +1 -1
  7. package/index.d.ts +1 -0
  8. package/index.d.ts.map +1 -1
  9. package/index.js +817 -753
  10. package/index.js.map +1 -1
  11. package/lib/components/dynamic-component/dynamic-component.d.ts +69 -0
  12. package/lib/components/dynamic-component/dynamic-component.d.ts.map +1 -1
  13. package/lib/contexts/index.d.ts +1 -0
  14. package/lib/contexts/index.d.ts.map +1 -1
  15. package/lib/contexts/plugins-provider/plugins-provider.d.ts.map +1 -1
  16. package/lib/contexts/reactive-extension-registry-context.d.ts +10 -0
  17. package/lib/contexts/reactive-extension-registry-context.d.ts.map +1 -0
  18. package/lib/hooks/index.d.ts +4 -2
  19. package/lib/hooks/index.d.ts.map +1 -1
  20. package/lib/hooks/use-dynamic-component.d.ts +12 -1
  21. package/lib/hooks/use-dynamic-component.d.ts.map +1 -1
  22. package/lib/hooks/use-extension-point.d.ts +95 -0
  23. package/lib/hooks/use-extension-point.d.ts.map +1 -0
  24. package/lib/hooks/use-reactive-extension-registry.d.ts +20 -0
  25. package/lib/hooks/use-reactive-extension-registry.d.ts.map +1 -0
  26. package/lib/hooks/use-typed-extensions.d.ts.map +1 -1
  27. package/lib/utils/contribution-registry.d.ts +170 -0
  28. package/lib/utils/contribution-registry.d.ts.map +1 -0
  29. package/lib/utils/extension-points/extension-point-registry.d.ts.map +1 -1
  30. package/lib/utils/extension-points/extension-point-schemas.d.ts +4 -4
  31. package/lib/utils/index.d.ts +3 -0
  32. package/lib/utils/index.d.ts.map +1 -1
  33. package/lib/utils/plugin-system/plugin-extension-manager.d.ts.map +1 -1
  34. package/lib/utils/processors/initialize-plugins.d.ts.map +1 -1
  35. package/lib/utils/reactive-extension-registry.d.ts +140 -0
  36. package/lib/utils/reactive-extension-registry.d.ts.map +1 -0
  37. package/lib/webpack/index.d.ts +2 -0
  38. package/lib/webpack/index.d.ts.map +1 -1
  39. package/lib/webpack/with-plugin-dev-aggregator.d.ts +94 -0
  40. package/lib/webpack/with-plugin-dev-aggregator.d.ts.map +1 -0
  41. package/lib/webpack/with-plugin-dev-server.d.ts +113 -0
  42. package/lib/webpack/with-plugin-dev-server.d.ts.map +1 -0
  43. package/package.json +2 -2
  44. package/types/contribution-enablement.d.ts +293 -0
  45. package/types/contribution-enablement.d.ts.map +1 -0
  46. package/types/plugins.d.ts +8 -0
  47. package/utils.cjs +1 -1
  48. package/utils.cjs.map +1 -1
  49. package/utils.js +29 -291
  50. package/utils.js.map +1 -1
  51. package/webpack.cjs +3 -12
  52. package/webpack.cjs.map +1 -1
  53. package/webpack.js +455 -727
  54. package/webpack.js.map +1 -1
  55. package/documentation-generator-DFaIDo0E.cjs +0 -266
  56. package/documentation-generator-DFaIDo0E.cjs.map +0 -1
  57. package/documentation-generator-auruIa_o.js +0 -1560
  58. package/documentation-generator-auruIa_o.js.map +0 -1
@@ -0,0 +1,2337 @@
1
+ var X = Object.defineProperty;
2
+ var ee = (n, e, t) => e in n ? X(n, e, { enumerable: !0, configurable: !0, writable: !0, value: t }) : n[e] = t;
3
+ var v = (n, e, t) => (ee(n, typeof e != "symbol" ? e + "" : e, t), t);
4
+ import { z as V } from "zod";
5
+ function te(n, e) {
6
+ for (var t = 0; t < e.length; t++) {
7
+ const i = e[t];
8
+ if (typeof i != "string" && !Array.isArray(i)) {
9
+ for (const s in i)
10
+ if (s !== "default" && !(s in n)) {
11
+ const o = Object.getOwnPropertyDescriptor(i, s);
12
+ o && Object.defineProperty(n, s, o.get ? o : {
13
+ enumerable: !0,
14
+ get: () => i[s]
15
+ });
16
+ }
17
+ }
18
+ }
19
+ return Object.freeze(Object.defineProperty(n, Symbol.toStringTag, { value: "Module" }));
20
+ }
21
+ var A = {}, R = {};
22
+ Object.defineProperty(R, "__esModule", { value: !0 });
23
+ R.loadRemoteModule = R.setRemoteDefinitions = R.setRemoteUrlResolver = void 0;
24
+ let T, j;
25
+ const O = /* @__PURE__ */ new Map(), K = /* @__PURE__ */ new Map();
26
+ let B = !1;
27
+ function ne(n) {
28
+ j = n;
29
+ }
30
+ R.setRemoteUrlResolver = ne;
31
+ function ie(n) {
32
+ T = n;
33
+ }
34
+ R.setRemoteDefinitions = ie;
35
+ async function se(n, e) {
36
+ const t = `${n}:${e}`;
37
+ if (O.has(t))
38
+ return O.get(t);
39
+ const o = (await (K.has(n) ? K.get(n) : await re(n)).get(e))();
40
+ return O.set(t, o), o;
41
+ }
42
+ R.loadRemoteModule = se;
43
+ const oe = (n, e) => new Promise((t, i) => {
44
+ const s = document.createElement("script");
45
+ s.src = n, s.type = "text/javascript", s.async = !0, s.onload = () => {
46
+ t({
47
+ get: (r) => window[e].get(r),
48
+ init: (r) => {
49
+ try {
50
+ window[e].init(r);
51
+ } catch (a) {
52
+ console.error(`Failed to initialize remote ${e}`, a), i(a);
53
+ }
54
+ }
55
+ });
56
+ }, s.onerror = () => i(new Error(`Remote ${e} not found`)), document.head.appendChild(s);
57
+ });
58
+ async function re(n) {
59
+ if (!j && !T)
60
+ throw new Error("Call setRemoteDefinitions or setRemoteUrlResolver to allow Dynamic Federation to find the remote apps correctly.");
61
+ B || (B = !0, await __webpack_init_sharing__("default"));
62
+ const e = T ? T[n] : await j(n);
63
+ let t = e;
64
+ !e.endsWith(".mjs") && !e.endsWith(".js") && (t = `${e}${e.endsWith("/") ? "" : "/"}remoteEntry.js`);
65
+ const i = await oe(t, n);
66
+ return await i.init(__webpack_share_scopes__.default), K.set(n, i), i;
67
+ }
68
+ (function(n) {
69
+ Object.defineProperty(n, "__esModule", { value: !0 }), n.setRemoteUrlResolver = n.setRemoteDefinitions = n.loadRemoteModule = void 0;
70
+ var e = R;
71
+ Object.defineProperty(n, "loadRemoteModule", { enumerable: !0, get: function() {
72
+ return e.loadRemoteModule;
73
+ } }), Object.defineProperty(n, "setRemoteDefinitions", { enumerable: !0, get: function() {
74
+ return e.setRemoteDefinitions;
75
+ } }), Object.defineProperty(n, "setRemoteUrlResolver", { enumerable: !0, get: function() {
76
+ return e.setRemoteUrlResolver;
77
+ } });
78
+ })(A);
79
+ const Be = /* @__PURE__ */ te({
80
+ __proto__: null
81
+ }, [A]);
82
+ function ae(n, e, t = !1) {
83
+ return !n || Object.keys(n).length === 0 ? null : t ? e && n[e] ? n[e] : null : e && n[e] ? n[e] : Object.values(n).filter((s) => typeof s.id == "string").sort((s, o) => {
84
+ const r = typeof s.rank == "number" ? s.rank : 1 / 0, a = typeof o.rank == "number" ? o.rank : 1 / 0;
85
+ if (r === a) {
86
+ const c = s.id ?? "", l = o.id ?? "";
87
+ return c.localeCompare(l);
88
+ }
89
+ return r - a;
90
+ })[0] ?? null;
91
+ }
92
+ class ce {
93
+ constructor() {
94
+ /**
95
+ * Map of contribution ID to its dynamic contribution state
96
+ */
97
+ v(this, "contributions", /* @__PURE__ */ new Map());
98
+ /**
99
+ * Map of extension point to contribution IDs
100
+ * Allows efficient lookup of contributions by extension point
101
+ */
102
+ v(this, "extensionPointIndex", /* @__PURE__ */ new Map());
103
+ /**
104
+ * Global listeners for all state changes
105
+ */
106
+ v(this, "globalListeners", /* @__PURE__ */ new Set());
107
+ /**
108
+ * Extension point-scoped listeners
109
+ * Map of extension point to listeners
110
+ */
111
+ v(this, "extensionPointListeners", /* @__PURE__ */ new Map());
112
+ /**
113
+ * Current enablement context for conditional evaluation
114
+ */
115
+ v(this, "enablementContext", {
116
+ extensions: {},
117
+ contributions: {
118
+ controlPourDefinitions: {},
119
+ experiences: {}
120
+ },
121
+ context: {}
122
+ });
123
+ }
124
+ /**
125
+ * Register a contribution in the registry
126
+ *
127
+ * This is called during plugin initialization to register all contributions
128
+ * with their default enabled state (true).
129
+ *
130
+ * @param contributionId - Unique identifier for the contribution
131
+ * @param extensionPoint - Extension point this contribution belongs to
132
+ * @param contribution - The contribution object
133
+ * @internal
134
+ */
135
+ register(e, t, i) {
136
+ const s = {
137
+ ...i,
138
+ enabled: !0,
139
+ lastStateChange: Date.now()
140
+ };
141
+ this.contributions.set(e, s), this.extensionPointIndex.has(t) || this.extensionPointIndex.set(t, /* @__PURE__ */ new Set()), this.extensionPointIndex.get(t).add(e);
142
+ }
143
+ /**
144
+ * Update the enablement context
145
+ *
146
+ * The context is used when evaluating conditional enablement functions.
147
+ *
148
+ * @param context - New enablement context
149
+ * @internal
150
+ */
151
+ setContext(e) {
152
+ this.enablementContext = {
153
+ ...this.enablementContext,
154
+ ...e
155
+ };
156
+ }
157
+ /**
158
+ * Set enabled state for a contribution
159
+ *
160
+ * Updates the contribution's enabled state and emits a
161
+ * ContributionStateChangeEvent to all subscribers.
162
+ *
163
+ * @param contributionId - Unique identifier of the contribution
164
+ * @param enabled - New enabled state (true = enabled, false = disabled)
165
+ * @param reason - Optional human-readable reason for the change
166
+ */
167
+ setEnabled(e, t, i) {
168
+ const s = this.contributions.get(e);
169
+ if (!s) {
170
+ console.warn(
171
+ `ContributionRegistry.setEnabled: Contribution '${e}' not found. Ignoring.`
172
+ );
173
+ return;
174
+ }
175
+ const o = s.enabled;
176
+ o !== t && (s.enabled = t, s.disabledReason = t ? void 0 : i, s.lastStateChange = Date.now(), this.emitStateChange({
177
+ contributionId: e,
178
+ extensionPoint: this.findExtensionPoint(e),
179
+ enabled: t,
180
+ previousState: o,
181
+ reason: i,
182
+ timestamp: s.lastStateChange
183
+ }));
184
+ }
185
+ /**
186
+ * Get enabled state for a contribution
187
+ *
188
+ * Checks both the enabled boolean field and evaluates any
189
+ * enabledCondition function if present. Returns true only if
190
+ * both checks pass.
191
+ *
192
+ * @param contributionId - Unique identifier of the contribution
193
+ * @returns true if contribution is enabled, false otherwise
194
+ */
195
+ isEnabled(e) {
196
+ const t = this.contributions.get(e);
197
+ if (!t)
198
+ return !0;
199
+ if (!t.enabled)
200
+ return !1;
201
+ if (t.enabledCondition)
202
+ try {
203
+ return t.enabledCondition(this.enablementContext);
204
+ } catch (i) {
205
+ return console.error(
206
+ `ContributionRegistry.isEnabled: Error evaluating enabledCondition for '${e}':`,
207
+ i
208
+ ), !1;
209
+ }
210
+ return !0;
211
+ }
212
+ /**
213
+ * Subscribe to all contribution state changes
214
+ *
215
+ * Registers a listener that will be called whenever any contribution's
216
+ * enabled state changes. The listener receives a ContributionStateChangeEvent.
217
+ *
218
+ * @param listener - Callback function to handle state change events
219
+ * @returns Unsubscribe function to stop receiving events
220
+ */
221
+ subscribe(e) {
222
+ if (typeof e != "function")
223
+ throw new TypeError(
224
+ "ContributionRegistry.subscribe: listener must be a function"
225
+ );
226
+ return this.globalListeners.add(e), () => {
227
+ this.globalListeners.delete(e);
228
+ };
229
+ }
230
+ /**
231
+ * Subscribe to changes for a specific extension point
232
+ *
233
+ * Like subscribe(), but only emits events for contributions
234
+ * belonging to the specified extension point.
235
+ *
236
+ * @param extensionPoint - Extension point identifier to monitor
237
+ * @param listener - Callback function to handle state change events
238
+ * @returns Unsubscribe function to stop receiving events
239
+ */
240
+ subscribeToExtensionPoint(e, t) {
241
+ if (typeof t != "function")
242
+ throw new TypeError(
243
+ "ContributionRegistry.subscribeToExtensionPoint: listener must be a function"
244
+ );
245
+ return this.extensionPointListeners.has(e) || this.extensionPointListeners.set(e, /* @__PURE__ */ new Set()), this.extensionPointListeners.get(e).add(t), () => {
246
+ var i, s;
247
+ (i = this.extensionPointListeners.get(e)) == null || i.delete(t), ((s = this.extensionPointListeners.get(e)) == null ? void 0 : s.size) === 0 && this.extensionPointListeners.delete(e);
248
+ };
249
+ }
250
+ /**
251
+ * Batch update multiple contributions atomically
252
+ *
253
+ * Updates multiple contribution states in a single atomic operation.
254
+ * All updates succeed or all fail together. Emits one event per
255
+ * contribution that changed state.
256
+ *
257
+ * @param updates - Array of contribution updates to apply
258
+ */
259
+ batchUpdate(e) {
260
+ if (!Array.isArray(e))
261
+ throw new TypeError(
262
+ "ContributionRegistry.batchUpdate: updates must be an array"
263
+ );
264
+ const t = e.map((s) => {
265
+ const o = this.contributions.get(s.contributionId);
266
+ return o ? o.enabled === s.enabled ? null : {
267
+ contribution: o,
268
+ update: s,
269
+ previousState: o.enabled
270
+ } : (console.warn(
271
+ `ContributionRegistry.batchUpdate: Contribution '${s.contributionId}' not found. Skipping.`
272
+ ), null);
273
+ }), i = Date.now();
274
+ t.forEach((s) => {
275
+ if (!s)
276
+ return;
277
+ const { contribution: o, update: r } = s;
278
+ o.enabled = r.enabled, o.disabledReason = r.enabled ? void 0 : r.reason, o.lastStateChange = i;
279
+ }), t.forEach((s) => {
280
+ if (!s)
281
+ return;
282
+ const { update: o, previousState: r } = s;
283
+ this.emitStateChange({
284
+ contributionId: o.contributionId,
285
+ extensionPoint: this.findExtensionPoint(o.contributionId),
286
+ enabled: o.enabled,
287
+ previousState: r,
288
+ reason: o.reason,
289
+ timestamp: i
290
+ });
291
+ });
292
+ }
293
+ /**
294
+ * Get all contributions for an extension point
295
+ *
296
+ * Returns an array of DynamicContribution objects for the specified
297
+ * extension point. By default, only returns enabled contributions.
298
+ *
299
+ * @param extensionPoint - Extension point identifier
300
+ * @param includeDisabled - If true, include disabled contributions in results
301
+ * @returns Array of contributions for the extension point
302
+ */
303
+ getContributions(e, t = !1) {
304
+ const i = this.extensionPointIndex.get(e);
305
+ if (!i || i.size === 0)
306
+ return [];
307
+ const s = [];
308
+ return i.forEach((o) => {
309
+ const r = this.contributions.get(o);
310
+ r && (t || this.isEnabled(o)) && s.push(r);
311
+ }), s;
312
+ }
313
+ /**
314
+ * Find the extension point for a contribution ID
315
+ * @internal
316
+ */
317
+ findExtensionPoint(e) {
318
+ for (const [t, i] of this.extensionPointIndex.entries())
319
+ if (i.has(e))
320
+ return t;
321
+ return "";
322
+ }
323
+ /**
324
+ * Emit state change event to all relevant listeners
325
+ * @internal
326
+ */
327
+ emitStateChange(e) {
328
+ this.globalListeners.forEach((i) => {
329
+ try {
330
+ i(e);
331
+ } catch (s) {
332
+ console.error("ContributionRegistry: Error in global listener:", s);
333
+ }
334
+ });
335
+ const t = this.extensionPointListeners.get(e.extensionPoint);
336
+ t && t.forEach((i) => {
337
+ try {
338
+ i(e);
339
+ } catch (s) {
340
+ console.error(
341
+ `ContributionRegistry: Error in extension point listener for '${e.extensionPoint}':`,
342
+ s
343
+ );
344
+ }
345
+ });
346
+ }
347
+ /**
348
+ * Clear all state (useful for testing or cleanup)
349
+ * @internal
350
+ */
351
+ reset() {
352
+ this.contributions.clear(), this.extensionPointIndex.clear(), this.globalListeners.clear(), this.extensionPointListeners.clear(), this.enablementContext = {
353
+ extensions: {},
354
+ contributions: {
355
+ controlPourDefinitions: {},
356
+ experiences: {}
357
+ },
358
+ context: {}
359
+ };
360
+ }
361
+ }
362
+ const N = new ce(), G = [];
363
+ function le(n) {
364
+ G.push(n);
365
+ }
366
+ function ue(n, e, t) {
367
+ return G.reduce(
368
+ (i, s) => s(i, e, t),
369
+ n
370
+ );
371
+ }
372
+ function de(n) {
373
+ var e;
374
+ try {
375
+ if ("shape" in n) {
376
+ const t = n, i = [];
377
+ for (const [s, o] of Object.entries(
378
+ t.shape
379
+ )) {
380
+ const r = o, a = {
381
+ name: s,
382
+ required: !r.isOptional()
383
+ };
384
+ if (r._def && r._def.description && (a.description = r._def.description), r._def) {
385
+ let c = r._def.typeName || "unknown";
386
+ c === "ZodOptional" && r._def.innerType && (c = ((e = r._def.innerType._def) == null ? void 0 : e.typeName) || "unknown"), a.type = c.replace("Zod", "").toLowerCase();
387
+ }
388
+ i.push(a);
389
+ }
390
+ return i;
391
+ }
392
+ return [];
393
+ } catch (t) {
394
+ return console.warn("Failed to extract schema field info:", t), [];
395
+ }
396
+ }
397
+ class fe {
398
+ constructor() {
399
+ v(this, "issues", []);
400
+ }
401
+ addError(e) {
402
+ this.issues.push({ type: "error", message: e });
403
+ }
404
+ addWarning(e) {
405
+ this.issues.push({ type: "warning", message: e });
406
+ }
407
+ addInfo(e) {
408
+ this.issues.push({ type: "info", message: e });
409
+ }
410
+ hasErrors() {
411
+ return this.issues.some((e) => e.type === "error");
412
+ }
413
+ hasIssues() {
414
+ return this.issues.length > 0;
415
+ }
416
+ getIssues() {
417
+ return [...this.issues];
418
+ }
419
+ }
420
+ class ge {
421
+ constructor() {
422
+ v(this, "cache", /* @__PURE__ */ new Map());
423
+ }
424
+ set(e, t) {
425
+ this.cache.set(e, t);
426
+ }
427
+ get(e) {
428
+ return this.cache.get(e) || [];
429
+ }
430
+ clear() {
431
+ this.cache.clear();
432
+ }
433
+ }
434
+ const U = new ge();
435
+ function He(n) {
436
+ return U.get(n);
437
+ }
438
+ class pe {
439
+ constructor() {
440
+ v(this, "extensionPoints", /* @__PURE__ */ new Map());
441
+ }
442
+ define(e) {
443
+ if (this.extensionPoints.has(e.id))
444
+ return console.warn(`Extension point ${e.id} is already defined`), this.extensionPoints.get(e.id);
445
+ const t = {
446
+ config: e,
447
+ id: e.id,
448
+ isRegistered: !1,
449
+ getExtensions: (i) => i[e.id] || {},
450
+ register: () => {
451
+ if (t.isRegistered) {
452
+ console.warn(`Extension point ${e.id} is already registered`);
453
+ return;
454
+ }
455
+ const i = this.createReducer(e);
456
+ le(i), t.isRegistered = !0;
457
+ }
458
+ };
459
+ return e.schema && (t.getSchemaFieldInfo = () => de(e.schema)), this.extensionPoints.set(e.id, t), t;
460
+ }
461
+ createReducer(e) {
462
+ return (t, i, s) => {
463
+ const o = i[e.contributionKey];
464
+ return !o || typeof o != "object" || Object.entries(o).forEach(
465
+ ([r, a]) => {
466
+ var d, m;
467
+ if (!a)
468
+ return;
469
+ const c = {
470
+ remote: a.remote || "",
471
+ sectionId: a.sectionId || r,
472
+ experiences: s,
473
+ contributions: i
474
+ };
475
+ if (e.validate) {
476
+ const f = new fe();
477
+ if (e.validate(
478
+ a,
479
+ f
480
+ ) === "skip") {
481
+ U.set(r, [
482
+ {
483
+ type: "warning",
484
+ message: "Plugin marked to skip processing"
485
+ }
486
+ ]);
487
+ return;
488
+ }
489
+ if (f.hasIssues()) {
490
+ const w = f.getIssues().map((E) => ({
491
+ ...E,
492
+ message: `Extension point validation: ${E.message}`
493
+ }));
494
+ if (U.set(r, w), f.hasErrors()) {
495
+ console.error(
496
+ `Validation failed for ${e.id} contribution "${r}":`,
497
+ w.filter((E) => E.type === "error").map((E) => E.message).join(", ")
498
+ );
499
+ return;
500
+ }
501
+ } else
502
+ U.set(r, []);
503
+ }
504
+ const l = e.transform ? e.transform(a, c) : a;
505
+ t[e.id] || (t[e.id] = {});
506
+ const u = {
507
+ id: r,
508
+ type: e.contributionKey,
509
+ data: l,
510
+ remote: c.remote,
511
+ sectionId: c.sectionId
512
+ };
513
+ if (e.isRankable && typeof a.rank == "number" && (u.rank = a.rank), l && typeof l == "object" && ("component" in l && (u.component = l.component), "view" in l && (u.view = l.view), "location" in l && (u.location = l.location)), t[e.id][r] = u, N.register(r, e.id, {
514
+ id: r,
515
+ remote: c.remote,
516
+ sectionId: c.sectionId
517
+ }), e.hasView && ((d = e.relatedPoints) != null && d.view)) {
518
+ const f = a.experienceId, g = s == null ? void 0 : s[f];
519
+ g && (t[e.relatedPoints.view] || (t[e.relatedPoints.view] = {}), t[e.relatedPoints.view][r] = {
520
+ id: r,
521
+ type: `${e.contributionKey}.view`,
522
+ data: g,
523
+ remote: c.remote,
524
+ sectionId: c.sectionId
525
+ }, N.register(r, e.relatedPoints.view, {
526
+ id: r,
527
+ remote: c.remote,
528
+ sectionId: c.sectionId
529
+ }));
530
+ }
531
+ (m = e.relatedPoints) != null && m.definition && (t[e.relatedPoints.definition] || (t[e.relatedPoints.definition] = {}), t[e.relatedPoints.definition][r] = {
532
+ id: r,
533
+ type: `${e.contributionKey}.definition`,
534
+ data: l,
535
+ remote: c.remote,
536
+ sectionId: c.sectionId
537
+ }, N.register(
538
+ r,
539
+ e.relatedPoints.definition,
540
+ {
541
+ id: r,
542
+ remote: c.remote,
543
+ sectionId: c.sectionId
544
+ }
545
+ ));
546
+ }
547
+ ), t;
548
+ };
549
+ }
550
+ /**
551
+ * Get all registered extension points (for discovery/documentation)
552
+ */
553
+ getAllExtensionPoints() {
554
+ return Array.from(this.extensionPoints.values()).filter(
555
+ (e) => e.isRegistered
556
+ );
557
+ }
558
+ /**
559
+ * Get all defined extension points (registered and unregistered)
560
+ */
561
+ getAllDefinedExtensionPoints() {
562
+ return Array.from(this.extensionPoints.values());
563
+ }
564
+ /**
565
+ * Get a specific extension point definition
566
+ */
567
+ getExtensionPoint(e) {
568
+ return this.extensionPoints.get(e);
569
+ }
570
+ /**
571
+ * Check if an extension point is registered
572
+ */
573
+ hasExtensionPoint(e) {
574
+ return this.extensionPoints.has(e);
575
+ }
576
+ /**
577
+ * Get the Zod schema for an extension point
578
+ * Returns undefined if the extension point doesn't have a schema
579
+ */
580
+ getExtensionPointSchema(e) {
581
+ const t = this.extensionPoints.get(e);
582
+ return t == null ? void 0 : t.config.schema;
583
+ }
584
+ }
585
+ const L = new pe();
586
+ function C() {
587
+ return L;
588
+ }
589
+ function We(n) {
590
+ return L.getExtensionPointSchema(n);
591
+ }
592
+ function me(n = {}) {
593
+ const {
594
+ experienceIdProperty: e = "experienceId",
595
+ flattenComponentProperties: t = !0,
596
+ customTransform: i
597
+ } = n;
598
+ return (s, o) => {
599
+ var l;
600
+ const r = s[e], a = r ? ((l = o.experiences) == null ? void 0 : l[r]) || {} : {};
601
+ let c = {
602
+ ...s,
603
+ view: a
604
+ };
605
+ return t && a && (a.component && (c.component = a.component), a.location && (c.location = a.location)), i && (c = i(s, a, o) || c), c;
606
+ };
607
+ }
608
+ function he(n) {
609
+ return L.define(n);
610
+ }
611
+ const be = {
612
+ $timestamp: () => Date.now(),
613
+ $date: () => (/* @__PURE__ */ new Date()).toISOString(),
614
+ $packageVersion: () => process.env.npm_package_version || "0.0.0",
615
+ $env: () => process.env.NODE_ENV || "development"
616
+ };
617
+ function ye(n) {
618
+ const e = {
619
+ id: n.id,
620
+ displayName: n.displayName,
621
+ description: n.description,
622
+ contributionKey: n.contributionKey,
623
+ hasView: n.hasView,
624
+ isRankable: n.isRankable,
625
+ relatedPoints: n.relatedPoints,
626
+ metadata: n.metadata ? {
627
+ ...n.metadata,
628
+ exportName: n.metadata.exportName || xe(n.id)
629
+ } : void 0
630
+ };
631
+ return n.schema && (e.schema = ve(n.schema, {
632
+ hasView: n.hasView,
633
+ isRankable: n.isRankable
634
+ })), n.validation && (e.validate = we(n.validation)), n.transform ? e.transform = Ve(n.transform) : n.hasView && (e.transform = me()), e;
635
+ }
636
+ function xe(n) {
637
+ return n.split(".").map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("") + "Extension";
638
+ }
639
+ function ve(n, e) {
640
+ try {
641
+ const { z: t } = require("zod");
642
+ if (n.properties) {
643
+ const i = {};
644
+ i.id = t.string().min(1), i.title = t.string().min(1), i.namespace = t.string().min(1), e != null && e.hasView && (i.experienceId = t.string().min(1)), e != null && e.isRankable && (i.rank = t.number().min(0).max(1e3).optional());
645
+ for (const [o, r] of Object.entries(n.properties))
646
+ i[o] = Ee(r, t);
647
+ let s = t.object(i);
648
+ return n.additionalProperties || (s = s.strict()), s;
649
+ }
650
+ return t.any();
651
+ } catch (t) {
652
+ console.warn("Zod not available for JSON schema conversion:", t);
653
+ return;
654
+ }
655
+ }
656
+ function Ee(n, e) {
657
+ let t;
658
+ switch (n.type) {
659
+ case "string":
660
+ t = e.string(), n.minLength && (t = t.min(n.minLength)), n.maxLength && (t = t.max(n.maxLength)), n.pattern && (t = t.regex(new RegExp(n.pattern))), n.enum && (t = e.enum(n.enum));
661
+ break;
662
+ case "number":
663
+ t = e.number(), n.minimum !== void 0 && (t = t.min(n.minimum)), n.maximum !== void 0 && (t = t.max(n.maximum));
664
+ break;
665
+ case "boolean":
666
+ t = e.boolean();
667
+ break;
668
+ case "array":
669
+ t = e.array(e.any());
670
+ break;
671
+ case "object":
672
+ t = e.object({});
673
+ break;
674
+ default:
675
+ t = e.any();
676
+ }
677
+ return n.description && (t = t.describe(n.description)), n.default !== void 0 && (t = t.default(n.default)), t;
678
+ }
679
+ function we(n) {
680
+ return n.module ? Se(n.module) : (e, t) => {
681
+ if (!n.rules)
682
+ return;
683
+ const i = e;
684
+ for (const s of n.rules)
685
+ Pe(s, i, t);
686
+ };
687
+ }
688
+ function Pe(n, e, t) {
689
+ switch (n.type) {
690
+ case "required":
691
+ Ce(n, e, t);
692
+ break;
693
+ case "range":
694
+ $e(n, e, t);
695
+ break;
696
+ case "pattern":
697
+ ke(n, e, t);
698
+ break;
699
+ case "dependency":
700
+ Re(n, e, t);
701
+ break;
702
+ case "custom":
703
+ Ie(n, e, t);
704
+ break;
705
+ }
706
+ }
707
+ function Ce(n, e, t) {
708
+ n.field && !e[n.field] && t.addError(n.message || `Field '${n.field}' is required`);
709
+ }
710
+ function $e(n, e, t) {
711
+ if (n.field && typeof e[n.field] == "number") {
712
+ const i = e[n.field];
713
+ n.min !== void 0 && i < n.min && t.addError(
714
+ n.message || `Field '${n.field}' must be at least ${n.min}`
715
+ ), n.max !== void 0 && i > n.max && t.addError(
716
+ n.message || `Field '${n.field}' must be at most ${n.max}`
717
+ );
718
+ }
719
+ }
720
+ function ke(n, e, t) {
721
+ n.field && n.pattern && typeof e[n.field] == "string" && (new RegExp(n.pattern).test(e[n.field]) || t.addError(
722
+ n.message || `Field '${n.field}' does not match pattern ${n.pattern}`
723
+ ));
724
+ }
725
+ function Re(n, e, t) {
726
+ if (n.field && n.dependsOn && n.expression)
727
+ try {
728
+ _(n.expression, e) || t.addError(
729
+ n.message || `Field '${n.field}' dependency validation failed`
730
+ );
731
+ } catch (i) {
732
+ t.addWarning(`Failed to evaluate dependency expression: ${i}`);
733
+ }
734
+ }
735
+ function Ie(n, e, t) {
736
+ if (n.expression)
737
+ try {
738
+ _(n.expression, e) || t.addError(n.message || "Custom validation failed");
739
+ } catch (i) {
740
+ t.addWarning(`Failed to evaluate custom expression: ${i}`);
741
+ }
742
+ }
743
+ function Se(n) {
744
+ return (e, t) => {
745
+ console.warn(`External validation module not implemented: ${n}`), t.addWarning(
746
+ `External validation module not yet supported: ${n}`
747
+ );
748
+ };
749
+ }
750
+ function Ve(n) {
751
+ return n.module ? Ne(n.module) : (e, t) => {
752
+ const i = { ...e };
753
+ if (n.addFields)
754
+ for (const [s, o] of Object.entries(n.addFields))
755
+ i[s] = De(o);
756
+ if (n.removeFields)
757
+ for (const s of n.removeFields)
758
+ delete i[s];
759
+ if (n.renameFields)
760
+ for (const [s, o] of Object.entries(
761
+ n.renameFields
762
+ ))
763
+ s in i && (i[o] = i[s], delete i[s]);
764
+ if (n.normalizeFields)
765
+ for (const { field: s, operation: o } of n.normalizeFields)
766
+ s in i && typeof i[s] == "string" && (i[s] = Fe(
767
+ i[s],
768
+ o
769
+ ));
770
+ return i;
771
+ };
772
+ }
773
+ function Ne(n) {
774
+ return (e, t) => (console.warn(`External transform module not implemented: ${n}`), e);
775
+ }
776
+ function De(n) {
777
+ if (typeof n == "string" && n.startsWith("$")) {
778
+ const e = be[n];
779
+ if (e)
780
+ return e();
781
+ }
782
+ return n;
783
+ }
784
+ function Fe(n, e) {
785
+ switch (e) {
786
+ case "trim":
787
+ return n.trim();
788
+ case "lowercase":
789
+ return n.toLowerCase();
790
+ case "uppercase":
791
+ return n.toUpperCase();
792
+ case "camelCase":
793
+ return Te(n);
794
+ case "kebabCase":
795
+ return Ue(n);
796
+ default:
797
+ return n;
798
+ }
799
+ }
800
+ function Te(n) {
801
+ return n.replace(/[-_\s]+(.)?/g, (e, t) => t ? t.toUpperCase() : "").replace(/^./, (e) => e.toLowerCase());
802
+ }
803
+ function Ue(n) {
804
+ return n.replace(/([a-z])([A-Z])/g, "$1-$2").replace(/[\s_]+/g, "-").toLowerCase();
805
+ }
806
+ function _(n, e) {
807
+ try {
808
+ let t = n;
809
+ for (const [i, s] of Object.entries(e)) {
810
+ const o = typeof s == "string" ? `"${s}"` : String(s);
811
+ t = t.replace(
812
+ new RegExp(`\\b${i}\\b`, "g"),
813
+ o
814
+ );
815
+ }
816
+ if (t.includes("!==")) {
817
+ const [i, s] = t.split("!==").map((o) => o.trim());
818
+ return i !== s;
819
+ }
820
+ if (t.includes("===")) {
821
+ const [i, s] = t.split("===").map((o) => o.trim());
822
+ return i === s;
823
+ }
824
+ return t.includes("||") ? t.split("||").map((s) => s.trim()).some((s) => _(s, e)) : t.includes("&&") ? t.split("&&").map((s) => s.trim()).every((s) => _(s, e)) : !1;
825
+ } catch (t) {
826
+ return console.error("Expression evaluation failed:", t), !1;
827
+ }
828
+ }
829
+ const _e = (n) => (e, t) => {
830
+ var c;
831
+ const i = n[t].remote, s = n[t].section || "default", o = ((c = n[t].contributes) == null ? void 0 : c.experiences) ?? {};
832
+ return Object.keys(o).forEach((l) => {
833
+ const u = o[l];
834
+ e.experiences[l] = {
835
+ ...u,
836
+ remote: i,
837
+ sectionId: s
838
+ };
839
+ }), C().getAllExtensionPoints().forEach((l) => {
840
+ var m;
841
+ const { contributionKey: u } = l.config, d = (m = n[t].contributes) == null ? void 0 : m[u];
842
+ d && (e[u] || (e[u] = {}), Array.isArray(d) ? d.forEach((f) => {
843
+ f && f.id && (e[u][f.id] = {
844
+ ...f,
845
+ remote: i,
846
+ sectionId: s
847
+ });
848
+ }) : typeof d == "object" && Object.entries(d).forEach(([f, g]) => {
849
+ e[u][f] = {
850
+ ...g,
851
+ id: f,
852
+ remote: i,
853
+ sectionId: s
854
+ };
855
+ }));
856
+ }), e;
857
+ };
858
+ async function Ae(n) {
859
+ const e = n ?? window.KosPlugins.__dynamicRemotes;
860
+ if (window.KosPlugins.extensions) {
861
+ const o = window.KosPlugins.extensions;
862
+ return {
863
+ extensionPoints: o,
864
+ getExtensions: (r) => o[r] || [],
865
+ remotes: e,
866
+ extensions: window.KosPlugins.__extensions
867
+ };
868
+ }
869
+ const t = window.KosPlugins.__extensions ?? await qe(e), i = {};
870
+ if (t)
871
+ for (const o of Object.keys(t))
872
+ i[o] = Object.values(
873
+ t[o] || {}
874
+ );
875
+ return window.KosPlugins.extensions = i, { extensionPoints: i, getExtensions: (o) => i[o] || [], remotes: e, extensions: t };
876
+ }
877
+ const H = {
878
+ controlPourDefinitions: {},
879
+ experiences: {}
880
+ };
881
+ function Oe(n) {
882
+ return n ? Object.keys(n).reduce(_e(n), {
883
+ ...H
884
+ }) : H;
885
+ }
886
+ async function qe(n) {
887
+ if (!n)
888
+ return window.KosPlugins = window.KosPlugins || {}, {};
889
+ for (const o of Object.values(n)) {
890
+ try {
891
+ if (o.extensions && Array.isArray(o.extensions)) {
892
+ const r = o.extensions.filter((a) => a && typeof a == "object" && "id" in a).map((a) => ye(a));
893
+ if (r.length > 0) {
894
+ console.info(
895
+ `Registering ${r.length} JSON extension point(s) from ${o.remote}`
896
+ );
897
+ for (const a of r)
898
+ try {
899
+ he(a).register(), console.debug(`Registered JSON extension point: ${a.id}`);
900
+ } catch (c) {
901
+ console.error(
902
+ `Failed to register JSON extension point '${a.id}' from ${o.remote}:`,
903
+ c
904
+ );
905
+ }
906
+ }
907
+ }
908
+ } catch (r) {
909
+ console.warn(
910
+ `Failed to parse JSON extension points from ${o.remote}:`,
911
+ r
912
+ );
913
+ }
914
+ if (o.init)
915
+ try {
916
+ const r = await A.loadRemoteModule(
917
+ o.remote,
918
+ "./InitPlugin"
919
+ );
920
+ if (r.default) {
921
+ const a = new r.default();
922
+ a == null || a.register();
923
+ }
924
+ } catch (r) {
925
+ console.warn(`Failed to load InitPlugin from ${o.remote}:`, r);
926
+ }
927
+ }
928
+ const e = Oe(n), t = e.experiences, s = ue(
929
+ {},
930
+ e,
931
+ t
932
+ );
933
+ return N.setContext({
934
+ extensions: s,
935
+ contributions: e
936
+ }), window.KosPlugins = window.KosPlugins || {}, window.KosPlugins.__extensions = s, s;
937
+ }
938
+ async function Ge(n) {
939
+ const { getExtensions: e } = await Ae();
940
+ return e(n);
941
+ }
942
+ const J = (n = null) => (n || window.location.search.replace("?", "")).split("&").map((e) => {
943
+ const [t, i] = e.split("=");
944
+ return [t, decodeURIComponent(i || "")];
945
+ }).reduce((e, [t, i]) => (e[t] = i, e), {}), je = () => {
946
+ const n = window.location.origin, e = J();
947
+ return (e == null ? void 0 : e.host) || n;
948
+ }, Je = async (n) => {
949
+ var z;
950
+ const e = je(), t = n ?? {}, {
951
+ pluginBaseUrl: i = e,
952
+ pluginApiPath: s,
953
+ overrides: o = {},
954
+ pluginContext: r
955
+ } = t;
956
+ console.log("[initialize-plugins] Config received:", {
957
+ propsPluginBaseUrl: n == null ? void 0 : n.pluginBaseUrl,
958
+ defaultHost: e,
959
+ resolvedPluginBaseUrl: i,
960
+ pluginApiPath: s
961
+ });
962
+ const a = s ? `${i}${s}` : `${i}/api/kos/ui/plugins/contexts`;
963
+ console.log(
964
+ `initialize-plugins: Using Plugin Framework. Fetching plugins from ${a}`
965
+ );
966
+ const l = await (await fetch(a)).json(), u = J(), d = u.pluginDevServers ? u.pluginDevServers.split(",").map((b) => b.trim()) : [];
967
+ if (d.length > 0) {
968
+ console.log(
969
+ "[initialize-plugins] Detected third-party plugin dev servers:",
970
+ d
971
+ );
972
+ const p = (await Promise.all(
973
+ d.map(async (h) => {
974
+ try {
975
+ console.log(
976
+ `[initialize-plugins] Fetching from dev server: ${h}`
977
+ );
978
+ const P = await fetch(
979
+ `${h}/api/kos/ui/plugins/contexts`
980
+ );
981
+ if (!P.ok)
982
+ return console.warn(
983
+ `[initialize-plugins] Dev server ${h} returned ${P.status}`
984
+ ), null;
985
+ const I = await P.json();
986
+ return { serverUrl: h, data: I };
987
+ } catch (P) {
988
+ return console.warn(
989
+ `[initialize-plugins] Failed to fetch from dev server ${h}:`,
990
+ P
991
+ ), null;
992
+ }
993
+ })
994
+ )).filter(
995
+ (h) => h !== null && h.data && h.data.status === 200
996
+ );
997
+ if (p.length > 0) {
998
+ console.log(
999
+ `[initialize-plugins] Merging ${p.length} dev server plugin(s)`
1000
+ );
1001
+ const h = {};
1002
+ p.forEach(({ serverUrl: P, data: I }) => {
1003
+ var $;
1004
+ ($ = I.data) == null || $.forEach((k) => {
1005
+ var D;
1006
+ let S = (D = l.data) == null ? void 0 : D.find(
1007
+ (y) => y.name === k.name
1008
+ );
1009
+ S || (S = { name: k.name, plugins: [] }, l.data = l.data || [], l.data.push(S)), k.plugins.forEach((y) => {
1010
+ var x;
1011
+ S.plugins.push(y), h[y.id] = `${P}/`, console.log(
1012
+ `[initialize-plugins] Added dev plugin: ${(x = y.descriptor) == null ? void 0 : x.id} from ${P}`
1013
+ );
1014
+ });
1015
+ });
1016
+ }), l.overrides = {
1017
+ ...l.overrides || {},
1018
+ ...h
1019
+ }, console.log(
1020
+ "[initialize-plugins] Dev server overrides:",
1021
+ h
1022
+ );
1023
+ }
1024
+ }
1025
+ const m = {
1026
+ ...o,
1027
+ ...l.overrides || {}
1028
+ };
1029
+ l.overrides && console.log(
1030
+ "[initialize-plugins] Using overrides from response:",
1031
+ l.overrides
1032
+ ), Object.keys(m).length > 0 && console.log("[initialize-plugins] Merged overrides:", m);
1033
+ const f = typeof (r == null ? void 0 : r.context) == "string" ? [r.context] : (r == null ? void 0 : r.context) || [], g = (z = l.data) == null ? void 0 : z.filter((b) => f.length === 0 || f.includes(b.name)).flatMap(
1034
+ (b) => b.plugins.map((p) => ({ ...p, name: b.name })) ?? []
1035
+ ), w = r == null ? void 0 : r.group, E = g == null ? void 0 : g.reduce((b, p) => {
1036
+ const h = (m == null ? void 0 : m[p.id]) ?? `${i}${p.path}`;
1037
+ if (p.descriptor) {
1038
+ const I = (p.descriptor.extensions || []).reduce((y, x) => {
1039
+ const F = x.groups || [];
1040
+ return (!w || F.includes(w)) && y.push(x), y;
1041
+ }, []), $ = p.descriptor.contributes || {};
1042
+ let k = !1;
1043
+ const S = Object.keys($).reduce(
1044
+ (y, x) => {
1045
+ if (Array.isArray($[x])) {
1046
+ const F = ($[x] || []).filter((Y) => {
1047
+ const Q = Y.groups || [];
1048
+ return !w || Q.includes(w);
1049
+ });
1050
+ k = k || F.length > 0, y[x] = F;
1051
+ } else
1052
+ y[x] = $[x], k = Object.keys($[x]).length > 0;
1053
+ return y;
1054
+ },
1055
+ {}
1056
+ ), D = !!p.descriptor.init && (I.length > 0 || k);
1057
+ b[p.id] = {
1058
+ section: p.name,
1059
+ basePath: `${h}remoteEntry.js`,
1060
+ extensions: I,
1061
+ contributes: S,
1062
+ remote: p.descriptor.id,
1063
+ init: D
1064
+ };
1065
+ } else
1066
+ console.error(
1067
+ `initialize-plugins: Plugin ${p.id} does not have a descriptor`
1068
+ );
1069
+ return b;
1070
+ }, {});
1071
+ window.KosPlugins = window.KosPlugins || {}, window.KosPlugins.__dynamicRemotes = E;
1072
+ const M = Object.keys(E).reduce((b, p) => {
1073
+ const h = E[p].remote;
1074
+ return b[h] = E[p].basePath, b;
1075
+ }, {});
1076
+ return A.setRemoteDefinitions(M), M;
1077
+ };
1078
+ class Ze {
1079
+ constructor(e) {
1080
+ /**
1081
+ * Reference to all plugin extensions (unfiltered)
1082
+ */
1083
+ v(this, "extensions");
1084
+ /**
1085
+ * Map of extension point to listeners
1086
+ * Each extension point can have multiple components listening for changes
1087
+ */
1088
+ v(this, "listeners");
1089
+ /**
1090
+ * Unsubscribe function for ContributionRegistry subscription
1091
+ * Used during cleanup to remove listener
1092
+ */
1093
+ v(this, "contributionUnsubscribe", null);
1094
+ this.extensions = e, this.listeners = /* @__PURE__ */ new Map(), this.subscribeToContributionChanges();
1095
+ }
1096
+ /**
1097
+ * Get extensions for an extension point (filtered by enabled state)
1098
+ *
1099
+ * By default, only returns enabled contributions. Use `includeDisabled: true`
1100
+ * to get all contributions regardless of state.
1101
+ *
1102
+ * @param extensionPoint - Extension point identifier
1103
+ * @param includeDisabled - If true, include disabled contributions (default: false)
1104
+ * @returns Record of extension ID to extension object
1105
+ *
1106
+ * @example
1107
+ * ```typescript
1108
+ * // Get only enabled settings extensions
1109
+ * const enabled = registry.getExtensions('ddk.settings.view');
1110
+ *
1111
+ * // Get all settings extensions (including disabled)
1112
+ * const all = registry.getExtensions('ddk.settings.view', true);
1113
+ * ```
1114
+ */
1115
+ getExtensions(e, t = !1) {
1116
+ const i = this.extensions[e] || {};
1117
+ return t ? i : Object.entries(i).reduce((s, [o, r]) => (N.isEnabled(o) && (s[o] = r), s), {});
1118
+ }
1119
+ /**
1120
+ * Subscribe to changes for a specific extension point
1121
+ *
1122
+ * Registers a listener that will be called whenever contributions for
1123
+ * the specified extension point change state (enabled/disabled) or when
1124
+ * the best contribution for that point changes.
1125
+ *
1126
+ * @param extensionPoint - Extension point identifier to monitor
1127
+ * @param listener - Callback function to handle change events
1128
+ * @returns Unsubscribe function to stop receiving events
1129
+ *
1130
+ * @example
1131
+ * ```typescript
1132
+ * const unsubscribe = registry.subscribe('ddk.settings.view', (event) => {
1133
+ * if (event.changeType === 'best-changed') {
1134
+ * console.log('New best contribution:', event.newBest);
1135
+ * }
1136
+ * });
1137
+ *
1138
+ * // Later...
1139
+ * unsubscribe();
1140
+ * ```
1141
+ */
1142
+ subscribe(e, t) {
1143
+ if (typeof t != "function")
1144
+ throw new TypeError(
1145
+ "ReactiveExtensionRegistry.subscribe: listener must be a function"
1146
+ );
1147
+ return this.listeners.has(e) || this.listeners.set(e, /* @__PURE__ */ new Set()), this.listeners.get(e).add(t), () => {
1148
+ var i, s;
1149
+ (i = this.listeners.get(e)) == null || i.delete(t), ((s = this.listeners.get(e)) == null ? void 0 : s.size) === 0 && this.listeners.delete(e);
1150
+ };
1151
+ }
1152
+ /**
1153
+ * Internal: Subscribe to contribution state changes
1154
+ *
1155
+ * Sets up subscription to ContributionRegistry to receive notifications
1156
+ * when any contribution's enabled state changes. Routes these events to
1157
+ * extension point-specific listeners.
1158
+ *
1159
+ * @private
1160
+ */
1161
+ subscribeToContributionChanges() {
1162
+ this.contributionUnsubscribe = N.subscribe(
1163
+ (e) => this.handleContributionChange(e)
1164
+ );
1165
+ }
1166
+ /**
1167
+ * Internal: Handle contribution state change
1168
+ *
1169
+ * Called when ContributionRegistry emits a state change event.
1170
+ * Determines if the "best" contribution has changed and emits
1171
+ * ExtensionPointChangeEvent to all listeners for that extension point.
1172
+ *
1173
+ * @param event - Contribution state change event from ContributionRegistry
1174
+ * @private
1175
+ */
1176
+ handleContributionChange(e) {
1177
+ const { contributionId: t, extensionPoint: i, enabled: s } = e;
1178
+ if (!this.listeners.has(i))
1179
+ return;
1180
+ this.extensions[i];
1181
+ const o = ae(
1182
+ this.getExtensions(i)
1183
+ ), r = s ? "contribution-enabled" : "contribution-disabled", a = this.listeners.get(i);
1184
+ if (a) {
1185
+ const c = {
1186
+ extensionPoint: i,
1187
+ changeType: r,
1188
+ affectedContribution: t,
1189
+ newBest: o == null ? void 0 : o.id,
1190
+ timestamp: e.timestamp
1191
+ };
1192
+ a.forEach((l) => {
1193
+ try {
1194
+ l(c);
1195
+ } catch (u) {
1196
+ console.error(
1197
+ `ReactiveExtensionRegistry: Error in listener for '${i}':`,
1198
+ u
1199
+ );
1200
+ }
1201
+ });
1202
+ }
1203
+ }
1204
+ /**
1205
+ * Cleanup subscriptions and listeners
1206
+ *
1207
+ * Call this when the registry is no longer needed to prevent memory leaks.
1208
+ * Typically called when the PluginsProvider is unmounted.
1209
+ *
1210
+ * @example
1211
+ * ```typescript
1212
+ * useEffect(() => {
1213
+ * const registry = new ReactiveExtensionRegistry(extensions);
1214
+ * // Use registry...
1215
+ * return () => registry.destroy();
1216
+ * }, []);
1217
+ * ```
1218
+ */
1219
+ destroy() {
1220
+ var e;
1221
+ (e = this.contributionUnsubscribe) == null || e.call(this), this.contributionUnsubscribe = null, this.listeners.clear();
1222
+ }
1223
+ }
1224
+ function W(n) {
1225
+ const e = n.match(/^(\d+)\.(\d+)\.\d+(?:-\S+)?$/);
1226
+ if (!e)
1227
+ throw new Error(`Invalid version format: ${n}`);
1228
+ const [t, i, s] = e;
1229
+ return `${i}.${s}.0`;
1230
+ }
1231
+ function Ye(n, e) {
1232
+ var l, u;
1233
+ e != null && e.sdkVersion && console.log("sdkVersion", e.sdkVersion), e != null && e.ddkVersion && console.log("ddkVersion", e.ddkVersion);
1234
+ const t = W((e == null ? void 0 : e.sdkVersion) || "0.2.0"), i = W((e == null ? void 0 : e.ddkVersion) || "0.2.0");
1235
+ console.log(`Using DDK version: ${i}`), console.log(`Using SDK version: ${t}`);
1236
+ const s = n == null ? void 0 : n.name;
1237
+ if (!s)
1238
+ throw new Error(
1239
+ "KOS Configuration should be added. Project name not found in config"
1240
+ );
1241
+ const r = ((e == null ? void 0 : e.pluginPath) || "kos.ui.plugin").split(".").reduce((d, m) => (console.log(`Accessing key: ${m}`), d && d[m] ? d[m] : void 0), n), a = r == null ? void 0 : r.id;
1242
+ if (!a)
1243
+ throw new Error(
1244
+ "KOS Configuration should be added. Plugin ID not found in config"
1245
+ );
1246
+ const c = Object.keys(((l = r == null ? void 0 : r.contributes) == null ? void 0 : l.views) || {}).reduce(
1247
+ (d, m) => (r.contributes.views[m].forEach((g) => {
1248
+ d[`./${g.component}`] = g.location;
1249
+ }), d),
1250
+ {}
1251
+ );
1252
+ return Object.values(((u = r == null ? void 0 : r.contributes) == null ? void 0 : u.experiences) || {}).forEach(
1253
+ (d) => {
1254
+ c[`./${d.component}`] = d.location;
1255
+ }
1256
+ ), r != null && r.init && (c["./InitPlugin"] = "./src/app/init.ts"), {
1257
+ name: s,
1258
+ exposes: c,
1259
+ library: { type: "var", name: a },
1260
+ additionalShared: [
1261
+ {
1262
+ libraryName: "@kosdev-code/kos-ui-plugin",
1263
+ sharedConfig: {
1264
+ singleton: !0,
1265
+ eager: !1,
1266
+ requiredVersion: `~${i}`
1267
+ }
1268
+ },
1269
+ {
1270
+ libraryName: "react",
1271
+ sharedConfig: {
1272
+ singleton: !0,
1273
+ eager: !1,
1274
+ strictVersion: !0,
1275
+ requiredVersion: "18.2.0"
1276
+ }
1277
+ },
1278
+ {
1279
+ libraryName: "react-dom",
1280
+ sharedConfig: {
1281
+ singleton: !0,
1282
+ eager: !1,
1283
+ strictVersion: !0,
1284
+ requiredVersion: "18.2.0"
1285
+ }
1286
+ },
1287
+ {
1288
+ libraryName: "@kosdev-code/kos-ui-sdk",
1289
+ sharedConfig: {
1290
+ singleton: !0,
1291
+ eager: !1,
1292
+ strictVersion: !1,
1293
+ requiredVersion: `~${t}`
1294
+ }
1295
+ },
1296
+ {
1297
+ libraryName: "@kosdev-code/kos-dispense-sdk",
1298
+ sharedConfig: {
1299
+ singleton: !0,
1300
+ eager: !1,
1301
+ strictVersion: !1,
1302
+ requiredVersion: `~${t}`
1303
+ }
1304
+ },
1305
+ {
1306
+ libraryName: "@kosdev-code/kos-freestyle-sdk",
1307
+ sharedConfig: {
1308
+ singleton: !0,
1309
+ eager: !1,
1310
+ strictVersion: !1,
1311
+ requiredVersion: `~${t}`
1312
+ }
1313
+ },
1314
+ {
1315
+ libraryName: "@kosdev-code/kos-ddk-components",
1316
+ sharedConfig: {
1317
+ singleton: !0,
1318
+ eager: !1,
1319
+ strictVersion: !1,
1320
+ requiredVersion: `~${i}`
1321
+ }
1322
+ },
1323
+ {
1324
+ libraryName: "@kosdev-code/kos-ddk-model-components",
1325
+ sharedConfig: {
1326
+ singleton: !0,
1327
+ eager: !1,
1328
+ strictVersion: !1,
1329
+ requiredVersion: `~${i}`
1330
+ }
1331
+ },
1332
+ {
1333
+ libraryName: "@kosdev-code/kos-ddk-models",
1334
+ sharedConfig: {
1335
+ singleton: !0,
1336
+ eager: !1,
1337
+ strictVersion: !1,
1338
+ requiredVersion: `~${i}`
1339
+ }
1340
+ },
1341
+ {
1342
+ libraryName: "@kosdev-code/kos-ddk",
1343
+ sharedConfig: {
1344
+ singleton: !0,
1345
+ eager: !1,
1346
+ strictVersion: !1,
1347
+ requiredVersion: `~${i}`
1348
+ }
1349
+ },
1350
+ {
1351
+ libraryName: "@kosdev-code/kos-ddk-styles",
1352
+ sharedConfig: {
1353
+ singleton: !0,
1354
+ eager: !1,
1355
+ strictVersion: !1,
1356
+ requiredVersion: `~${i}`
1357
+ }
1358
+ },
1359
+ {
1360
+ libraryName: "@emotion/styled",
1361
+ sharedConfig: {
1362
+ singleton: !0,
1363
+ eager: !1,
1364
+ strictVersion: !1,
1365
+ requiredVersion: "~11.11.0"
1366
+ }
1367
+ },
1368
+ {
1369
+ libraryName: "@emotion/react",
1370
+ sharedConfig: {
1371
+ singleton: !0,
1372
+ eager: !1,
1373
+ strictVersion: !1,
1374
+ requiredVersion: "~11.11.0"
1375
+ }
1376
+ },
1377
+ {
1378
+ libraryName: "reflect-metadata",
1379
+ sharedConfig: {
1380
+ singleton: !0,
1381
+ eager: !1,
1382
+ strictVersion: !1,
1383
+ requiredVersion: "^0.2.2"
1384
+ }
1385
+ },
1386
+ {
1387
+ libraryName: "mobx",
1388
+ sharedConfig: {
1389
+ singleton: !0,
1390
+ eager: !1,
1391
+ strictVersion: !1,
1392
+ requiredVersion: "^6.9.0"
1393
+ }
1394
+ },
1395
+ {
1396
+ libraryName: "loglevel",
1397
+ sharedConfig: {
1398
+ singleton: !0,
1399
+ eager: !1,
1400
+ strictVersion: !1,
1401
+ requiredVersion: "^1.8.1"
1402
+ }
1403
+ },
1404
+ {
1405
+ libraryName: "robot3",
1406
+ sharedConfig: {
1407
+ singleton: !0,
1408
+ eager: !1,
1409
+ strictVersion: !1,
1410
+ requiredVersion: "^0.4.0"
1411
+ }
1412
+ },
1413
+ {
1414
+ libraryName: "mobx-react-lite",
1415
+ sharedConfig: {
1416
+ singleton: !0,
1417
+ eager: !1,
1418
+ strictVersion: !1,
1419
+ requiredVersion: "^3.4.3"
1420
+ }
1421
+ },
1422
+ {
1423
+ libraryName: "react-router-dom",
1424
+ sharedConfig: {
1425
+ singleton: !0,
1426
+ eager: !1,
1427
+ strictVersion: !1,
1428
+ requiredVersion: "^6.11.2"
1429
+ }
1430
+ },
1431
+ {
1432
+ libraryName: "date-fns",
1433
+ sharedConfig: {
1434
+ singleton: !0,
1435
+ eager: !1,
1436
+ strictVersion: !1,
1437
+ requiredVersion: "^2.30.0"
1438
+ }
1439
+ },
1440
+ {
1441
+ libraryName: "@use-gesture/react",
1442
+ sharedConfig: {
1443
+ singleton: !0,
1444
+ eager: !1,
1445
+ strictVersion: !1,
1446
+ requiredVersion: "^10.3.0"
1447
+ }
1448
+ },
1449
+ {
1450
+ libraryName: "@react-spring/web",
1451
+ sharedConfig: {
1452
+ singleton: !0,
1453
+ eager: !1,
1454
+ strictVersion: !1,
1455
+ requiredVersion: "^9.7.3"
1456
+ }
1457
+ },
1458
+ {
1459
+ libraryName: "react-simple-keyboard",
1460
+ sharedConfig: {
1461
+ singleton: !0,
1462
+ eager: !1,
1463
+ strictVersion: !1,
1464
+ requiredVersion: "^3.6.13"
1465
+ }
1466
+ },
1467
+ {
1468
+ libraryName: "expr-eval",
1469
+ sharedConfig: {
1470
+ singleton: !0,
1471
+ eager: !1,
1472
+ strictVersion: !1,
1473
+ requiredVersion: "^2.0.2"
1474
+ }
1475
+ },
1476
+ {
1477
+ libraryName: "zod",
1478
+ sharedConfig: {
1479
+ singleton: !0,
1480
+ eager: !0,
1481
+ strictVersion: !1,
1482
+ requiredVersion: "^3.25.0"
1483
+ }
1484
+ }
1485
+ ]
1486
+ };
1487
+ }
1488
+ const Z = V.object({
1489
+ id: V.string().min(1, "ID is required").describe("Unique identifier for this extension"),
1490
+ title: V.string().min(1, "Title is required").describe("Display title shown in the interface"),
1491
+ namespace: V.string().min(1, "Namespace is required").describe("Namespace for organizing related extensions"),
1492
+ experienceId: V.string().min(1, "Experience ID is required").describe("Reference to the UI component experience for rendering")
1493
+ }), Ke = Z.extend({
1494
+ rank: V.number().int().min(0).optional().describe("Optional ranking for ordering (higher = preferred)")
1495
+ });
1496
+ function Qe(n, e, t) {
1497
+ const i = n.safeParse(e);
1498
+ return i.success ? !0 : (i.error.errors.forEach((s) => {
1499
+ t.addError(`${s.path.join(".")}: ${s.message}`);
1500
+ }), !1);
1501
+ }
1502
+ function Xe(n, e, t) {
1503
+ e && !e.includes(".") && t.addWarning(
1504
+ `${n} '${e}' should typically include dot notation (e.g., 'category.item')`
1505
+ );
1506
+ }
1507
+ function Le(n, e, t = 1e3) {
1508
+ n !== void 0 && n > t && e.addWarning(
1509
+ `Rank ${n} seems unusually high - consider using lower values for better ordering`
1510
+ );
1511
+ }
1512
+ function et(n, e = {}) {
1513
+ return (e.rankable ? Ke : Z).extend(n);
1514
+ }
1515
+ function tt(n, e, t = 1e3) {
1516
+ typeof n == "object" && n !== null && "rank" in n && Le(n.rank, e, t);
1517
+ }
1518
+ class q {
1519
+ /**
1520
+ * Get all extension points with their plugin information
1521
+ */
1522
+ static getExtensionPoints(e, t = {}) {
1523
+ const {
1524
+ includeLegacyExtensions: i = !0,
1525
+ includeEmptyExtensionPoints: s = !0
1526
+ } = t, r = C().getAllExtensionPoints(), a = [];
1527
+ return r.forEach((c) => {
1528
+ const l = Object.values((e == null ? void 0 : e[c.id]) || {});
1529
+ !s && l.length === 0 || a.push({
1530
+ id: c.id,
1531
+ displayName: c.config.displayName,
1532
+ description: c.config.description,
1533
+ source: "simplified",
1534
+ metadata: c.config.metadata,
1535
+ pluginCount: l.length,
1536
+ plugins: l
1537
+ });
1538
+ }), i && e && Object.entries(e).forEach(([c, l]) => {
1539
+ if (a.some((d) => d.id === c))
1540
+ return;
1541
+ const u = Object.values(l || {});
1542
+ !s && u.length === 0 || a.push({
1543
+ id: c,
1544
+ source: "legacy",
1545
+ pluginCount: u.length,
1546
+ plugins: u
1547
+ });
1548
+ }), a.sort((c, l) => c.id.localeCompare(l.id));
1549
+ }
1550
+ /**
1551
+ * Filter extension points based on search criteria
1552
+ */
1553
+ static filterExtensionPoints(e, t) {
1554
+ if (!t.trim())
1555
+ return e;
1556
+ const i = t.toLowerCase();
1557
+ return e.filter(
1558
+ (s) => {
1559
+ var o, r, a, c, l, u;
1560
+ return s.id.toLowerCase().includes(i) || ((o = s.displayName) == null ? void 0 : o.toLowerCase().includes(i)) || ((r = s.description) == null ? void 0 : r.toLowerCase().includes(i)) || ((c = (a = s.metadata) == null ? void 0 : a.category) == null ? void 0 : c.toLowerCase().includes(i)) || ((u = (l = s.metadata) == null ? void 0 : l.tags) == null ? void 0 : u.some((d) => d.toLowerCase().includes(i)));
1561
+ }
1562
+ );
1563
+ }
1564
+ /**
1565
+ * Calculate health statistics for the plugin system
1566
+ */
1567
+ static calculateHealthStats(e) {
1568
+ const t = e.length, i = e.filter(
1569
+ (c) => c.pluginCount > 0
1570
+ ).length, s = e.reduce(
1571
+ (c, l) => c + l.pluginCount,
1572
+ 0
1573
+ ), o = e.filter(
1574
+ (c) => c.source === "simplified"
1575
+ ).length, r = e.filter(
1576
+ (c) => c.source === "legacy"
1577
+ ).length, a = e.filter(
1578
+ (c) => {
1579
+ var l;
1580
+ return (l = c.metadata) == null ? void 0 : l.deprecated;
1581
+ }
1582
+ ).length;
1583
+ return {
1584
+ totalExtensionPoints: t,
1585
+ extensionPointsWithPlugins: i,
1586
+ totalPlugins: s,
1587
+ simplifiedExtensionPoints: o,
1588
+ legacyExtensionPoints: r,
1589
+ deprecatedExtensionPoints: a
1590
+ };
1591
+ }
1592
+ /**
1593
+ * Analyze a specific plugin for health and capabilities
1594
+ */
1595
+ static analyzePlugin(e) {
1596
+ const t = !!e.component, i = typeof e.rank == "number", s = e.rank || 0, o = [];
1597
+ if (t ? o.push("UI Component") : o.push("Background Service"), i && o.push(`Rank: ${s}`), e.namespace) {
1598
+ const a = e.namespace;
1599
+ a.includes("kos") || a.includes("ddk") ? o.push("First-party") : o.push("Third-party");
1600
+ }
1601
+ e.modalMode && o.push(`Modal: ${e.modalMode}`);
1602
+ let r = "healthy";
1603
+ return e.remote || (r = "warning"), {
1604
+ hasComponent: t,
1605
+ hasRank: i,
1606
+ healthStatus: r,
1607
+ capabilities: o
1608
+ };
1609
+ }
1610
+ /**
1611
+ * Get extension point by ID with detailed information
1612
+ */
1613
+ static getExtensionPointById(e, t) {
1614
+ return e.find((i) => i.id === t);
1615
+ }
1616
+ /**
1617
+ * Validate if an extension point ID follows conventions
1618
+ */
1619
+ static validateExtensionPointId(e) {
1620
+ const t = [], i = [];
1621
+ e.includes(".") || (t.push(
1622
+ "Extension point ID should contain at least one dot (namespace.feature)"
1623
+ ), i.push('Use format like "ddk.myFeature" or "app.myFeature"'));
1624
+ const s = e.split(".");
1625
+ s.length < 2 && t.push(
1626
+ "Extension point ID should have at least 2 parts (namespace.feature)"
1627
+ );
1628
+ const o = s[0];
1629
+ return o && !["ddk", "cui", "app"].includes(o) && !o.endsWith("app") && i.push(
1630
+ "Consider using standard namespaces: ddk, cui, or [appname]app"
1631
+ ), s.some((a) => /[A-Z]/.test(a)) && (t.push("Extension point ID parts should be lowercase"), i.push(
1632
+ 'Use kebab-case or dot notation: "my.feature" not "my.myFeature"'
1633
+ )), {
1634
+ isValid: t.length === 0,
1635
+ issues: t,
1636
+ suggestions: i
1637
+ };
1638
+ }
1639
+ /**
1640
+ * Validate a plugin descriptor structure and content
1641
+ */
1642
+ static validatePluginDescriptor(e) {
1643
+ const t = [], i = [], s = [], o = [];
1644
+ if (e.id ? e.id.match(/^[a-z0-9-]+$/) || o.push(
1645
+ "Plugin ID convention: use lowercase letters, numbers, and hyphens (e.g., 'my-awesome-plugin')"
1646
+ ) : (s.push("id"), t.push("Plugin descriptor must have an 'id' field")), !e.contributes)
1647
+ i.push(
1648
+ "Plugin has no contributions - it won't extend any functionality"
1649
+ ), o.push("Add a 'contributes' section with plugin contributions");
1650
+ else {
1651
+ const r = Object.keys(e.contributes);
1652
+ r.length === 0 && i.push("Plugin contributes section is empty"), r.forEach((a) => {
1653
+ const c = e.contributes[a];
1654
+ if (!Array.isArray(c)) {
1655
+ t.push(`Contribution '${a}' must be an array`);
1656
+ return;
1657
+ }
1658
+ c.forEach((l, u) => {
1659
+ l.id || t.push(
1660
+ `Contribution ${a}[${u}] missing required 'id' field`
1661
+ ), a === "experiences" && l.component && !l.location && (t.push(
1662
+ `Experience '${l.id}' has component but no location`
1663
+ ), o.push(
1664
+ "Add 'location' field pointing to the component file"
1665
+ )), ["cui", "utilities", "settings", "setup"].includes(a) && (l.title || i.push(
1666
+ `${a} contribution '${l.id}' missing 'title' field`
1667
+ ), l.namespace || i.push(
1668
+ `${a} contribution '${l.id}' missing 'namespace' field`
1669
+ ), l.experienceId || t.push(
1670
+ `${a} contribution '${l.id}' missing required 'experienceId' field`
1671
+ ));
1672
+ });
1673
+ });
1674
+ }
1675
+ return e.init !== void 0 && typeof e.init != "boolean" && t.push("'init' field must be a boolean value"), {
1676
+ isValid: t.length === 0 && s.length === 0,
1677
+ errors: t,
1678
+ warnings: i,
1679
+ missingRequired: s,
1680
+ suggestions: o
1681
+ };
1682
+ }
1683
+ /**
1684
+ * Check compatibility between plugin contributions and available extension points
1685
+ */
1686
+ static checkPluginCompatibility(e, t) {
1687
+ const i = [], s = [], o = [], r = [];
1688
+ if (!e.contributes)
1689
+ return {
1690
+ isCompatible: !0,
1691
+ issues: ["Plugin has no contributions to check"],
1692
+ missingExtensionPoints: [],
1693
+ incompatibleTypes: [],
1694
+ suggestions: []
1695
+ };
1696
+ const a = C(), c = new Set(
1697
+ t.map((l) => l.id)
1698
+ );
1699
+ return Object.entries(e.contributes).forEach(
1700
+ ([l, u]) => {
1701
+ this.getExpectedExtensionPoints(l).forEach((g) => {
1702
+ c.has(g) || (s.push(g), i.push(
1703
+ `Extension point '${g}' not available for '${l}' contributions`
1704
+ ), r.push(
1705
+ `Ensure the extension point '${g}' is registered`
1706
+ ));
1707
+ });
1708
+ const f = a.getAllExtensionPoints().find(
1709
+ (g) => g.config.contributionKey === l
1710
+ );
1711
+ f && u.length > 0 && u.forEach((g, w) => {
1712
+ f.config.isRankable && typeof g.rank != "number" && (i.push(
1713
+ `${l}[${w}]: Extension point '${f.id}' expects 'rank' property`
1714
+ ), r.push(
1715
+ "Add 'rank' property with numeric value for ordering"
1716
+ )), f.config.hasView && !g.experienceId && (i.push(
1717
+ `${l}[${w}]: Extension point '${f.id}' expects 'experienceId' for view-based contributions`
1718
+ ), r.push(
1719
+ "Add 'experienceId' property linking to an experience definition"
1720
+ ));
1721
+ });
1722
+ }
1723
+ ), {
1724
+ isCompatible: i.length === 0,
1725
+ issues: i,
1726
+ missingExtensionPoints: s,
1727
+ incompatibleTypes: o,
1728
+ suggestions: r
1729
+ };
1730
+ }
1731
+ /**
1732
+ * Map contribution keys to their expected extension point IDs
1733
+ */
1734
+ static getExpectedExtensionPoints(e) {
1735
+ return {
1736
+ cui: ["ddk.cui", "ddk.cui.view", "ddk.cui.settings.config"],
1737
+ utilities: ["ddk.utility", "ddk.utility.view", "ddk.utilities"],
1738
+ setup: ["ddk.setup", "ddk.setup.view"],
1739
+ settings: ["ddk.settings", "ddk.settings.view"],
1740
+ troubleActions: ["ddk.troubleAction", "ddk.troubleAction.view"],
1741
+ navViews: ["ddk.nav", "ddk.nav.view"],
1742
+ controlPour: ["ddk.controlPour", "ddk.controlPour.view"],
1743
+ experiences: [],
1744
+ // Experiences don't directly map to extension points
1745
+ views: []
1746
+ // Views are mapped by their extension point ID keys
1747
+ }[e] || [];
1748
+ }
1749
+ /**
1750
+ * Get comprehensive plugin analysis including validation and compatibility
1751
+ */
1752
+ static analyzePluginDescriptor(e, t) {
1753
+ const i = this.validatePluginDescriptor(e), s = this.checkPluginCompatibility(
1754
+ e,
1755
+ t
1756
+ ), o = [];
1757
+ return i.warnings.length > 0 && o.push(
1758
+ "Address validation warnings to improve plugin quality"
1759
+ ), s.isCompatible || o.push(
1760
+ "Resolve compatibility issues before deploying plugin"
1761
+ ), e.contributes && Object.keys(e.contributes).length === 1 && o.push(
1762
+ "Consider adding more contribution types to increase plugin value"
1763
+ ), {
1764
+ validation: i,
1765
+ compatibility: s,
1766
+ recommendations: o
1767
+ };
1768
+ }
1769
+ }
1770
+ class nt {
1771
+ /**
1772
+ * Generate complete documentation for all extension points
1773
+ */
1774
+ static generateFullDocumentation(e, t = {}) {
1775
+ const {
1776
+ includeUsageExamples: i = !0,
1777
+ includeTypeDefinitions: s = !0,
1778
+ includeLegacyExtensions: o = !0,
1779
+ includePluginHealth: r = !0
1780
+ } = t, a = q.getExtensionPoints(
1781
+ e,
1782
+ {
1783
+ includeLegacyExtensions: o,
1784
+ includeEmptyExtensionPoints: !0
1785
+ }
1786
+ ), c = q.calculateHealthStats(a);
1787
+ let l = this.generateHeader(c);
1788
+ return l += this.generateTableOfContents(a), l += this.generateOverviewSection(a, c), a.forEach((u) => {
1789
+ l += this.generateExtensionPointSection(u, {
1790
+ includeUsageExamples: i,
1791
+ includePluginHealth: r
1792
+ });
1793
+ }), s && (l += this.generateTypeDefinitionsSection(a)), l += this.generateContributionGuide(), l += this.generateTroubleshootingSection(), {
1794
+ content: l,
1795
+ metadata: {
1796
+ generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
1797
+ totalExtensionPoints: c.totalExtensionPoints,
1798
+ totalPlugins: c.totalPlugins,
1799
+ simplifiedExtensionPoints: c.simplifiedExtensionPoints,
1800
+ legacyExtensionPoints: c.legacyExtensionPoints
1801
+ }
1802
+ };
1803
+ }
1804
+ /**
1805
+ * Generate documentation header with metadata
1806
+ */
1807
+ static generateHeader(e) {
1808
+ return `# KOS Plugin Extension Points Reference
1809
+
1810
+ **Generated**: ${(/* @__PURE__ */ new Date()).toLocaleString()}
1811
+
1812
+ ## System Overview
1813
+
1814
+ - **Total Extension Points**: ${e.totalExtensionPoints}
1815
+ - **Extension Points with Plugins**: ${e.extensionPointsWithPlugins}
1816
+ - **Total Active Plugins**: ${e.totalPlugins}
1817
+ - **Simplified Extension Points**: ${e.simplifiedExtensionPoints}
1818
+ - **Legacy Extension Points**: ${e.legacyExtensionPoints}
1819
+
1820
+ ---
1821
+
1822
+ `;
1823
+ }
1824
+ /**
1825
+ * Generate table of contents
1826
+ */
1827
+ static generateTableOfContents(e) {
1828
+ let t = `## Table of Contents
1829
+
1830
+ `;
1831
+ return t += `- [Overview](#overview)
1832
+ `, t += `- [Extension Points](#extension-points)
1833
+ `, e.forEach((i) => {
1834
+ const s = i.id.toLowerCase().replace(/\./g, "");
1835
+ t += ` - [${i.id}](#${s}) (${i.pluginCount} plugins)
1836
+ `;
1837
+ }), t += `- [Type Definitions](#type-definitions)
1838
+ `, t += `- [Contribution Guide](#contribution-guide)
1839
+ `, t += `- [Troubleshooting](#troubleshooting)
1840
+
1841
+ `, t;
1842
+ }
1843
+ /**
1844
+ * Generate overview section with health statistics
1845
+ */
1846
+ static generateOverviewSection(e, t) {
1847
+ let i = `## Overview
1848
+
1849
+ `;
1850
+ return i += "This document provides a comprehensive reference for all available extension points in the KOS plugin system. ", i += `Extension points allow plugins to contribute functionality to the application.
1851
+
1852
+ `, i += `### Extension Point Types
1853
+
1854
+ `, i += "- ** Simplified Extension Points**: Use the new simplified API from `defineExtensionPoint`\n", i += `- ** Legacy Extension Points**: Use the traditional reducer-based system
1855
+
1856
+ `, t.deprecatedExtensionPoints > 0 && (i += `### ⚠️ Deprecated Extension Points
1857
+
1858
+ `, i += `${t.deprecatedExtensionPoints} extension points are marked as deprecated. `, i += `Consider migrating to newer alternatives.
1859
+
1860
+ `), i + `---
1861
+
1862
+ `;
1863
+ }
1864
+ /**
1865
+ * Generate documentation section for a single extension point
1866
+ */
1867
+ static generateExtensionPointSection(e, t) {
1868
+ var r;
1869
+ const { includeUsageExamples: i = !0, includePluginHealth: s = !0 } = t;
1870
+ let o = `## ${e.id}
1871
+
1872
+ `;
1873
+ if (e.displayName && (o += `**Display Name**: ${e.displayName}
1874
+
1875
+ `), e.description && (o += `**Description**: ${e.description}
1876
+
1877
+ `), o += `**Source**: ${e.source}
1878
+ `, o += `**Active Plugins**: ${e.pluginCount}
1879
+
1880
+ `, e.metadata) {
1881
+ o += `### Metadata
1882
+
1883
+ `;
1884
+ const a = e.metadata;
1885
+ a.category && (o += `- **Category**: ${a.category}
1886
+ `), a.owner && (o += `- **Owner**: ${a.owner}
1887
+ `), a.since && (o += `- **Since**: ${a.since}
1888
+ `), (r = a.tags) != null && r.length && (o += `- **Tags**: ${a.tags.join(", ")}
1889
+ `), a.deprecated && (o += `- **⚠️ Status**: Deprecated
1890
+ `), o += `
1891
+ `;
1892
+ }
1893
+ return i && (o += this.generateUsageExamples(e)), e.plugins.length > 0 ? o += this.generatePluginList(
1894
+ e.plugins,
1895
+ s
1896
+ ) : o += `### Plugins
1897
+
1898
+ No plugins currently registered for this extension point.
1899
+
1900
+ `, o += this.generateSchemaFieldsSection(e), o += this.generateContributionStructure(e), o + `---
1901
+
1902
+ `;
1903
+ }
1904
+ /**
1905
+ * Generate usage examples for an extension point
1906
+ */
1907
+ static generateUsageExamples(e) {
1908
+ let t = `### Usage Examples
1909
+
1910
+ `;
1911
+ return e.source === "simplified" && (t += `#### Using Simplified API
1912
+
1913
+ `, t += "```typescript\n", t += `// Import the extension point
1914
+ `, t += `import { ${this.getExtensionPointImportName(
1915
+ e.id
1916
+ )} } from './extension-points';
1917
+
1918
+ `, t += `// Use extension component hook
1919
+ `, t += `import { useExtensionComponent } from '@kosdev-code/kos-ui-plugin';
1920
+
1921
+ `, t += `const Component = useExtensionComponent(${this.getExtensionPointImportName(
1922
+ e.id
1923
+ )});
1924
+
1925
+ `, t += `if (Component) {
1926
+ `, t += ` return (
1927
+ `, t += ` <Component
1928
+ `, t += ` customProp="value"
1929
+ `, t += ` onComplete={handleComplete}
1930
+ `, t += ` />
1931
+ `, t += ` );
1932
+ `, t += `}
1933
+
1934
+ `, t += `// Or use with dynamic component
1935
+ `, t += `const [Component] = useDynamicComponent({
1936
+ `, t += ` extension: ${this.getExtensionPointImportName(
1937
+ e.id
1938
+ )}.id
1939
+ `, t += `});
1940
+ `, t += "```\n\n", t += `#### Using Typed Hooks
1941
+
1942
+ `, t += "```typescript\n", t += `// Get all extensions with type safety
1943
+ `, t += `const extensions = useExtensions(${this.getExtensionPointImportName(
1944
+ e.id
1945
+ )});
1946
+
1947
+ `, t += `// Get best extension
1948
+ `, t += `const bestExtension = useBest(${this.getExtensionPointImportName(
1949
+ e.id
1950
+ )});
1951
+
1952
+ `, t += `// Check availability
1953
+ `, t += `const hasExtensions = useHasExtensions(${this.getExtensionPointImportName(
1954
+ e.id
1955
+ )});
1956
+ `, t += "```\n\n"), t += `#### Using DynamicComponent
1957
+
1958
+ `, t += "```typescript\n", t += `import { DynamicComponent } from '@kosdev-code/kos-ui-plugin';
1959
+ `, t += `import { ${this.getExtensionPointImportName(
1960
+ e.id
1961
+ )} } from './extension-points';
1962
+
1963
+ `, t += `<DynamicComponent
1964
+ `, t += ` extension={${this.getExtensionPointImportName(
1965
+ e.id
1966
+ )}.id}
1967
+ `, t += ` props={{ customData: "value" }}
1968
+ `, t += ` fallback={<div>Loading...</div>}
1969
+ `, t += `/>
1970
+ `, t += "```\n\n", t += `#### Using Context
1971
+
1972
+ `, t += "```typescript\n", t += `import { useKosPluginsContext } from '@kosdev-code/kos-ui-plugin';
1973
+ `, t += `import { ${this.getExtensionPointImportName(
1974
+ e.id
1975
+ )} } from './extension-points';
1976
+
1977
+ `, t += `const { getExtensions } = useKosPluginsContext();
1978
+ `, t += `const extensions = getExtensions(${this.getExtensionPointImportName(
1979
+ e.id
1980
+ )}.id);
1981
+ `, t += "```\n\n", t;
1982
+ }
1983
+ /**
1984
+ * Generate plugin list with health information
1985
+ */
1986
+ static generatePluginList(e, t) {
1987
+ let i = `### Active Plugins
1988
+
1989
+ `;
1990
+ return e.forEach((s) => {
1991
+ if (i += `#### ${s.id}
1992
+
1993
+ `, s.remote && (i += `- **Remote**: ${s.remote}
1994
+ `), s.sectionId && (i += `- **Section**: ${s.sectionId}
1995
+ `), s.rank !== void 0 && (i += `- **Rank**: ${s.rank}
1996
+ `), t) {
1997
+ const o = q.analyzePlugin(s);
1998
+ i += `- **Health**: ${this.getHealthEmoji(o.healthStatus)} ${o.healthStatus}
1999
+ `, o.capabilities.length > 0 && (i += `- **Capabilities**: ${o.capabilities.join(", ")}
2000
+ `);
2001
+ }
2002
+ i += `
2003
+ `;
2004
+ }), i;
2005
+ }
2006
+ /**
2007
+ * Generate schema fields documentation
2008
+ */
2009
+ static generateSchemaFieldsSection(e) {
2010
+ if (e.source !== "simplified")
2011
+ return "";
2012
+ const i = C().getExtensionPoint(e.id);
2013
+ if (!(i != null && i.getSchemaFieldInfo))
2014
+ return "";
2015
+ const s = i.getSchemaFieldInfo();
2016
+ if (s.length === 0)
2017
+ return "";
2018
+ let o = `### Schema Fields
2019
+
2020
+ `;
2021
+ return o += `The following fields are defined in the schema for this extension point:
2022
+
2023
+ `, o += `| Field | Type | Required | Description |
2024
+ `, o += `|-------|------|----------|-------------|
2025
+ `, s.forEach((r) => {
2026
+ const a = r.name, c = r.type || "unknown", l = r.required ? "✅" : "⭕", u = r.description || "-";
2027
+ o += `| \`${a}\` | ${c} | ${l} | ${u} |
2028
+ `;
2029
+ }), o += `
2030
+ `, o;
2031
+ }
2032
+ /**
2033
+ * Generate contribution structure documentation
2034
+ */
2035
+ static generateContributionStructure(e) {
2036
+ let t = `### Contribution Structure
2037
+
2038
+ `;
2039
+ t += `To contribute to this extension point, add the following to your plugin descriptor:
2040
+
2041
+ `, t += "```json\n", t += `{
2042
+ `, t += ` "id": "your-plugin-id",
2043
+ `, t += ` "contributes": {
2044
+ `;
2045
+ const i = this.inferContributionKey(e);
2046
+ t += ` "${i}": [
2047
+ `, t += ` {
2048
+ `;
2049
+ const s = this.getSchemaFieldsForContribution(e);
2050
+ if (s.length > 0) {
2051
+ const r = [];
2052
+ s.forEach((a) => {
2053
+ let c;
2054
+ a.name === "id" ? c = '"your-contribution-id"' : a.name === "title" ? c = '"Your Contribution Title"' : a.name === "namespace" ? c = '"your-namespace"' : a.name === "experienceId" ? c = '"your-experience-id"' : a.name === "dashboardKey" ? c = '"your-dashboard-key"' : a.name === "rank" ? c = "10" : a.type === "string" ? c = `"your-${a.name}"` : a.type === "number" ? c = "0" : a.type === "boolean" ? c = "false" : c = `"your-${a.name}"`, (a.required || ["experienceId", "rank", "dashboardKey"].includes(a.name)) && r.push(` "${a.name}": ${c}`);
2055
+ }), t += r.join(`,
2056
+ `);
2057
+ } else {
2058
+ t += ` "id": "your-contribution-id",
2059
+ `, t += ` "title": "Your Contribution Title",
2060
+ `, t += ' "namespace": "your-namespace"', this.isViewBasedExtensionPoint(e) && (t += `,
2061
+ "experienceId": "your-experience-id"`), this.isRankableExtensionPoint(e) && (t += `,
2062
+ "rank": 10`);
2063
+ const r = this.getSpecificFields(e);
2064
+ r.length > 0 && (t += `,
2065
+ ${r.join(`,
2066
+ `)}`);
2067
+ }
2068
+ return t += `
2069
+ }
2070
+ `, t += " ]", (s.some((r) => r.name === "experienceId") || this.isViewBasedExtensionPoint(e)) && (t += `,
2071
+ "experiences": {
2072
+ `, t += ` "your-experience-id": {
2073
+ `, t += ` "id": "your-experience-id",
2074
+ `, t += ` "component": "YourComponent",
2075
+ `, t += ` "location": "./src/components/YourComponent.tsx"
2076
+ `, t += ` }
2077
+ `, t += " }"), t += `
2078
+ }
2079
+ `, t += `}
2080
+ `, t += "```\n\n", t;
2081
+ }
2082
+ /**
2083
+ * Generate TypeScript definitions section
2084
+ */
2085
+ static generateTypeDefinitionsSection(e) {
2086
+ let t = `## Type Definitions
2087
+
2088
+ `;
2089
+ return t += `### Extension Point Types
2090
+
2091
+ `, t += "```typescript\n", e.forEach((i) => {
2092
+ i.source === "simplified" && (t += `// ${i.id}
2093
+ `, t += `interface ${this.getExtensionPointTypeName(i.id)} {
2094
+ `, t += ` id: "${i.id}";
2095
+ `, t += ` displayName?: "${i.displayName || ""}";
2096
+ `, t += ` description?: "${i.description || ""}";
2097
+ `, t += `}
2098
+
2099
+ `);
2100
+ }), t += "```\n\n", t += `### Plugin Contribution Types
2101
+
2102
+ `, t += "```typescript\n", t += `interface BaseContribution {
2103
+ `, t += ` id: string;
2104
+ `, t += ` title: string;
2105
+ `, t += ` namespace: string;
2106
+ `, t += `}
2107
+
2108
+ `, t += `interface ViewBasedContribution extends BaseContribution {
2109
+ `, t += ` experienceId: string;
2110
+ `, t += `}
2111
+
2112
+ `, t += `interface RankableContribution extends BaseContribution {
2113
+ `, t += ` rank: number;
2114
+ `, t += `}
2115
+ `, t += "```\n\n", t;
2116
+ }
2117
+ /**
2118
+ * Generate contribution guide
2119
+ */
2120
+ static generateContributionGuide() {
2121
+ return `## Contribution Guide
2122
+
2123
+ ### Creating a Plugin
2124
+
2125
+ 1. **Create Plugin Project**
2126
+ \`\`\`bash
2127
+ kosui plugin-project --name my-plugin
2128
+ \`\`\`
2129
+
2130
+ 2. **Add Components**
2131
+ \`\`\`bash
2132
+ kosui component --name MyComponent --pluginType utility --project my-plugin
2133
+ \`\`\`
2134
+
2135
+ 3. **Update Plugin Descriptor**
2136
+ Add contributions to your \`kosdev-plugin.json\` file following the structure examples above.
2137
+
2138
+ 4. **Test Integration**
2139
+ Use the Plugin Explorer (Ctrl+Shift+P) to validate your plugin registration.
2140
+
2141
+ ### Best Practices
2142
+
2143
+ - **Use descriptive IDs**: Plugin and contribution IDs should be clear and unique
2144
+ - **Follow naming conventions**: Use kebab-case for IDs, PascalCase for components
2145
+ - **Provide meaningful titles**: Titles are shown to users in the interface
2146
+ - **Set appropriate ranks**: Higher numbers = higher priority for rankable contributions
2147
+ - **Include proper metadata**: Namespace helps organize plugins by owner
2148
+
2149
+ ### Validation
2150
+
2151
+ Use the Plugin Discovery Service to validate your plugin descriptor:
2152
+
2153
+ \`\`\`typescript
2154
+ import { PluginDiscoveryService } from '@kosdev-code/kos-ui-plugin';
2155
+
2156
+ const validation = PluginDiscoveryService.validatePluginDescriptor(yourDescriptor);
2157
+ console.log(validation.errors); // Check for errors
2158
+ console.log(validation.warnings); // Check for warnings
2159
+ \`\`\`
2160
+
2161
+ `;
2162
+ }
2163
+ /**
2164
+ * Generate troubleshooting section
2165
+ */
2166
+ static generateTroubleshootingSection() {
2167
+ return `## Troubleshooting
2168
+
2169
+ ### Common Issues
2170
+
2171
+ **Plugin not appearing in extension point**
2172
+ - Check plugin descriptor syntax
2173
+ - Verify contribution key matches extension point requirements
2174
+ - Ensure experienceId references exist in experiences section
2175
+
2176
+ **Component fails to load**
2177
+ - Verify component path in experience location
2178
+ - Check module federation configuration
2179
+ - Use Plugin Explorer to see detailed error messages
2180
+
2181
+ **Type errors with simplified extension points**
2182
+ - Ensure extension point is properly imported
2183
+ - Check that component props match expected interface
2184
+ - Verify extension point is registered before use
2185
+
2186
+ ### Debugging Tools
2187
+
2188
+ **Plugin Explorer**
2189
+ - Press Ctrl+Shift+P in development mode
2190
+ - View all extension points and their plugins
2191
+ - See plugin health status and capabilities
2192
+ - Test component rendering with error boundaries
2193
+
2194
+ **Validation Service**
2195
+ - Use \`PluginDiscoveryService.validatePluginDescriptor()\`
2196
+ - Check \`PluginDiscoveryService.checkPluginCompatibility()\`
2197
+ - Run \`PluginDiscoveryService.analyzePluginDescriptor()\` for full analysis
2198
+
2199
+ **Browser DevTools**
2200
+ - Check \`window.KosPlugins.extensions\` for runtime state
2201
+ - Look for module federation errors in Network tab
2202
+ - Use React DevTools to inspect component loading
2203
+
2204
+ ---
2205
+
2206
+ *Generated by KOS Plugin Documentation Generator*
2207
+ `;
2208
+ }
2209
+ // Helper methods
2210
+ static getExtensionPointImportName(e) {
2211
+ var r;
2212
+ const i = C().getExtensionPoint(e);
2213
+ if ((r = i == null ? void 0 : i.config.metadata) != null && r.exportName)
2214
+ return i.config.metadata.exportName;
2215
+ const s = e.split(".");
2216
+ return (s.length > 1 ? s.slice(1) : s).map(
2217
+ (a) => (
2218
+ // Handle hyphenated parts (e.g., "pump-detail" -> "PumpDetail")
2219
+ a.split("-").map((c) => c.charAt(0).toUpperCase() + c.slice(1)).join("")
2220
+ )
2221
+ ).join("") + "Extension";
2222
+ }
2223
+ static getExtensionPointTypeName(e) {
2224
+ return this.getExtensionPointImportName(e) + "Type";
2225
+ }
2226
+ static getHealthEmoji(e) {
2227
+ switch (e) {
2228
+ case "healthy":
2229
+ return "✅";
2230
+ case "warning":
2231
+ return "⚠️";
2232
+ case "error":
2233
+ return "❌";
2234
+ default:
2235
+ return "❓";
2236
+ }
2237
+ }
2238
+ static inferContributionKey(e) {
2239
+ if (e.source === "simplified") {
2240
+ const r = C().getExtensionPoint(e.id);
2241
+ if (r != null && r.config.contributionKey)
2242
+ return r.config.contributionKey;
2243
+ }
2244
+ const t = e.id.split("."), i = t[t.length - 1];
2245
+ return {
2246
+ cui: "cui",
2247
+ utility: "utilities",
2248
+ utilities: "utilities",
2249
+ setup: "setupStep",
2250
+ settings: "settings",
2251
+ nav: "navViews",
2252
+ troubleAction: "troubleActions",
2253
+ controlPour: "controlPour"
2254
+ }[i] || i + "s";
2255
+ }
2256
+ static isViewBasedExtensionPoint(e) {
2257
+ if (e.source === "simplified") {
2258
+ const i = C().getExtensionPoint(e.id);
2259
+ return (i == null ? void 0 : i.config.hasView) || !1;
2260
+ }
2261
+ return e.plugins.some(
2262
+ (t) => t.experienceId
2263
+ );
2264
+ }
2265
+ static isRankableExtensionPoint(e) {
2266
+ if (e.source === "simplified") {
2267
+ const i = C().getExtensionPoint(e.id);
2268
+ return (i == null ? void 0 : i.config.isRankable) || !1;
2269
+ }
2270
+ return e.plugins.some(
2271
+ (t) => typeof t.rank == "number"
2272
+ );
2273
+ }
2274
+ /**
2275
+ * Get schema fields for contribution structure generation
2276
+ */
2277
+ static getSchemaFieldsForContribution(e) {
2278
+ if (e.source !== "simplified")
2279
+ return [];
2280
+ const i = C().getExtensionPoint(e.id);
2281
+ return i != null && i.getSchemaFieldInfo ? i.getSchemaFieldInfo() : [];
2282
+ }
2283
+ static getSpecificFields(e) {
2284
+ const t = [];
2285
+ switch (this.inferContributionKey(e)) {
2286
+ case "utilities":
2287
+ t.push('"utilDescriptor": "your-util-descriptor"');
2288
+ break;
2289
+ case "setupStep":
2290
+ t.push('"setupDescriptor": "your-setup-descriptor"');
2291
+ break;
2292
+ case "settings":
2293
+ t.push('"settingsGroup": "your-settings-group"');
2294
+ break;
2295
+ case "navViews":
2296
+ t.push('"navDescriptor": "your-nav-descriptor"');
2297
+ break;
2298
+ case "troubleActions":
2299
+ t.push('"troubleType": "your-trouble-type"');
2300
+ break;
2301
+ case "cui":
2302
+ t.push('"cuiDescriptor": "your-cui-descriptor"');
2303
+ break;
2304
+ }
2305
+ return t;
2306
+ }
2307
+ }
2308
+ export {
2309
+ Z as B,
2310
+ N as C,
2311
+ nt as D,
2312
+ q as P,
2313
+ Ze as R,
2314
+ Je as a,
2315
+ Ae as b,
2316
+ C as c,
2317
+ Ge as d,
2318
+ Oe as e,
2319
+ he as f,
2320
+ He as g,
2321
+ Ye as h,
2322
+ Be as i,
2323
+ _e as j,
2324
+ We as k,
2325
+ qe as l,
2326
+ A as m,
2327
+ L as n,
2328
+ me as o,
2329
+ Ke as p,
2330
+ Xe as q,
2331
+ ae as r,
2332
+ Le as s,
2333
+ et as t,
2334
+ tt as u,
2335
+ Qe as v
2336
+ };
2337
+ //# sourceMappingURL=documentation-generator-Di4c9D9P.js.map