@hamak/ui-shell-impl 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/.turbo/turbo-build.log +1 -0
  2. package/dist/core/DefaultFeatureManager.d.ts +24 -0
  3. package/dist/core/DefaultFeatureManager.d.ts.map +1 -0
  4. package/dist/core/DefaultFeatureManager.js +80 -0
  5. package/dist/core/DefaultLayoutManager.d.ts +19 -0
  6. package/dist/core/DefaultLayoutManager.d.ts.map +1 -0
  7. package/dist/core/DefaultLayoutManager.js +59 -0
  8. package/dist/core/DefaultRouter.d.ts +30 -0
  9. package/dist/core/DefaultRouter.d.ts.map +1 -0
  10. package/dist/core/DefaultRouter.js +111 -0
  11. package/dist/core/DefaultShell.d.ts +30 -0
  12. package/dist/core/DefaultShell.d.ts.map +1 -0
  13. package/dist/core/DefaultShell.js +147 -0
  14. package/dist/core/DefaultThemeManager.d.ts +27 -0
  15. package/dist/core/DefaultThemeManager.d.ts.map +1 -0
  16. package/dist/core/DefaultThemeManager.js +76 -0
  17. package/dist/core/index.d.ts +10 -0
  18. package/dist/core/index.d.ts.map +1 -0
  19. package/dist/core/index.js +9 -0
  20. package/dist/index.d.ts +20 -0
  21. package/dist/index.d.ts.map +1 -0
  22. package/dist/index.js +39 -0
  23. package/dist/plugin/ShellPluginFactory.d.ts +11 -0
  24. package/dist/plugin/ShellPluginFactory.d.ts.map +1 -0
  25. package/dist/plugin/ShellPluginFactory.js +73 -0
  26. package/dist/plugin/index.d.ts +6 -0
  27. package/dist/plugin/index.d.ts.map +1 -0
  28. package/dist/plugin/index.js +5 -0
  29. package/dist/providers/CSSVariablesThemeProvider.d.ts +16 -0
  30. package/dist/providers/CSSVariablesThemeProvider.d.ts.map +1 -0
  31. package/dist/providers/CSSVariablesThemeProvider.js +47 -0
  32. package/dist/providers/HashRouterStrategy.d.ts +20 -0
  33. package/dist/providers/HashRouterStrategy.d.ts.map +1 -0
  34. package/dist/providers/HashRouterStrategy.js +57 -0
  35. package/dist/providers/HistoryRouterStrategy.d.ts +21 -0
  36. package/dist/providers/HistoryRouterStrategy.d.ts.map +1 -0
  37. package/dist/providers/HistoryRouterStrategy.js +64 -0
  38. package/dist/providers/LocalStorageProvider.d.ts +13 -0
  39. package/dist/providers/LocalStorageProvider.d.ts.map +1 -0
  40. package/dist/providers/LocalStorageProvider.js +50 -0
  41. package/dist/providers/MemoryStorageProvider.d.ts +14 -0
  42. package/dist/providers/MemoryStorageProvider.d.ts.map +1 -0
  43. package/dist/providers/MemoryStorageProvider.js +22 -0
  44. package/dist/providers/index.d.ts +10 -0
  45. package/dist/providers/index.d.ts.map +1 -0
  46. package/dist/providers/index.js +9 -0
  47. package/dist/utils/index.d.ts +6 -0
  48. package/dist/utils/index.d.ts.map +1 -0
  49. package/dist/utils/index.js +5 -0
  50. package/dist/utils/viewport-utils.d.ts +16 -0
  51. package/dist/utils/viewport-utils.d.ts.map +1 -0
  52. package/dist/utils/viewport-utils.js +52 -0
  53. package/package.json +37 -0
  54. package/src/core/DefaultFeatureManager.ts +101 -0
  55. package/src/core/DefaultLayoutManager.ts +74 -0
  56. package/src/core/DefaultRouter.ts +135 -0
  57. package/src/core/DefaultShell.ts +176 -0
  58. package/src/core/DefaultThemeManager.ts +99 -0
  59. package/src/core/index.ts +10 -0
  60. package/src/index.ts +51 -0
  61. package/src/plugin/ShellPluginFactory.ts +98 -0
  62. package/src/plugin/index.ts +6 -0
  63. package/src/providers/CSSVariablesThemeProvider.ts +60 -0
  64. package/src/providers/HashRouterStrategy.ts +71 -0
  65. package/src/providers/HistoryRouterStrategy.ts +78 -0
  66. package/src/providers/LocalStorageProvider.ts +53 -0
  67. package/src/providers/MemoryStorageProvider.ts +30 -0
  68. package/src/providers/index.ts +10 -0
  69. package/src/utils/index.ts +6 -0
  70. package/src/utils/viewport-utils.ts +64 -0
  71. package/tsconfig.json +20 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,eAAO,MAAM,OAAO,UAAU,CAAC;AAG/B,cAAc,QAAQ,CAAC;AAGvB,cAAc,aAAa,CAAC;AAG5B,cAAc,SAAS,CAAC;AAGxB,cAAc,UAAU,CAAC;AAGzB,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD,wBAAgB,WAAW,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,YAAY,CAE9D;AAED,wBAAgB,mBAAmB,IAAI,oBAAoB,CAE1D;AAKD,wBAAgB,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,YAAY,CAK3D;AAED,wBAAgB,UAAU,IAAI,IAAI,CAKjC"}
