@herdingbits/trailhead-core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,30 @@
1
+ # @herdingbits/trailhead-core
2
+
3
+ Core shell orchestration for the Trailhead micro-frontend framework.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @herdingbits/trailhead-core
9
+ ```
10
+
11
+ ## Usage
12
+
13
+ ```typescript
14
+ import { Trailhead } from '@herdingbits/trailhead-core';
15
+ import { YourAdapter } from '@herdingbits/trailhead-your-design-system';
16
+
17
+ const shell = new Trailhead({
18
+ adapter: new YourAdapter(),
19
+ basePath: '/app',
20
+ apiUrl: 'https://api.example.com'
21
+ });
22
+ ```
23
+
24
+ ## Documentation
25
+
26
+ See the [main Trailhead documentation](https://github.com/herdingbits/trailhead) for more information.
27
+
28
+ ## License
29
+
30
+ MIT
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Public Adapter API - For creating custom design system adapters
3
+ */
4
+ export type { DesignSystemAdapter, FeedbackAdapter, ToastVariant, DialogButton, DialogConfig, DialogResult, } from './types.js';
5
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/adapters/public-api.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,YAAY,EACZ,YAAY,GACb,MAAM,YAAY,CAAC"}
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Public Adapter API - For creating custom design system adapters
3
+ */
4
+ export {};
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Design System Adapter Interfaces
3
+ *
4
+ * These interfaces define the contract between Trailhead core and design system implementations.
5
+ */
6
+ export type ToastVariant = "success" | "error" | "warning" | "info";
7
+ export interface DialogButton<T extends string = string> {
8
+ label: string;
9
+ value: T;
10
+ variant?: string;
11
+ }
12
+ export interface DialogConfig<T extends string = string> {
13
+ message: string;
14
+ title?: string;
15
+ buttons: DialogButton<T>[];
16
+ }
17
+ export interface DialogResult<T extends string = string> {
18
+ value: T | null;
19
+ }
20
+ /**
21
+ * Feedback Adapter - Handles user feedback (toasts, dialogs, busy states)
22
+ */
23
+ export interface FeedbackAdapter {
24
+ /**
25
+ * Show a busy overlay with a message
26
+ */
27
+ showBusy(message: string): void;
28
+ /**
29
+ * Clear the busy overlay
30
+ */
31
+ clearBusy(): void;
32
+ /**
33
+ * Show a toast notification
34
+ */
35
+ showToast(message: string, variant: ToastVariant, duration?: number): void;
36
+ /**
37
+ * Show a dialog with custom buttons
38
+ */
39
+ showDialog<T extends string>(config: DialogConfig<T>): Promise<DialogResult<T>>;
40
+ }
41
+ /**
42
+ * Design System Adapter - Main adapter interface
43
+ */
44
+ export interface DesignSystemAdapter {
45
+ /**
46
+ * Adapter name (e.g., "shoelace", "cloudscape")
47
+ */
48
+ name: string;
49
+ /**
50
+ * Adapter version
51
+ */
52
+ version: string;
53
+ /**
54
+ * Initialize the design system (load assets, set base paths, etc.)
55
+ */
56
+ init(basePath: string): Promise<void>;
57
+ /**
58
+ * Feedback adapter for user notifications
59
+ */
60
+ feedback: FeedbackAdapter;
61
+ }
62
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/adapters/types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpE,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACrD,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,CAAC,CAAC;IACT,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACrD,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,YAAY,CAAC,CAAC,CAAC,EAAE,CAAC;CAC5B;AAED,MAAM,WAAW,YAAY,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM;IACrD,KAAK,EAAE,CAAC,GAAG,IAAI,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,SAAS,IAAI,IAAI,CAAC;IAElB;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAE3E;;OAEG;IACH,UAAU,CAAC,CAAC,SAAS,MAAM,EAAE,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;CACjF;AAED;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;OAEG;IACH,IAAI,EAAE,MAAM,CAAC;IAEb;;OAEG;IACH,OAAO,EAAE,MAAM,CAAC;IAEhB;;OAEG;IACH,IAAI,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEtC;;OAEG;IACH,QAAQ,EAAE,eAAe,CAAC;CAC3B"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Design System Adapter Interfaces
3
+ *
4
+ * These interfaces define the contract between Trailhead core and design system implementations.
5
+ */
6
+ export {};
@@ -0,0 +1,7 @@
1
+ /**
2
+ * @herdingbits/trailhead-core
3
+ * Core shell orchestration and services
4
+ */
5
+ export { Trailhead } from './shell.js';
6
+ export type { ShellConfig } from './shell.js';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AACvC,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,5 @@
1
+ /**
2
+ * @herdingbits/trailhead-core
3
+ * Core shell orchestration and services
4
+ */
5
+ export { Trailhead } from './shell.js';
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Feedback system - imperative API for user feedback
3
+ * No React, pure DOM manipulation
4
+ */
5
+ import type { AlertVariant } from "../types/shell-api";
6
+ /**
7
+ * Show blocking busy overlay with spinner
8
+ */
9
+ export declare function busy(message: string): void;
10
+ /**
11
+ * Clear busy overlay
12
+ */
13
+ export declare function clear(): void;
14
+ /**
15
+ * Show toast notification
16
+ */
17
+ export declare function alert(message: string, variant?: AlertVariant, duration?: number): void;
18
+ /**
19
+ * Show success toast
20
+ */
21
+ export declare function success(message: string, duration?: number): void;
22
+ /**
23
+ * Show error toast
24
+ */
25
+ export declare function error(message: string, duration?: number): void;
26
+ /**
27
+ * Show warning toast
28
+ */
29
+ export declare function warning(message: string, duration?: number): void;
30
+ /**
31
+ * Show info toast
32
+ */
33
+ export declare function info(message: string, duration?: number): void;
34
+ /**
35
+ * Show dialog with custom buttons
36
+ */
37
+ export declare function custom<T extends string>(message: string, title: string, buttons: Array<{
38
+ label: string;
39
+ value: T;
40
+ variant?: string;
41
+ }>): Promise<T | null>;
42
+ /**
43
+ * Show confirm dialog (Cancel/Confirm)
44
+ */
45
+ export declare function confirm(message: string, title?: string): Promise<boolean>;
46
+ /**
47
+ * Show OK dialog
48
+ */
49
+ export declare function ok(message: string, title?: string): Promise<void>;
50
+ /**
51
+ * Show Yes/No dialog
52
+ */
53
+ export declare function yesNo(message: string, title?: string): Promise<boolean>;
54
+ /**
55
+ * Show Yes/No/Cancel dialog
56
+ */
57
+ export declare function yesNoCancel(message: string, title?: string): Promise<"yes" | "no" | "cancel">;
58
+ //# sourceMappingURL=feedback.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../../src/lib/feedback.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAKvD;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAkB1C;AAED;;GAEG;AACH,wBAAgB,KAAK,IAAI,IAAI,CAI5B;AAED;;GAEG;AACH,wBAAgB,KAAK,CACnB,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,YAAqB,EAC9B,QAAQ,GAAE,MAAa,GACtB,IAAI,CAiBN;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAEhE;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAE9D;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAEhE;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAE7D;AAED;;GAEG;AACH,wBAAgB,MAAM,CAAC,CAAC,SAAS,MAAM,EACrC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,KAAK,CAAC;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,GAC5D,OAAO,CAAC,CAAC,GAAG,IAAI,CAAC,CAqCnB;AAED;;GAEG;AACH,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKpF;AAED;;GAEG;AACH,wBAAgB,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAsB,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhF;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,GAAE,MAAkB,GAAG,OAAO,CAAC,OAAO,CAAC,CAKlF;AAED;;GAEG;AACH,wBAAgB,WAAW,CACzB,OAAO,EAAE,MAAM,EACf,KAAK,GAAE,MAAkB,GACxB,OAAO,CAAC,KAAK,GAAG,IAAI,GAAG,QAAQ,CAAC,CAMlC"}
@@ -0,0 +1,145 @@
1
+ let busyOverlay = null;
2
+ let toastContainer = null;
3
+ /**
4
+ * Show blocking busy overlay with spinner
5
+ */
6
+ export function busy(message) {
7
+ if (!busyOverlay) {
8
+ busyOverlay = document.createElement("div");
9
+ busyOverlay.id = "shell-busy-overlay";
10
+ busyOverlay.innerHTML = `
11
+ <div class="shell-busy-content">
12
+ <div class="shell-spinner"></div>
13
+ <div class="shell-busy-message"></div>
14
+ </div>
15
+ `;
16
+ document.body.appendChild(busyOverlay);
17
+ }
18
+ const messageEl = busyOverlay.querySelector(".shell-busy-message");
19
+ if (messageEl) {
20
+ messageEl.textContent = message;
21
+ }
22
+ busyOverlay.style.display = "flex";
23
+ }
24
+ /**
25
+ * Clear busy overlay
26
+ */
27
+ export function clear() {
28
+ if (busyOverlay) {
29
+ busyOverlay.style.display = "none";
30
+ }
31
+ }
32
+ /**
33
+ * Show toast notification
34
+ */
35
+ export function alert(message, variant = "info", duration = 3000) {
36
+ if (!toastContainer) {
37
+ toastContainer = document.createElement("div");
38
+ toastContainer.id = "shell-toast-container";
39
+ document.body.appendChild(toastContainer);
40
+ }
41
+ const toast = document.createElement("div");
42
+ toast.className = `shell-toast shell-toast-${variant}`;
43
+ toast.textContent = message;
44
+ toastContainer.appendChild(toast);
45
+ setTimeout(() => toast.classList.add("shell-toast-show"), 10);
46
+ setTimeout(() => {
47
+ toast.classList.remove("shell-toast-show");
48
+ setTimeout(() => toast.remove(), 300);
49
+ }, duration);
50
+ }
51
+ /**
52
+ * Show success toast
53
+ */
54
+ export function success(message, duration) {
55
+ alert(message, "success", duration);
56
+ }
57
+ /**
58
+ * Show error toast
59
+ */
60
+ export function error(message, duration) {
61
+ alert(message, "error", duration || 5000);
62
+ }
63
+ /**
64
+ * Show warning toast
65
+ */
66
+ export function warning(message, duration) {
67
+ alert(message, "warning", duration || 4000);
68
+ }
69
+ /**
70
+ * Show info toast
71
+ */
72
+ export function info(message, duration) {
73
+ alert(message, "info", duration);
74
+ }
75
+ /**
76
+ * Show dialog with custom buttons
77
+ */
78
+ export function custom(message, title, buttons) {
79
+ return new Promise((resolve) => {
80
+ const dialog = document.createElement("div");
81
+ dialog.className = "shell-dialog-overlay";
82
+ dialog.innerHTML = `
83
+ <div class="shell-dialog">
84
+ <div class="shell-dialog-title">${title}</div>
85
+ <div class="shell-dialog-message">${message}</div>
86
+ <div class="shell-dialog-buttons">
87
+ ${buttons
88
+ .map((btn) => `<button class="shell-btn shell-btn-${btn.variant || "default"}" data-value="${btn.value}">${btn.label}</button>`)
89
+ .join("")}
90
+ </div>
91
+ </div>
92
+ `;
93
+ dialog.querySelectorAll("button").forEach((btn) => {
94
+ btn.onclick = () => {
95
+ const value = btn.getAttribute("data-value");
96
+ dialog.remove();
97
+ resolve(value);
98
+ };
99
+ });
100
+ // Click outside to cancel
101
+ dialog.onclick = (e) => {
102
+ if (e.target === dialog) {
103
+ dialog.remove();
104
+ resolve(null);
105
+ }
106
+ };
107
+ document.body.appendChild(dialog);
108
+ });
109
+ }
110
+ /**
111
+ * Show confirm dialog (Cancel/Confirm)
112
+ */
113
+ export function confirm(message, title = "Confirm") {
114
+ return custom(message, title, [
115
+ { label: "Cancel", value: "cancel", variant: "secondary" },
116
+ { label: "Confirm", value: "confirm", variant: "primary" },
117
+ ]).then((result) => result === "confirm");
118
+ }
119
+ /**
120
+ * Show OK dialog
121
+ */
122
+ export function ok(message, title = "Information") {
123
+ return custom(message, title, [
124
+ { label: "OK", value: "ok", variant: "primary" },
125
+ ]).then(() => undefined);
126
+ }
127
+ /**
128
+ * Show Yes/No dialog
129
+ */
130
+ export function yesNo(message, title = "Confirm") {
131
+ return custom(message, title, [
132
+ { label: "No", value: "no", variant: "secondary" },
133
+ { label: "Yes", value: "yes", variant: "primary" },
134
+ ]).then((result) => result === "yes");
135
+ }
136
+ /**
137
+ * Show Yes/No/Cancel dialog
138
+ */
139
+ export function yesNoCancel(message, title = "Confirm") {
140
+ return custom(message, title, [
141
+ { label: "Cancel", value: "cancel", variant: "secondary" },
142
+ { label: "No", value: "no", variant: "secondary" },
143
+ { label: "Yes", value: "yes", variant: "primary" },
144
+ ]).then((result) => result || "cancel");
145
+ }
@@ -0,0 +1,26 @@
1
+ import type { RequestOptions, Result } from "../types/shell-api";
2
+ /**
3
+ * Initialize HTTP client
4
+ */
5
+ export declare function init(baseUrl?: string): void;
6
+ /**
7
+ * GET request
8
+ */
9
+ export declare function get<T>(url: string, options?: RequestOptions): Promise<Result<T>>;
10
+ /**
11
+ * POST request
12
+ */
13
+ export declare function post<T>(url: string, data?: any, options?: RequestOptions): Promise<Result<T>>;
14
+ /**
15
+ * PUT request
16
+ */
17
+ export declare function put<T>(url: string, data?: any, options?: RequestOptions): Promise<Result<T>>;
18
+ /**
19
+ * PATCH request
20
+ */
21
+ export declare function patch<T>(url: string, data?: any, options?: RequestOptions): Promise<Result<T>>;
22
+ /**
23
+ * DELETE request
24
+ */
25
+ export declare function del<T>(url: string, options?: RequestOptions): Promise<Result<T>>;
26
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../src/lib/http.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,EAAyC,MAAM,oBAAoB,CAAC;AAKxG;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,MAAW,GAAG,IAAI,CAM/C;AA4ED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAEhF;AAED;;GAEG;AACH,wBAAgB,IAAI,CAAC,CAAC,EACpB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAEpB;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EACnB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAEpB;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,CAAC,EACrB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAEpB;AAED;;GAEG;AACH,wBAAgB,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAEhF"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * HTTP client using ky with automatic feedback orchestration
3
+ */
4
+ import ky from "ky";
5
+ import * as requestManager from "./requestManager";
6
+ let kyInstance;
7
+ /**
8
+ * Initialize HTTP client
9
+ */
10
+ export function init(baseUrl = "") {
11
+ kyInstance = ky.create({
12
+ prefixUrl: baseUrl,
13
+ timeout: 30000,
14
+ retry: 0,
15
+ });
16
+ }
17
+ /**
18
+ * Make HTTP request with feedback orchestration
19
+ */
20
+ async function request(method, url, data, options = {}) {
21
+ const { requestKey, busyMessage, successMessage, showSuccess = false, noFeedback = false, headers = {}, } = options;
22
+ try {
23
+ requestManager.startRequest(requestKey, busyMessage, noFeedback);
24
+ const kyOptions = {
25
+ method,
26
+ headers,
27
+ };
28
+ if (data && (method === "POST" || method === "PUT" || method === "PATCH")) {
29
+ kyOptions.json = data;
30
+ }
31
+ const response = await kyInstance(url, kyOptions);
32
+ const result = await response.json();
33
+ requestManager.endRequest(requestKey, noFeedback);
34
+ if (!noFeedback && showSuccess && successMessage) {
35
+ requestManager.showSuccess(successMessage);
36
+ }
37
+ return {
38
+ success: true,
39
+ data: result,
40
+ requestKey,
41
+ };
42
+ }
43
+ catch (err) {
44
+ requestManager.endRequest(requestKey, noFeedback);
45
+ const error = {
46
+ name: err.name || "HttpError",
47
+ message: err.message || "Request failed",
48
+ status: err.response?.status,
49
+ };
50
+ if (err.response) {
51
+ try {
52
+ error.data = await err.response.json();
53
+ error.message = error.data.message || error.message;
54
+ }
55
+ catch {
56
+ // Response not JSON
57
+ }
58
+ }
59
+ if (!noFeedback) {
60
+ requestManager.showError(error.message);
61
+ }
62
+ return {
63
+ success: false,
64
+ error,
65
+ requestKey,
66
+ };
67
+ }
68
+ }
69
+ /**
70
+ * GET request
71
+ */
72
+ export function get(url, options) {
73
+ return request("GET", url, undefined, options);
74
+ }
75
+ /**
76
+ * POST request
77
+ */
78
+ export function post(url, data, options) {
79
+ return request("POST", url, data, options);
80
+ }
81
+ /**
82
+ * PUT request
83
+ */
84
+ export function put(url, data, options) {
85
+ return request("PUT", url, data, options);
86
+ }
87
+ /**
88
+ * PATCH request
89
+ */
90
+ export function patch(url, data, options) {
91
+ return request("PATCH", url, data, options);
92
+ }
93
+ /**
94
+ * DELETE request
95
+ */
96
+ export function del(url, options) {
97
+ return request("DELETE", url, undefined, options);
98
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Translation helper function
3
+ * In source code, this returns the key as-is (English)
4
+ * At build time, the i18n plugin replaces t("key") with the translated string
5
+ */
6
+ export declare const t: (key: string) => string;
7
+ //# sourceMappingURL=i18n.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"i18n.d.ts","sourceRoot":"","sources":["../../src/lib/i18n.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,CAAC,GAAI,KAAK,MAAM,KAAG,MAAa,CAAC"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Translation helper function
3
+ * In source code, this returns the key as-is (English)
4
+ * At build time, the i18n plugin replaces t("key") with the translated string
5
+ */
6
+ export const t = (key) => key;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Request manager - orchestrates HTTP requests with feedback
3
+ */
4
+ import type { FeedbackAdapter } from "../adapters/types.js";
5
+ /**
6
+ * Initialize request manager with feedback adapter
7
+ */
8
+ export declare function init(adapter: FeedbackAdapter): void;
9
+ /**
10
+ * Track request start
11
+ */
12
+ export declare function startRequest(requestKey?: string, busyMessage?: string, noFeedback?: boolean): void;
13
+ /**
14
+ * Track request end
15
+ */
16
+ export declare function endRequest(requestKey?: string, noFeedback?: boolean): void;
17
+ /**
18
+ * Show success feedback
19
+ */
20
+ export declare function showSuccess(message: string): void;
21
+ /**
22
+ * Show error feedback
23
+ */
24
+ export declare function showError(message: string): void;
25
+ /**
26
+ * Get active request count
27
+ */
28
+ export declare function getActiveRequestCount(): number;
29
+ /**
30
+ * Check if specific request is active
31
+ */
32
+ export declare function isRequestActive(requestKey: string): boolean;
33
+ //# sourceMappingURL=requestManager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"requestManager.d.ts","sourceRoot":"","sources":["../../src/lib/requestManager.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAM5D;;GAEG;AACH,wBAAgB,IAAI,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,CAEnD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAC1B,UAAU,CAAC,EAAE,MAAM,EACnB,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,OAAO,GACnB,IAAI,CAYN;AAED;;GAEG;AACH,wBAAgB,UAAU,CACxB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,OAAO,GACnB,IAAI,CAgBN;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAIjD;AAED;;GAEG;AACH,wBAAgB,SAAS,CAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAI/C;AAED;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE3D"}
@@ -0,0 +1,72 @@
1
+ let activeRequests = 0;
2
+ const requestKeys = new Map();
3
+ let feedbackAdapter = null;
4
+ /**
5
+ * Initialize request manager with feedback adapter
6
+ */
7
+ export function init(adapter) {
8
+ feedbackAdapter = adapter;
9
+ }
10
+ /**
11
+ * Track request start
12
+ */
13
+ export function startRequest(requestKey, busyMessage, noFeedback) {
14
+ if (noFeedback || !feedbackAdapter)
15
+ return;
16
+ if (requestKey) {
17
+ const count = requestKeys.get(requestKey) || 0;
18
+ requestKeys.set(requestKey, count + 1);
19
+ }
20
+ activeRequests++;
21
+ if (activeRequests === 1) {
22
+ feedbackAdapter.showBusy(busyMessage || "Loading...");
23
+ }
24
+ }
25
+ /**
26
+ * Track request end
27
+ */
28
+ export function endRequest(requestKey, noFeedback) {
29
+ if (noFeedback || !feedbackAdapter)
30
+ return;
31
+ if (requestKey) {
32
+ const count = requestKeys.get(requestKey) || 0;
33
+ if (count > 1) {
34
+ requestKeys.set(requestKey, count - 1);
35
+ }
36
+ else {
37
+ requestKeys.delete(requestKey);
38
+ }
39
+ }
40
+ activeRequests--;
41
+ if (activeRequests === 0) {
42
+ feedbackAdapter.clearBusy();
43
+ }
44
+ }
45
+ /**
46
+ * Show success feedback
47
+ */
48
+ export function showSuccess(message) {
49
+ if (feedbackAdapter) {
50
+ feedbackAdapter.showToast(message, "success");
51
+ }
52
+ }
53
+ /**
54
+ * Show error feedback
55
+ */
56
+ export function showError(message) {
57
+ if (feedbackAdapter) {
58
+ feedbackAdapter.showToast(message, "error", 5000);
59
+ }
60
+ }
61
+ /**
62
+ * Get active request count
63
+ */
64
+ export function getActiveRequestCount() {
65
+ return activeRequests;
66
+ }
67
+ /**
68
+ * Check if specific request is active
69
+ */
70
+ export function isRequestActive(requestKey) {
71
+ return requestKeys.has(requestKey);
72
+ }
@@ -0,0 +1,54 @@
1
+ import type { DesignSystemAdapter } from "./adapters/types.js";
2
+ export interface ShellConfig {
3
+ adapter: DesignSystemAdapter;
4
+ basePath?: string;
5
+ apiUrl?: string;
6
+ }
7
+ export declare class Trailhead {
8
+ private navigation;
9
+ private routeChangeCallbacks;
10
+ private basePath;
11
+ private adapter;
12
+ constructor(config: ShellConfig);
13
+ /**
14
+ * Initialize shell
15
+ */
16
+ private init;
17
+ /**
18
+ * Initialize design system adapter
19
+ */
20
+ private initAdapter;
21
+ /**
22
+ * Create shell API
23
+ */
24
+ private createAPI;
25
+ /**
26
+ * Load navigation configuration
27
+ */
28
+ private loadNavigation;
29
+ /**
30
+ * Render navigation menu
31
+ */
32
+ private renderNavigation;
33
+ /**
34
+ * Setup routing
35
+ */
36
+ private setupRouting;
37
+ /**
38
+ * Navigate to path
39
+ */
40
+ private navigate;
41
+ /**
42
+ * Handle route change
43
+ */
44
+ private handleRoute;
45
+ /**
46
+ * Update active navigation item
47
+ */
48
+ private updateActiveNav;
49
+ /**
50
+ * Load plugin application
51
+ */
52
+ private loadPlugin;
53
+ }
54
+ //# sourceMappingURL=shell.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell.d.ts","sourceRoot":"","sources":["../src/shell.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAK/D,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,mBAAmB,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,oBAAoB,CAAqC;IACjE,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,OAAO,CAAsB;gBAEzB,MAAM,EAAE,WAAW;IAM/B;;OAEG;YACW,IAAI;IAwBlB;;OAEG;YACW,WAAW;IAUzB;;OAEG;IACH,OAAO,CAAC,SAAS;IAmFjB;;OAEG;YACW,cAAc;IAU5B;;OAEG;IACH,OAAO,CAAC,gBAAgB;IA6BxB;;OAEG;IACH,OAAO,CAAC,YAAY;IAMpB;;OAEG;IACH,OAAO,CAAC,QAAQ;IAIhB;;OAEG;IACH,OAAO,CAAC,WAAW;IAenB;;OAEG;IACH,OAAO,CAAC,eAAe;IAavB;;OAEG;YACW,UAAU;CAsCzB"}
package/dist/shell.js ADDED
@@ -0,0 +1,236 @@
1
+ import * as http from "./lib/http.js";
2
+ import * as requestManager from "./lib/requestManager.js";
3
+ import { t } from "./lib/i18n.js";
4
+ export class Trailhead {
5
+ constructor(config) {
6
+ this.navigation = [];
7
+ this.routeChangeCallbacks = [];
8
+ this.basePath = config.basePath || "";
9
+ this.adapter = config.adapter;
10
+ this.init(config.apiUrl);
11
+ }
12
+ /**
13
+ * Initialize shell
14
+ */
15
+ async init(apiUrl) {
16
+ // Initialize design system adapter
17
+ await this.initAdapter();
18
+ // Initialize request manager and HTTP client with adapter
19
+ requestManager.init(this.adapter.feedback);
20
+ http.init(apiUrl || "");
21
+ // Expose shell API globally
22
+ window.shell = this.createAPI();
23
+ // Load navigation
24
+ await this.loadNavigation();
25
+ // Setup routing
26
+ this.setupRouting();
27
+ // Render navigation
28
+ this.renderNavigation();
29
+ // Load initial route
30
+ this.handleRoute();
31
+ }
32
+ /**
33
+ * Initialize design system adapter
34
+ */
35
+ async initAdapter() {
36
+ try {
37
+ await this.adapter.init(this.basePath);
38
+ console.log(`[Trailhead] Initialized ${this.adapter.name} adapter v${this.adapter.version}`);
39
+ }
40
+ catch (error) {
41
+ console.error("Failed to initialize design system adapter:", error);
42
+ throw error;
43
+ }
44
+ }
45
+ /**
46
+ * Create shell API
47
+ */
48
+ createAPI() {
49
+ const adapter = this.adapter;
50
+ return {
51
+ version: "1.0.0",
52
+ feedback: {
53
+ busy: (message) => adapter.feedback.showBusy(message),
54
+ clear: () => adapter.feedback.clearBusy(),
55
+ success: (message, duration) => adapter.feedback.showToast(message, "success", duration),
56
+ error: (message, duration) => adapter.feedback.showToast(message, "error", duration || 5000),
57
+ warning: (message, duration) => adapter.feedback.showToast(message, "warning", duration || 4000),
58
+ info: (message, duration) => adapter.feedback.showToast(message, "info", duration),
59
+ alert: (message, variant = "info", duration) => adapter.feedback.showToast(message, variant, duration),
60
+ confirm: (message, title = "Confirm") => adapter.feedback.showDialog({
61
+ message,
62
+ title,
63
+ buttons: [
64
+ { label: "Cancel", value: "cancel", variant: "secondary" },
65
+ { label: "Confirm", value: "confirm", variant: "primary" },
66
+ ],
67
+ }).then((result) => result.value === "confirm"),
68
+ ok: (message, title = "Information") => adapter.feedback.showDialog({
69
+ message,
70
+ title,
71
+ buttons: [{ label: "OK", value: "ok", variant: "primary" }],
72
+ }).then(() => undefined),
73
+ yesNo: (message, title = "Confirm") => adapter.feedback.showDialog({
74
+ message,
75
+ title,
76
+ buttons: [
77
+ { label: "No", value: "no", variant: "secondary" },
78
+ { label: "Yes", value: "yes", variant: "primary" },
79
+ ],
80
+ }).then((result) => result.value === "yes"),
81
+ yesNoCancel: (message, title = "Confirm") => adapter.feedback.showDialog({
82
+ message,
83
+ title,
84
+ buttons: [
85
+ { label: "Cancel", value: "cancel", variant: "secondary" },
86
+ { label: "No", value: "no", variant: "secondary" },
87
+ { label: "Yes", value: "yes", variant: "primary" },
88
+ ],
89
+ }).then((result) => result.value || "cancel"),
90
+ custom: (message, title, buttons) => adapter.feedback.showDialog({ message, title, buttons })
91
+ .then((result) => result.value),
92
+ },
93
+ http: {
94
+ get: http.get,
95
+ post: http.post,
96
+ put: http.put,
97
+ patch: http.patch,
98
+ delete: http.del,
99
+ },
100
+ navigation: {
101
+ navigate: (path) => this.navigate(path),
102
+ getCurrentPath: () => window.location.pathname,
103
+ onRouteChange: (callback) => {
104
+ this.routeChangeCallbacks.push(callback);
105
+ return () => {
106
+ const index = this.routeChangeCallbacks.indexOf(callback);
107
+ if (index > -1) {
108
+ this.routeChangeCallbacks.splice(index, 1);
109
+ }
110
+ };
111
+ },
112
+ },
113
+ };
114
+ }
115
+ /**
116
+ * Load navigation configuration
117
+ */
118
+ async loadNavigation() {
119
+ try {
120
+ const response = await fetch(`${this.basePath}/navigation.json`);
121
+ this.navigation = await response.json();
122
+ }
123
+ catch (error) {
124
+ console.error("Failed to load navigation:", error);
125
+ this.navigation = [];
126
+ }
127
+ }
128
+ /**
129
+ * Render navigation menu
130
+ */
131
+ renderNavigation() {
132
+ const nav = document.getElementById("shell-navigation");
133
+ if (!nav)
134
+ return;
135
+ nav.innerHTML = this.navigation
136
+ .map((item) => `
137
+ <a href="${this.basePath}${item.path}"
138
+ class="shell-nav-item"
139
+ data-path="${item.path}"
140
+ data-app="${item.app}">
141
+ <i class="shell-icon shell-icon-${item.icon}"></i>
142
+ <span class="shell-nav-label">${item.label}</span>
143
+ </a>
144
+ `)
145
+ .join("");
146
+ nav.querySelectorAll("a").forEach((link) => {
147
+ link.addEventListener("click", (e) => {
148
+ e.preventDefault();
149
+ const path = link.getAttribute("data-path");
150
+ if (path) {
151
+ this.navigate(path);
152
+ }
153
+ });
154
+ });
155
+ }
156
+ /**
157
+ * Setup routing
158
+ */
159
+ setupRouting() {
160
+ window.addEventListener("popstate", () => {
161
+ this.handleRoute();
162
+ });
163
+ }
164
+ /**
165
+ * Navigate to path
166
+ */
167
+ navigate(path) {
168
+ window.location.href = this.basePath + path;
169
+ }
170
+ /**
171
+ * Handle route change
172
+ */
173
+ handleRoute() {
174
+ let path = window.location.pathname;
175
+ if (this.basePath && path.startsWith(this.basePath)) {
176
+ path = path.substring(this.basePath.length) || "/";
177
+ }
178
+ const navItem = this.navigation.find((item) => path.startsWith(item.path));
179
+ if (navItem) {
180
+ this.loadPlugin(navItem.app, navItem.path);
181
+ this.updateActiveNav(navItem.path);
182
+ }
183
+ }
184
+ /**
185
+ * Update active navigation item
186
+ */
187
+ updateActiveNav(path) {
188
+ const nav = document.getElementById("shell-navigation");
189
+ if (!nav)
190
+ return;
191
+ nav.querySelectorAll("a").forEach((link) => {
192
+ if (link.getAttribute("data-path") === path) {
193
+ link.classList.add("shell-nav-item-active");
194
+ }
195
+ else {
196
+ link.classList.remove("shell-nav-item-active");
197
+ }
198
+ });
199
+ }
200
+ /**
201
+ * Load plugin application
202
+ */
203
+ async loadPlugin(appName, appPath) {
204
+ const root = document.getElementById("shell-content");
205
+ if (!root)
206
+ return;
207
+ root.innerHTML = `<div class="shell-loading">${t("Loading...")}</div>`;
208
+ try {
209
+ const pluginUrl = `${this.basePath}${appPath}/app.js`;
210
+ const pluginCss = `${this.basePath}${appPath}/${appName}.css`;
211
+ // Load CSS
212
+ const link = document.createElement("link");
213
+ link.rel = "stylesheet";
214
+ link.href = pluginCss;
215
+ document.head.appendChild(link);
216
+ // Load JS
217
+ const script = document.createElement("script");
218
+ script.src = pluginUrl;
219
+ script.type = "module";
220
+ script.onload = () => {
221
+ root.innerHTML = "";
222
+ if (window.AppMount) {
223
+ window.AppMount(root);
224
+ }
225
+ };
226
+ script.onerror = () => {
227
+ root.innerHTML = `<div class="shell-error">${t("Failed to load application")}: ${appName}</div>`;
228
+ };
229
+ document.body.appendChild(script);
230
+ }
231
+ catch (error) {
232
+ console.error("Failed to load plugin:", error);
233
+ root.innerHTML = `<div class="shell-error">${t("Failed to load application")}</div>`;
234
+ }
235
+ }
236
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Public Shell API - Only these types are exposed to plugin applications
3
+ * This file explicitly defines what's public vs internal
4
+ */
5
+ export type { ShellAPI, FeedbackAPI, AlertVariant, HttpAPI, RequestOptions, Result, SuccessResult, ErrorResult, HttpError, NavigationAPI, NavItem, } from './shell-api.js';
6
+ //# sourceMappingURL=public-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/types/public-api.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,YAAY,EACV,QAAQ,EACR,WAAW,EACX,YAAY,EACZ,OAAO,EACP,cAAc,EACd,MAAM,EACN,aAAa,EACb,WAAW,EACX,SAAS,EACT,aAAa,EACb,OAAO,GACR,MAAM,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Public Shell API - Only these types are exposed to plugin applications
3
+ * This file explicitly defines what's public vs internal
4
+ */
5
+ export {};
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Shell API Interface
3
+ * Exposed to plugin applications via window.shell
4
+ */
5
+ export interface ShellAPI {
6
+ version: string;
7
+ feedback: FeedbackAPI;
8
+ http: HttpAPI;
9
+ navigation: NavigationAPI;
10
+ }
11
+ /**
12
+ * Feedback system API
13
+ */
14
+ export interface FeedbackAPI {
15
+ busy(message: string): void;
16
+ clear(): void;
17
+ success(message: string, duration?: number): void;
18
+ error(message: string, duration?: number): void;
19
+ warning(message: string, duration?: number): void;
20
+ info(message: string, duration?: number): void;
21
+ alert(message: string, variant?: AlertVariant, duration?: number): void;
22
+ confirm(message: string, title?: string): Promise<boolean>;
23
+ ok(message: string, title?: string): Promise<void>;
24
+ yesNo(message: string, title?: string): Promise<boolean>;
25
+ yesNoCancel(message: string, title?: string): Promise<"yes" | "no" | "cancel">;
26
+ custom<T extends string>(message: string, title: string, buttons: Array<{
27
+ label: string;
28
+ value: T;
29
+ variant?: string;
30
+ }>): Promise<T | null>;
31
+ }
32
+ export type AlertVariant = "success" | "error" | "warning" | "info";
33
+ /**
34
+ * HTTP client API with automatic feedback orchestration
35
+ */
36
+ export interface HttpAPI {
37
+ get<T = any>(url: string, options?: RequestOptions): Promise<Result<T>>;
38
+ post<T = any>(url: string, data?: any, options?: RequestOptions): Promise<Result<T>>;
39
+ put<T = any>(url: string, data?: any, options?: RequestOptions): Promise<Result<T>>;
40
+ patch<T = any>(url: string, data?: any, options?: RequestOptions): Promise<Result<T>>;
41
+ delete<T = any>(url: string, options?: RequestOptions): Promise<Result<T>>;
42
+ }
43
+ export interface RequestOptions {
44
+ requestKey?: string;
45
+ busyMessage?: string;
46
+ successMessage?: string;
47
+ showSuccess?: boolean;
48
+ noFeedback?: boolean;
49
+ headers?: Record<string, string>;
50
+ }
51
+ export interface SuccessResult<T> {
52
+ success: true;
53
+ data: T;
54
+ requestKey?: string;
55
+ }
56
+ export interface ErrorResult {
57
+ success: false;
58
+ error: HttpError;
59
+ requestKey?: string;
60
+ }
61
+ export type Result<T> = SuccessResult<T> | ErrorResult;
62
+ export interface HttpError {
63
+ name: string;
64
+ message: string;
65
+ status?: number;
66
+ data?: any;
67
+ }
68
+ /**
69
+ * Navigation API
70
+ */
71
+ export interface NavigationAPI {
72
+ navigate(path: string): void;
73
+ getCurrentPath(): string;
74
+ onRouteChange(callback: (path: string) => void): () => void;
75
+ }
76
+ /**
77
+ * Navigation configuration
78
+ */
79
+ export interface NavItem {
80
+ id: string;
81
+ path: string;
82
+ app: string;
83
+ icon: string;
84
+ label: string;
85
+ order: number;
86
+ badge?: () => number;
87
+ }
88
+ /**
89
+ * Global window extension
90
+ */
91
+ declare global {
92
+ interface Window {
93
+ shell: ShellAPI;
94
+ AppMount?: (container: HTMLElement) => void;
95
+ }
96
+ }
97
+ //# sourceMappingURL=shell-api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-api.d.ts","sourceRoot":"","sources":["../../src/types/shell-api.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Shell API Interface
3
+ * Exposed to plugin applications via window.shell
4
+ */
5
+ export {};
package/package.json ADDED
@@ -0,0 +1,46 @@
1
+ {
2
+ "name": "@herdingbits/trailhead-core",
3
+ "version": "0.0.1",
4
+ "description": "Core shell orchestration for Trailhead micro-frontend framework",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ }
13
+ },
14
+ "files": [
15
+ "dist",
16
+ "README.md"
17
+ ],
18
+ "scripts": {
19
+ "clean": "rm -rf dist ../types/*.d.ts ../types/adapters",
20
+ "build": "npm run clean && tsc && npm run build:types",
21
+ "build:types": "tsc src/types/public-api.ts --declaration --emitDeclarationOnly --outDir ../types --skipLibCheck && tsc src/adapters/public-api.ts --declaration --emitDeclarationOnly --outDir ../types/adapters --skipLibCheck",
22
+ "test": "vitest"
23
+ },
24
+ "dependencies": {
25
+ "ky": "^1.14.3"
26
+ },
27
+ "devDependencies": {
28
+ "typescript": "^5.9.3",
29
+ "vitest": "^4.0.18"
30
+ },
31
+ "keywords": [
32
+ "micro-frontend",
33
+ "shell",
34
+ "trailhead"
35
+ ],
36
+ "author": "HerdingBits",
37
+ "license": "MIT",
38
+ "publishConfig": {
39
+ "access": "public"
40
+ },
41
+ "repository": {
42
+ "type": "git",
43
+ "url": "https://github.com/herdingbits/trailhead.git",
44
+ "directory": "packages/core"
45
+ }
46
+ }