package/dist/index.js ADDED
@@ -0,0 +1,39 @@
1
+ /**
2
+ * UI Shell Implementation
3
+ * Concrete implementations of UI Shell interfaces
4
+ *
5
+ * This package provides default implementations that can be used directly
6
+ * or extended for custom behavior.
7
+ */
8
+ export const version = '0.1.0';
9
+ // Export core implementations
10
+ export * from './core';
11
+ // Export providers
12
+ export * from './providers';
13
+ // Export utilities
14
+ export * from './utils';
15
+ // Export plugin integration
16
+ export * from './plugin';
17
+ // Factory functions
18
+ import { DefaultShell } from './core/DefaultShell';
19
+ import { DefaultLayoutManager } from './core/DefaultLayoutManager';
20
+ export function createShell(config) {
21
+ return new DefaultShell(config);
22
+ }
23
+ export function createLayoutManager() {
24
+ return new DefaultLayoutManager();
25
+ }
26
+ // Singleton pattern support
27
+ let globalShell = null;
28
+ export function getShell(config) {
29
+ if (!globalShell) {
30
+ globalShell = createShell(config);
31
+ }
32
+ return globalShell;
33
+ }
34
+ export function resetShell() {
35
+ if (globalShell) {
36
+ globalShell.destroy();
37
+ globalShell = null;
38
+ }
39
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Shell Plugin Factory
3
+ * Creates microkernel plugin for UI Shell integration
4
+ */
5
+ import type { PluginModule } from '@amk/microkernel-spi';
6
+ import type { ActivateContext } from '@amk/microkernel-api';
7
+ import type { ShellConfig } from '@amk/ui-shell-api';
8
+ import { DefaultShell } from '../core/DefaultShell';
9
+ export declare function createShellPlugin(config?: ShellConfig): PluginModule;
10
+ export declare function getShellFromContext(ctx: ActivateContext): DefaultShell;
11
+ //# sourceMappingURL=ShellPluginFactory.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ShellPluginFactory.d.ts","sourceRoot":"","sources":["../../src/plugin/ShellPluginFactory.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AASrD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGpD,wBAAgB,iBAAiB,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,YAAY,CAyEpE;AAGD,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,eAAe,GAAG,YAAY,CAEtE"}
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Shell Plugin Factory
3
+ * Creates microkernel plugin for UI Shell integration
4
+ */
5
+ import { SHELL_TOKEN, THEME_MANAGER_TOKEN, FEATURE_MANAGER_TOKEN, LAYOUT_MANAGER_TOKEN, ShellCommands, ShellEvents, } from '@amk/ui-shell-api';
6
+ import { DefaultShell } from '../core/DefaultShell';
7
+ import { DefaultLayoutManager } from '../core/DefaultLayoutManager';
8
+ export function createShellPlugin(config) {
9
+ let shell;
10
+ let layoutManager;
11
+ return {
12
+ initialize(ctx) {
13
+ shell = new DefaultShell(config);
14
+ layoutManager = new DefaultLayoutManager();
15
+ // Provide shell services
16
+ ctx.provide({ provide: SHELL_TOKEN, useValue: shell });
17
+ ctx.provide({ provide: THEME_MANAGER_TOKEN, useValue: shell.getThemeManager() });
18
+ ctx.provide({ provide: FEATURE_MANAGER_TOKEN, useValue: shell.getFeatureManager() });
19
+ ctx.provide({ provide: LAYOUT_MANAGER_TOKEN, useValue: layoutManager });
20
+ // Register commands
21
+ ctx.commands.register(ShellCommands.SET_THEME, (mode) => {
22
+ shell.getThemeManager().setTheme(mode);
23
+ });
24
+ ctx.commands.register(ShellCommands.TOGGLE_THEME, () => {
25
+ shell.getThemeManager().toggleTheme();
26
+ });
27
+ ctx.commands.register(ShellCommands.ENABLE_FEATURE, (key) => {
28
+ shell.getFeatureManager().enable(key);
29
+ });
30
+ ctx.commands.register(ShellCommands.DISABLE_FEATURE, (key) => {
31
+ shell.getFeatureManager().disable(key);
32
+ });
33
+ ctx.commands.register(ShellCommands.TOGGLE_FEATURE, (key) => {
34
+ shell.getFeatureManager().toggle(key);
35
+ });
36
+ ctx.commands.register(ShellCommands.NAVIGATE, (path) => {
37
+ const router = shell.getRouter();
38
+ if (!router) {
39
+ console.warn('Router not initialized');
40
+ return;
41
+ }
42
+ return router.push(path);
43
+ });
44
+ ctx.commands.register(ShellCommands.NAVIGATE_BACK, () => {
45
+ const router = shell.getRouter();
46
+ if (!router) {
47
+ console.warn('Router not initialized');
48
+ return;
49
+ }
50
+ router.back();
51
+ });
52
+ // Forward shell events to microkernel hooks
53
+ shell.on('shell:ready', () => ctx.hooks.emit(ShellEvents.READY, {}));
54
+ shell.on('theme:changed', (event) => ctx.hooks.emit(ShellEvents.THEME_CHANGED, event.payload));
55
+ shell.on('feature:toggled', (event) => ctx.hooks.emit(ShellEvents.FEATURE_TOGGLED, event.payload));
56
+ shell.on('route:changed', (event) => ctx.hooks.emit(ShellEvents.ROUTE_CHANGED, event.payload));
57
+ shell.on('viewport:resized', (event) => ctx.hooks.emit(ShellEvents.VIEWPORT_RESIZED, event.payload));
58
+ },
59
+ async activate(ctx) {
60
+ await shell.initialize();
61
+ const shellContext = shell.getContext();
62
+ ctx.hooks.emit('shell:activated', { context: shellContext });
63
+ },
64
+ deactivate() {
65
+ shell.destroy();
66
+ layoutManager.destroy();
67
+ },
68
+ };
69
+ }
70
+ // Helper functions
71
+ export function getShellFromContext(ctx) {
72
+ return ctx.resolve(SHELL_TOKEN);
73
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Plugin Integration
3
+ * Export plugin factory and helpers
4
+ */
5
+ export * from './ShellPluginFactory';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/plugin/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Plugin Integration
3
+ * Export plugin factory and helpers
4
+ */
5
+ export * from './ShellPluginFactory';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * CSS Variables Theme Provider
3
+ * Implements theming using CSS custom properties
4
+ */
5
+ import type { IThemeProvider } from '@amk/ui-shell-spi';
6
+ import type { ThemeMode, ThemeConfig } from '@amk/ui-shell-api';
7
+ export declare class CSSVariablesThemeProvider implements IThemeProvider {
8
+ private mediaQuery?;
9
+ private listeners;
10
+ applyTheme(mode: ThemeMode, config: ThemeConfig): void;
11
+ getSystemPreference(): 'light' | 'dark';
12
+ onSystemThemeChange(callback: (theme: 'light' | 'dark') => void): () => void;
13
+ destroy(): void;
14
+ private handleMediaQueryChange;
15
+ }
16
+ //# sourceMappingURL=CSSVariablesThemeProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CSSVariablesThemeProvider.d.ts","sourceRoot":"","sources":["../../src/providers/CSSVariablesThemeProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACxD,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhE,qBAAa,yBAA0B,YAAW,cAAc;IAC9D,OAAO,CAAC,UAAU,CAAC,CAAiB;IACpC,OAAO,CAAC,SAAS,CAAqD;IAEtE,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,WAAW,GAAG,IAAI;IAgBtD,mBAAmB,IAAI,OAAO,GAAG,MAAM;IAKvC,mBAAmB,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAiB5E,OAAO,IAAI,IAAI;IAKf,OAAO,CAAC,sBAAsB,CAG5B;CACH"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * CSS Variables Theme Provider
3
+ * Implements theming using CSS custom properties
4
+ */
5
+ export class CSSVariablesThemeProvider {
6
+ mediaQuery;
7
+ listeners = new Set();
8
+ applyTheme(mode, config) {
9
+ if (typeof document === 'undefined')
10
+ return;
11
+ const resolved = mode === 'system' ? this.getSystemPreference() : mode;
12
+ document.documentElement.setAttribute('data-theme', resolved);
13
+ document.documentElement.style.colorScheme = resolved;
14
+ // Apply custom CSS variables
15
+ if (config.cssVariables) {
16
+ Object.entries(config.cssVariables).forEach(([key, value]) => {
17
+ document.documentElement.style.setProperty(key, value);
18
+ });
19
+ }
20
+ }
21
+ getSystemPreference() {
22
+ if (typeof window === 'undefined')
23
+ return 'light';
24
+ return window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light';
25
+ }
26
+ onSystemThemeChange(callback) {
27
+ if (typeof window === 'undefined') {
28
+ return () => { };
29
+ }
30
+ this.listeners.add(callback);
31
+ if (!this.mediaQuery) {
32
+ this.mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
33
+ this.mediaQuery.addEventListener('change', this.handleMediaQueryChange);
34
+ }
35
+ return () => {
36
+ this.listeners.delete(callback);
37
+ };
38
+ }
39
+ destroy() {
40
+ this.mediaQuery?.removeEventListener('change', this.handleMediaQueryChange);
41
+ this.listeners.clear();
42
+ }
43
+ handleMediaQueryChange = () => {
44
+ const theme = this.getSystemPreference();
45
+ this.listeners.forEach(listener => listener(theme));
46
+ };
47
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Hash Router Strategy
3
+ * Uses URL hash for routing
4
+ */
5
+ import type { IRouterStrategy } from '@amk/ui-shell-spi';
6
+ export declare class HashRouterStrategy implements IRouterStrategy {
7
+ private listeners;
8
+ constructor();
9
+ push(path: string): void;
10
+ replace(path: string): void;
11
+ back(): void;
12
+ forward(): void;
13
+ getCurrentPath(): string;
14
+ listen(callback: (path: string) => void): () => void;
15
+ destroy(): void;
16
+ private setupListener;
17
+ private handleHashChange;
18
+ private notifyListeners;
19
+ }
20
+ //# sourceMappingURL=HashRouterStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HashRouterStrategy.d.ts","sourceRoot":"","sources":["../../src/providers/HashRouterStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,qBAAa,kBAAmB,YAAW,eAAe;IACxD,OAAO,CAAC,SAAS,CAA0C;;IAM3D,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAMxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAM3B,IAAI,IAAI,IAAI;IAMZ,OAAO,IAAI,IAAI;IAMf,cAAc,IAAI,MAAM;IAMxB,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAKpD,OAAO,IAAI,IAAI;IAOf,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,gBAAgB,CAGtB;IAEF,OAAO,CAAC,eAAe;CAGxB"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Hash Router Strategy
3
+ * Uses URL hash for routing
4
+ */
5
+ export class HashRouterStrategy {
6
+ listeners = new Set();
7
+ constructor() {
8
+ this.setupListener();
9
+ }
10
+ push(path) {
11
+ if (typeof window === 'undefined')
12
+ return;
13
+ window.location.hash = path;
14
+ }
15
+ replace(path) {
16
+ if (typeof window === 'undefined')
17
+ return;
18
+ window.location.replace(`#${path}`);
19
+ }
20
+ back() {
21
+ if (typeof window !== 'undefined') {
22
+ window.history.back();
23
+ }
24
+ }
25
+ forward() {
26
+ if (typeof window !== 'undefined') {
27
+ window.history.forward();
28
+ }
29
+ }
30
+ getCurrentPath() {
31
+ if (typeof window === 'undefined')
32
+ return '/';
33
+ return window.location.hash.slice(1) || '/';
34
+ }
35
+ listen(callback) {
36
+ this.listeners.add(callback);
37
+ return () => this.listeners.delete(callback);
38
+ }
39
+ destroy() {
40
+ if (typeof window !== 'undefined') {
41
+ window.removeEventListener('hashchange', this.handleHashChange);
42
+ }
43
+ this.listeners.clear();
44
+ }
45
+ setupListener() {
46
+ if (typeof window !== 'undefined') {
47
+ window.addEventListener('hashchange', this.handleHashChange);
48
+ }
49
+ }
50
+ handleHashChange = () => {
51
+ const path = this.getCurrentPath();
52
+ this.notifyListeners(path);
53
+ };
54
+ notifyListeners(path) {
55
+ this.listeners.forEach(listener => listener(path));
56
+ }
57
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * History Router Strategy
3
+ * Uses browser History API for routing
4
+ */
5
+ import type { IRouterStrategy } from '@amk/ui-shell-spi';
6
+ export declare class HistoryRouterStrategy implements IRouterStrategy {
7
+ private base;
8
+ private listeners;
9
+ constructor(base?: string);
10
+ push(path: string): void;
11
+ replace(path: string): void;
12
+ back(): void;
13
+ forward(): void;
14
+ getCurrentPath(): string;
15
+ listen(callback: (path: string) => void): () => void;
16
+ destroy(): void;
17
+ private setupListener;
18
+ private handlePopState;
19
+ private notifyListeners;
20
+ }
21
+ //# sourceMappingURL=HistoryRouterStrategy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HistoryRouterStrategy.d.ts","sourceRoot":"","sources":["../../src/providers/HistoryRouterStrategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,qBAAa,qBAAsB,YAAW,eAAe;IAC3D,OAAO,CAAC,IAAI,CAAS;IACrB,OAAO,CAAC,SAAS,CAA0C;gBAE/C,IAAI,GAAE,MAAY;IAK9B,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQxB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAQ3B,IAAI,IAAI,IAAI;IAMZ,OAAO,IAAI,IAAI;IAMf,cAAc,IAAI,MAAM;IAOxB,MAAM,CAAC,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;IAKpD,OAAO,IAAI,IAAI;IAOf,OAAO,CAAC,aAAa;IAMrB,OAAO,CAAC,cAAc,CAGpB;IAEF,OAAO,CAAC,eAAe;CAGxB"}
@@ -0,0 +1,64 @@
1
+ /**
2
+ * History Router Strategy
3
+ * Uses browser History API for routing
4
+ */
5
+ export class HistoryRouterStrategy {
6
+ base;
7
+ listeners = new Set();
8
+ constructor(base = '/') {
9
+ this.base = base;
10
+ this.setupListener();
11
+ }
12
+ push(path) {
13
+ if (typeof window === 'undefined')
14
+ return;
15
+ const fullPath = this.base + path;
16
+ window.history.pushState({}, '', fullPath);
17
+ this.notifyListeners(path);
18
+ }
19
+ replace(path) {
20
+ if (typeof window === 'undefined')
21
+ return;
22
+ const fullPath = this.base + path;
23
+ window.history.replaceState({}, '', fullPath);
24
+ this.notifyListeners(path);
25
+ }
26
+ back() {
27
+ if (typeof window !== 'undefined') {
28
+ window.history.back();
29
+ }
30
+ }
31
+ forward() {
32
+ if (typeof window !== 'undefined') {
33
+ window.history.forward();
34
+ }
35
+ }
36
+ getCurrentPath() {
37
+ if (typeof window === 'undefined')
38
+ return '/';
39
+ const path = window.location.pathname;
40
+ return path.startsWith(this.base) ? path.slice(this.base.length) : path;
41
+ }
42
+ listen(callback) {
43
+ this.listeners.add(callback);
44
+ return () => this.listeners.delete(callback);
45
+ }
46
+ destroy() {
47
+ if (typeof window !== 'undefined') {
48
+ window.removeEventListener('popstate', this.handlePopState);
49
+ }
50
+ this.listeners.clear();
51
+ }
52
+ setupListener() {
53
+ if (typeof window !== 'undefined') {
54
+ window.addEventListener('popstate', this.handlePopState);
55
+ }
56
+ }
57
+ handlePopState = () => {
58
+ const path = this.getCurrentPath();
59
+ this.notifyListeners(path);
60
+ };
61
+ notifyListeners(path) {
62
+ this.listeners.forEach(listener => listener(path));
63
+ }
64
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * LocalStorage Provider
3
+ * Implementation using browser localStorage
4
+ */
5
+ import type { IStorageProvider } from '@amk/ui-shell-spi';
6
+ export declare class LocalStorageProvider implements IStorageProvider {
7
+ getItem(key: string): string | null;
8
+ setItem(key: string, value: string): void;
9
+ removeItem(key: string): void;
10
+ clear(): void;
11
+ isAvailable(): boolean;
12
+ }
13
+ //# sourceMappingURL=LocalStorageProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"LocalStorageProvider.d.ts","sourceRoot":"","sources":["../../src/providers/LocalStorageProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,qBAAa,oBAAqB,YAAW,gBAAgB;IAC3D,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAWnC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAUzC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAU7B,KAAK,IAAI,IAAI;IAUb,WAAW,IAAI,OAAO;CAGvB"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * LocalStorage Provider
3
+ * Implementation using browser localStorage
4
+ */
5
+ export class LocalStorageProvider {
6
+ getItem(key) {
7
+ if (!this.isAvailable())
8
+ return null;
9
+ try {
10
+ return localStorage.getItem(key);
11
+ }
12
+ catch (e) {
13
+ console.warn('Failed to get item from localStorage:', e);
14
+ return null;
15
+ }
16
+ }
17
+ setItem(key, value) {
18
+ if (!this.isAvailable())
19
+ return;
20
+ try {
21
+ localStorage.setItem(key, value);
22
+ }
23
+ catch (e) {
24
+ console.warn('Failed to set item in localStorage:', e);
25
+ }
26
+ }
27
+ removeItem(key) {
28
+ if (!this.isAvailable())
29
+ return;
30
+ try {
31
+ localStorage.removeItem(key);
32
+ }
33
+ catch (e) {
34
+ console.warn('Failed to remove item from localStorage:', e);
35
+ }
36
+ }
37
+ clear() {
38
+ if (!this.isAvailable())
39
+ return;
40
+ try {
41
+ localStorage.clear();
42
+ }
43
+ catch (e) {
44
+ console.warn('Failed to clear localStorage:', e);
45
+ }
46
+ }
47
+ isAvailable() {
48
+ return typeof localStorage !== 'undefined';
49
+ }
50
+ }
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Memory Storage Provider
3
+ * In-memory storage for SSR or testing
4
+ */
5
+ import type { IStorageProvider } from '@amk/ui-shell-spi';
6
+ export declare class MemoryStorageProvider implements IStorageProvider {
7
+ private storage;
8
+ getItem(key: string): string | null;
9
+ setItem(key: string, value: string): void;
10
+ removeItem(key: string): void;
11
+ clear(): void;
12
+ isAvailable(): boolean;
13
+ }
14
+ //# sourceMappingURL=MemoryStorageProvider.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MemoryStorageProvider.d.ts","sourceRoot":"","sources":["../../src/providers/MemoryStorageProvider.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,mBAAmB,CAAC;AAE1D,qBAAa,qBAAsB,YAAW,gBAAgB;IAC5D,OAAO,CAAC,OAAO,CAAkC;IAEjD,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI;IAInC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAIzC,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI;IAI7B,KAAK,IAAI,IAAI;IAIb,WAAW,IAAI,OAAO;CAGvB"}
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Memory Storage Provider
3
+ * In-memory storage for SSR or testing
4
+ */
5
+ export class MemoryStorageProvider {
6
+ storage = new Map();
7
+ getItem(key) {
8
+ return this.storage.get(key) || null;
9
+ }
10
+ setItem(key, value) {
11
+ this.storage.set(key, value);
12
+ }
13
+ removeItem(key) {
14
+ this.storage.delete(key);
15
+ }
16
+ clear() {
17
+ this.storage.clear();
18
+ }
19
+ isAvailable() {
20
+ return true;
21
+ }
22
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Providers
3
+ * Export all provider implementations
4
+ */
5
+ export * from './LocalStorageProvider';
6
+ export * from './MemoryStorageProvider';
7
+ export * from './CSSVariablesThemeProvider';
8
+ export * from './HistoryRouterStrategy';
9
+ export * from './HashRouterStrategy';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,wBAAwB,CAAC;AACvC,cAAc,yBAAyB,CAAC;AACxC,cAAc,6BAA6B,CAAC;AAC5C,cAAc,yBAAyB,CAAC;AACxC,cAAc,sBAAsB,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Providers
3
+ * Export all provider implementations
4
+ */
5
+ export * from './LocalStorageProvider';
6
+ export * from './MemoryStorageProvider';
7
+ export * from './CSSVariablesThemeProvider';
8
+ export * from './HistoryRouterStrategy';
9
+ export * from './HashRouterStrategy';
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Utilities
3
+ * Export all utility classes
4
+ */
5
+ export * from './viewport-utils';
6
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Utilities
3
+ * Export all utility classes
4
+ */
5
+ export * from './viewport-utils';
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Viewport Utilities
3
+ */
4
+ import type { BreakpointName, Breakpoint } from '@amk/ui-shell-api';
5
+ export declare const BREAKPOINTS: Record<BreakpointName, Breakpoint>;
6
+ export declare class ViewportUtils {
7
+ static getCurrentBreakpoint(): BreakpointName;
8
+ static matchesBreakpoint(breakpoint: BreakpointName): boolean;
9
+ static isMinBreakpoint(breakpoint: BreakpointName): boolean;
10
+ static getDimensions(): {
11
+ width: number;
12
+ height: number;
13
+ };
14
+ static isTouchDevice(): boolean;
15
+ }
16
+ //# sourceMappingURL=viewport-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"viewport-utils.d.ts","sourceRoot":"","sources":["../../src/utils/viewport-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpE,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,cAAc,EAAE,UAAU,CAO1D,CAAC;AAEF,qBAAa,aAAa;IACxB,MAAM,CAAC,oBAAoB,IAAI,cAAc;IAc7C,MAAM,CAAC,iBAAiB,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO;IAS7D,MAAM,CAAC,eAAe,CAAC,UAAU,EAAE,cAAc,GAAG,OAAO;IAS3D,MAAM,CAAC,aAAa,IAAI;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE;IAWzD,MAAM,CAAC,aAAa,IAAI,OAAO;CAIhC"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Viewport Utilities
3
+ */
4
+ export const BREAKPOINTS = {
5
+ xs: { name: 'xs', minWidth: 0, maxWidth: 639 },
6
+ sm: { name: 'sm', minWidth: 640, maxWidth: 767 },
7
+ md: { name: 'md', minWidth: 768, maxWidth: 1023 },
8
+ lg: { name: 'lg', minWidth: 1024, maxWidth: 1279 },
9
+ xl: { name: 'xl', minWidth: 1280, maxWidth: 1535 },
10
+ '2xl': { name: '2xl', minWidth: 1536 },
11
+ };
12
+ export class ViewportUtils {
13
+ static getCurrentBreakpoint() {
14
+ if (typeof window === 'undefined')
15
+ return 'md';
16
+ const width = window.innerWidth;
17
+ for (const [name, breakpoint] of Object.entries(BREAKPOINTS)) {
18
+ if (width >= breakpoint.minWidth && (!breakpoint.maxWidth || width <= breakpoint.maxWidth)) {
19
+ return name;
20
+ }
21
+ }
22
+ return 'md';
23
+ }
24
+ static matchesBreakpoint(breakpoint) {
25
+ if (typeof window === 'undefined')
26
+ return false;
27
+ const width = window.innerWidth;
28
+ const bp = BREAKPOINTS[breakpoint];
29
+ return width >= bp.minWidth && (!bp.maxWidth || width <= bp.maxWidth);
30
+ }
31
+ static isMinBreakpoint(breakpoint) {
32
+ if (typeof window === 'undefined')
33
+ return false;
34
+ const width = window.innerWidth;
35
+ const bp = BREAKPOINTS[breakpoint];
36
+ return width >= bp.minWidth;
37
+ }
38
+ static getDimensions() {
39
+ if (typeof window === 'undefined') {
40
+ return { width: 0, height: 0 };
41
+ }
42
+ return {
43
+ width: window.innerWidth,
44
+ height: window.innerHeight,
45
+ };
46
+ }
47
+ static isTouchDevice() {
48
+ if (typeof window === 'undefined')
49
+ return false;
50
+ return 'ontouchstart' in window || navigator.maxTouchPoints > 0;
51
+ }
52
+ }
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@hamak/ui-shell-impl",
3
+ "version": "0.1.0",
4
+ "private": false,
5
+ "type": "module",
6
+ "description": "UI Shell Implementation - Core UI shell functionality",
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "sideEffects": false,
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/amah/app-framework.git",
13
+ "directory": "packages/ui-shell/ui-shell-impl"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "scripts": {
19
+ "build": "tsc -p tsconfig.json",
20
+ "clean": "rm -rf dist"
21
+ },
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ }
27
+ },
28
+ "dependencies": {
29
+ "@hamak/ui-shell-api": "0.1.0",
30
+ "@hamak/ui-shell-spi": "0.1.0",
31
+ "@hamak/microkernel-api": "0.1.0",
32
+ "@hamak/microkernel-spi": "0.1.0"
33
+ },
34
+ "devDependencies": {
35
+ "typescript": "~5.4.0"
36
+ }
37
+ }