slicejs-web-framework 4.0.1 → 4.0.2

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/.opencode/opencode.json +14 -14
  2. package/LICENSE +21 -21
  3. package/README.md +97 -97
  4. package/Slice/Components/Structural/ContextManager/ContextManager.js +422 -422
  5. package/Slice/Components/Structural/ContextManager/ContextManagerDebugger.js +470 -470
  6. package/Slice/Components/Structural/Controller/Controller.js +1406 -1406
  7. package/Slice/Components/Structural/Controller/allowedValuesValidation.js +52 -52
  8. package/Slice/Components/Structural/Debugger/Debugger.html +72 -72
  9. package/Slice/Components/Structural/Debugger/Debugger.js +1505 -1505
  10. package/Slice/Components/Structural/EventManager/EventManager.js +651 -651
  11. package/Slice/Components/Structural/EventManager/EventManagerDebugger.js +985 -985
  12. package/Slice/Components/Structural/LeakInspector/LeakInspector.js +296 -296
  13. package/Slice/Components/Structural/Logger/Log.js +10 -10
  14. package/Slice/Components/Structural/Logger/LogViewer/LogViewer.js +662 -662
  15. package/Slice/Components/Structural/Logger/Logger.js +225 -225
  16. package/Slice/Components/Structural/Router/Router.js +810 -793
  17. package/Slice/Components/Structural/StylesManager/StylesManager.js +82 -82
  18. package/Slice/Components/Structural/StylesManager/ThemeManager/ThemeManager.js +175 -162
  19. package/Slice/Slice.js +708 -685
  20. package/Slice/tests/build-bundled-component-without-category.test.js +103 -103
  21. package/Slice/tests/build-js-only-visual-components.test.js +144 -144
  22. package/Slice/tests/build-singleton.test.js +244 -244
  23. package/Slice/tests/bundle-v2-runtime-contract.test.js +747 -738
  24. package/Slice/tests/context-patch-use.test.js +95 -95
  25. package/Slice/tests/destroy-cascade.test.js +215 -215
  26. package/Slice/tests/event-emitters.test.js +79 -79
  27. package/Slice/tests/event-registry.test.js +141 -141
  28. package/Slice/tests/fixtures/real-runtime-loader.mjs +21 -21
  29. package/Slice/tests/leak-orphans.test.js +131 -131
  30. package/Slice/tests/props-allowed-values-validation.test.js +119 -119
  31. package/Slice/tests/public-env-runtime-accessors.test.js +44 -44
  32. package/Slice/tests/public-env-typed-accessors.test.js +66 -66
  33. package/Slice/tests/router-loading-finally.test.js +68 -68
  34. package/api/framework/devDepsOptimizer.js +335 -335
  35. package/api/framework/express.js +3 -3
  36. package/api/framework/precompressedStatic.js +93 -93
  37. package/api/framework/publicEnvResolver.js +123 -123
  38. package/api/framework/securityMiddleware.js +197 -197
  39. package/api/framework/server.js +411 -411
  40. package/api/index.js +7 -7
  41. package/api/tests/dev-deps-optimizer.test.js +137 -137
  42. package/api/tests/dev-server-external.test.js +56 -56
  43. package/api/tests/precompressed-static.test.js +119 -119
  44. package/api/tests/public-env-resolver.test.js +193 -193
  45. package/package.json +49 -49
  46. package/sliceConfig.schema.json +122 -122
  47. package/src/App/index.html +69 -69
  48. package/src/App/index.js +20 -20
  49. package/src/App/style.css +11 -11
  50. package/src/Components/AppComponents/AboutSection/AboutSection.css +9 -9
  51. package/src/Components/AppComponents/AboutSection/AboutSection.html +8 -8
  52. package/src/Components/AppComponents/AboutSection/AboutSection.js +12 -12
  53. package/src/Components/AppComponents/AppShell/AppShell.css +10 -10
  54. package/src/Components/AppComponents/AppShell/AppShell.html +4 -4
  55. package/src/Components/AppComponents/AppShell/AppShell.js +36 -36
  56. package/src/Components/AppComponents/HomeSection/HomeSection.css +20 -20
  57. package/src/Components/AppComponents/HomeSection/HomeSection.html +10 -10
  58. package/src/Components/AppComponents/HomeSection/HomeSection.js +19 -19
  59. package/src/Components/components.js +8 -8
  60. package/src/public/Styles/sliceStyles.css +34 -34
  61. package/src/public/Themes/Dark.css +42 -42
  62. package/src/public/Themes/Light.css +31 -31
  63. package/src/public/Themes/Slice.css +47 -47
  64. package/src/public/manifest.json +15 -15
  65. package/src/public/robots.txt +4 -4
  66. package/src/public/sitemap.xml +8 -8
  67. package/src/routes.js +9 -9
  68. package/src/sliceConfig.json +72 -72
  69. package/tests/router-build-failure.test.js +125 -0
  70. package/tests/router-emit-ordering.test.js +63 -63
  71. package/types/index.d.ts +219 -219
package/types/index.d.ts CHANGED
@@ -1,219 +1,219 @@
1
- export type SliceMode = 'development' | 'production' | string;
2
-
3
- export interface RouteConfig {
4
- path: string;
5
- component: string;
6
- children?: RouteConfig[];
7
- metadata?: Record<string, unknown>;
8
- fullPath?: string;
9
- parentPath?: string | null;
10
- parentRoute?: RouteConfig | null;
11
- }
12
-
13
- export interface RouteInfo {
14
- path: string;
15
- component: string;
16
- params: Record<string, string>;
17
- query: Record<string, string>;
18
- metadata: Record<string, unknown>;
19
- }
20
-
21
- export interface RouteMatch {
22
- route: RouteConfig | null;
23
- params: Record<string, string>;
24
- childRoute?: RouteConfig;
25
- }
26
-
27
- export type RouterNext = (arg?: void | false | string | { path: string; replace?: boolean }) => void;
28
-
29
- export interface SliceControllerApi {
30
- componentCategories: Map<string, string>;
31
- templates: Map<string, HTMLTemplateElement>;
32
- classes: Map<string, new (...args: any[]) => HTMLElement>;
33
- requestedStyles: Set<string>;
34
- activeComponents: Map<string, HTMLElement>;
35
- getComponent(sliceId: string): HTMLElement | undefined;
36
- getComponentCategory(componentSliceId: string): string | undefined;
37
- fetchText(
38
- componentName: string,
39
- resourceType: 'html' | 'css' | 'theme' | 'styles',
40
- componentCategory?: string,
41
- customPath?: string
42
- ): Promise<string>;
43
- setComponentProps(component: HTMLElement, props: Record<string, unknown>): void;
44
- destroyComponent(components: HTMLElement | string | Array<HTMLElement | string>): number;
45
- destroyByContainer(container: HTMLElement): number;
46
- destroyByPattern(pattern: string | RegExp): number;
47
- findOrphans(): Array<{ sliceId: string; name: string; reason: string; retainPath: string[] }>;
48
- registerLeakExclusion(predicate: (component: HTMLElement) => boolean): void;
49
- sampleComponentGrowth(): void;
50
- isGrowthMonotonic(): boolean;
51
- }
52
-
53
- export interface SliceStylesManagerApi {
54
- componentStyles: HTMLStyleElement;
55
- themeManager?: SliceThemeManagerApi;
56
- init(): Promise<void>;
57
- appendComponentStyles(cssText: string): void;
58
- registerComponentStyles(componentName: string, cssText: string): void;
59
- }
60
-
61
- export interface SliceThemeManagerApi {
62
- currentTheme: string | null;
63
- applyTheme(themeName: string): Promise<void>;
64
- }
65
-
66
- export interface SliceLoggerApi {
67
- logError(componentSliceId: string, message: string, error?: unknown): void;
68
- logWarning(componentSliceId: string, message: string): void;
69
- logInfo(componentSliceId: string, message: string): void;
70
- getLogs(): unknown[];
71
- clearLogs(): void;
72
- }
73
-
74
- export interface SliceEventBindingApi {
75
- subscribe(eventName: string, callback: (data?: unknown) => void): string | null;
76
- subscribeOnce(eventName: string, callback: (data?: unknown) => void): string | null;
77
- emit(eventName: string, data?: unknown): void;
78
- }
79
-
80
- export interface SliceEventManagerApi {
81
- init(): boolean;
82
- subscribe(
83
- eventName: string,
84
- callback: (data?: unknown) => void,
85
- options?: { component?: HTMLElement }
86
- ): string | null;
87
- subscribeOnce(
88
- eventName: string,
89
- callback: (data?: unknown) => void,
90
- options?: { component?: HTMLElement }
91
- ): string | null;
92
- unsubscribe(eventName: string, subscriptionId: string): boolean;
93
- emit(eventName: string, ...data: unknown[]): void;
94
- bind(component: HTMLElement): SliceEventBindingApi | null;
95
- register(namespace: string, catalog: Record<string, { description?: string; payload?: unknown }>): SliceEventManagerApi;
96
- register(catalog: Record<string, { description?: string; payload?: unknown }>): SliceEventManagerApi;
97
- loadGraph(graph: { events: Record<string, unknown>; dynamic?: unknown }): SliceEventManagerApi;
98
- staticEmittersOf(eventName: string): Array<{ file: string; line: number; component: string | null }>;
99
- staticListenersOf(eventName: string): Array<{ file: string; line: number; component: string | null }>;
100
- isDeclared(eventName: string): boolean;
101
- namespaceOf(eventName: string): string | null;
102
- cleanupComponent(sliceId: string): number;
103
- hasSubscribers(eventName: string): boolean;
104
- subscriberCount(eventName: string): number;
105
- clear(): void;
106
- }
107
-
108
- export interface SliceContextOptions {
109
- persist?: boolean;
110
- storageKey?: string;
111
- }
112
-
113
- export interface SliceContextManagerApi {
114
- init(): boolean;
115
- create(name: string, initialState?: Record<string, unknown>, options?: SliceContextOptions): boolean;
116
- getState<T = unknown>(name: string): T | null;
117
- setState<T = unknown>(name: string, updater: T | ((prevState: T) => T)): void;
118
- watch<TSelected = unknown>(
119
- name: string,
120
- component: HTMLElement,
121
- callback: (value: TSelected) => void,
122
- selector?: (state: unknown) => TSelected
123
- ): string | null;
124
- has(name: string): boolean;
125
- destroy(name: string): boolean;
126
- list(): string[];
127
- }
128
-
129
- export interface SliceRouterApi {
130
- activeRoute: RouteConfig | null;
131
- pathToRouteMap: Map<string, RouteConfig>;
132
- init(): void;
133
- start(): Promise<void>;
134
- beforeEach(guard: (to: RouteInfo, from: RouteInfo, next: RouterNext) => void | Promise<void>): void;
135
- afterEach(guard: (to: RouteInfo, from: RouteInfo) => void): void;
136
- navigate(path: string, redirectChain?: string[], options?: { replace?: boolean }): Promise<void>;
137
- matchRoute(path: string): RouteMatch;
138
- }
139
-
140
- export interface SlicePanelDebuggerApi {
141
- init(): Promise<void>;
142
- toggle(): void;
143
- open(): void;
144
- close(): void;
145
- }
146
-
147
- export interface SliceDebuggerApi {
148
- enableDebugMode(): Promise<boolean>;
149
- attachDebugMode(component: HTMLElement): void;
150
- hide(): void;
151
- }
152
-
153
- export interface SliceLoadingApi {
154
- start?: () => void;
155
- stop?: () => void;
156
- }
157
-
158
- export interface SlicePaths {
159
- routesFile?: string;
160
- themes?: string;
161
- styles?: string;
162
- structuralComponentFolderPath?: string;
163
- components?: Record<string, { path: string; type?: string }>;
164
- [key: string]: unknown;
165
- }
166
-
167
- export interface SliceFrameworkClasses {
168
- Controller?: new () => SliceControllerApi;
169
- StylesManager?: new () => SliceStylesManagerApi;
170
- Router?: new (routes: RouteConfig[]) => SliceRouterApi;
171
- Logger?: new () => SliceLoggerApi;
172
- EventManager?: new () => SliceEventManagerApi;
173
- ContextManager?: new () => SliceContextManagerApi;
174
- Debugger?: new () => SliceDebuggerApi;
175
- EventManagerDebugger?: new () => SlicePanelDebuggerApi;
176
- ContextManagerDebugger?: new () => SlicePanelDebuggerApi;
177
- ThemeManager?: new () => SliceThemeManagerApi;
178
- [key: string]: unknown;
179
- }
180
-
181
- export interface SliceApi {
182
- frameworkClasses: SliceFrameworkClasses | null;
183
- controller: SliceControllerApi;
184
- stylesManager: SliceStylesManagerApi;
185
- logger: SliceLoggerApi;
186
- router: SliceRouterApi;
187
- events: SliceEventManagerApi;
188
- context: SliceContextManagerApi;
189
- debugger?: SliceDebuggerApi;
190
- eventsDebugger?: SlicePanelDebuggerApi;
191
- contextDebugger?: SlicePanelDebuggerApi;
192
- leakInspector?: SlicePanelDebuggerApi;
193
- loading?: SliceLoadingApi;
194
- paths: SlicePaths;
195
- _mode: SliceMode;
196
- getClass<T = unknown>(module: string): Promise<T | undefined>;
197
- isProduction(): boolean;
198
- getEnv(name: string, fallbackValue?: string): string | undefined;
199
- getPublicEnv(): Record<string, string>;
200
- getComponent(componentSliceId: string): HTMLElement | undefined;
201
- build<T = HTMLElement>(componentName: string, props?: Record<string, unknown>): Promise<T | null>;
202
- setTheme(themeName: string): Promise<void>;
203
- readonly theme: string | null;
204
- attachTemplate(componentInstance: HTMLElement): void;
205
- }
206
-
207
- declare class Slice {
208
- constructor(sliceConfig: Record<string, unknown>, frameworkClasses?: SliceFrameworkClasses | null);
209
- }
210
-
211
- export default Slice;
212
-
213
- declare global {
214
- interface Window {
215
- slice: SliceApi;
216
- }
217
-
218
- const slice: SliceApi;
219
- }
1
+ export type SliceMode = 'development' | 'production' | string;
2
+
3
+ export interface RouteConfig {
4
+ path: string;
5
+ component: string;
6
+ children?: RouteConfig[];
7
+ metadata?: Record<string, unknown>;
8
+ fullPath?: string;
9
+ parentPath?: string | null;
10
+ parentRoute?: RouteConfig | null;
11
+ }
12
+
13
+ export interface RouteInfo {
14
+ path: string;
15
+ component: string;
16
+ params: Record<string, string>;
17
+ query: Record<string, string>;
18
+ metadata: Record<string, unknown>;
19
+ }
20
+
21
+ export interface RouteMatch {
22
+ route: RouteConfig | null;
23
+ params: Record<string, string>;
24
+ childRoute?: RouteConfig;
25
+ }
26
+
27
+ export type RouterNext = (arg?: void | false | string | { path: string; replace?: boolean }) => void;
28
+
29
+ export interface SliceControllerApi {
30
+ componentCategories: Map<string, string>;
31
+ templates: Map<string, HTMLTemplateElement>;
32
+ classes: Map<string, new (...args: any[]) => HTMLElement>;
33
+ requestedStyles: Set<string>;
34
+ activeComponents: Map<string, HTMLElement>;
35
+ getComponent(sliceId: string): HTMLElement | undefined;
36
+ getComponentCategory(componentSliceId: string): string | undefined;
37
+ fetchText(
38
+ componentName: string,
39
+ resourceType: 'html' | 'css' | 'theme' | 'styles',
40
+ componentCategory?: string,
41
+ customPath?: string
42
+ ): Promise<string>;
43
+ setComponentProps(component: HTMLElement, props: Record<string, unknown>): void;
44
+ destroyComponent(components: HTMLElement | string | Array<HTMLElement | string>): number;
45
+ destroyByContainer(container: HTMLElement): number;
46
+ destroyByPattern(pattern: string | RegExp): number;
47
+ findOrphans(): Array<{ sliceId: string; name: string; reason: string; retainPath: string[] }>;
48
+ registerLeakExclusion(predicate: (component: HTMLElement) => boolean): void;
49
+ sampleComponentGrowth(): void;
50
+ isGrowthMonotonic(): boolean;
51
+ }
52
+
53
+ export interface SliceStylesManagerApi {
54
+ componentStyles: HTMLStyleElement;
55
+ themeManager?: SliceThemeManagerApi;
56
+ init(): Promise<void>;
57
+ appendComponentStyles(cssText: string): void;
58
+ registerComponentStyles(componentName: string, cssText: string): void;
59
+ }
60
+
61
+ export interface SliceThemeManagerApi {
62
+ currentTheme: string | null;
63
+ applyTheme(themeName: string): Promise<void>;
64
+ }
65
+
66
+ export interface SliceLoggerApi {
67
+ logError(componentSliceId: string, message: string, error?: unknown): void;
68
+ logWarning(componentSliceId: string, message: string): void;
69
+ logInfo(componentSliceId: string, message: string): void;
70
+ getLogs(): unknown[];
71
+ clearLogs(): void;
72
+ }
73
+
74
+ export interface SliceEventBindingApi {
75
+ subscribe(eventName: string, callback: (data?: unknown) => void): string | null;
76
+ subscribeOnce(eventName: string, callback: (data?: unknown) => void): string | null;
77
+ emit(eventName: string, data?: unknown): void;
78
+ }
79
+
80
+ export interface SliceEventManagerApi {
81
+ init(): boolean;
82
+ subscribe(
83
+ eventName: string,
84
+ callback: (data?: unknown) => void,
85
+ options?: { component?: HTMLElement }
86
+ ): string | null;
87
+ subscribeOnce(
88
+ eventName: string,
89
+ callback: (data?: unknown) => void,
90
+ options?: { component?: HTMLElement }
91
+ ): string | null;
92
+ unsubscribe(eventName: string, subscriptionId: string): boolean;
93
+ emit(eventName: string, ...data: unknown[]): void;
94
+ bind(component: HTMLElement): SliceEventBindingApi | null;
95
+ register(namespace: string, catalog: Record<string, { description?: string; payload?: unknown }>): SliceEventManagerApi;
96
+ register(catalog: Record<string, { description?: string; payload?: unknown }>): SliceEventManagerApi;
97
+ loadGraph(graph: { events: Record<string, unknown>; dynamic?: unknown }): SliceEventManagerApi;
98
+ staticEmittersOf(eventName: string): Array<{ file: string; line: number; component: string | null }>;
99
+ staticListenersOf(eventName: string): Array<{ file: string; line: number; component: string | null }>;
100
+ isDeclared(eventName: string): boolean;
101
+ namespaceOf(eventName: string): string | null;
102
+ cleanupComponent(sliceId: string): number;
103
+ hasSubscribers(eventName: string): boolean;
104
+ subscriberCount(eventName: string): number;
105
+ clear(): void;
106
+ }
107
+
108
+ export interface SliceContextOptions {
109
+ persist?: boolean;
110
+ storageKey?: string;
111
+ }
112
+
113
+ export interface SliceContextManagerApi {
114
+ init(): boolean;
115
+ create(name: string, initialState?: Record<string, unknown>, options?: SliceContextOptions): boolean;
116
+ getState<T = unknown>(name: string): T | null;
117
+ setState<T = unknown>(name: string, updater: T | ((prevState: T) => T)): void;
118
+ watch<TSelected = unknown>(
119
+ name: string,
120
+ component: HTMLElement,
121
+ callback: (value: TSelected) => void,
122
+ selector?: (state: unknown) => TSelected
123
+ ): string | null;
124
+ has(name: string): boolean;
125
+ destroy(name: string): boolean;
126
+ list(): string[];
127
+ }
128
+
129
+ export interface SliceRouterApi {
130
+ activeRoute: RouteConfig | null;
131
+ pathToRouteMap: Map<string, RouteConfig>;
132
+ init(): void;
133
+ start(): Promise<void>;
134
+ beforeEach(guard: (to: RouteInfo, from: RouteInfo, next: RouterNext) => void | Promise<void>): void;
135
+ afterEach(guard: (to: RouteInfo, from: RouteInfo) => void): void;
136
+ navigate(path: string, redirectChain?: string[], options?: { replace?: boolean }): Promise<void>;
137
+ matchRoute(path: string): RouteMatch;
138
+ }
139
+
140
+ export interface SlicePanelDebuggerApi {
141
+ init(): Promise<void>;
142
+ toggle(): void;
143
+ open(): void;
144
+ close(): void;
145
+ }
146
+
147
+ export interface SliceDebuggerApi {
148
+ enableDebugMode(): Promise<boolean>;
149
+ attachDebugMode(component: HTMLElement): void;
150
+ hide(): void;
151
+ }
152
+
153
+ export interface SliceLoadingApi {
154
+ start?: () => void;
155
+ stop?: () => void;
156
+ }
157
+
158
+ export interface SlicePaths {
159
+ routesFile?: string;
160
+ themes?: string;
161
+ styles?: string;
162
+ structuralComponentFolderPath?: string;
163
+ components?: Record<string, { path: string; type?: string }>;
164
+ [key: string]: unknown;
165
+ }
166
+
167
+ export interface SliceFrameworkClasses {
168
+ Controller?: new () => SliceControllerApi;
169
+ StylesManager?: new () => SliceStylesManagerApi;
170
+ Router?: new (routes: RouteConfig[]) => SliceRouterApi;
171
+ Logger?: new () => SliceLoggerApi;
172
+ EventManager?: new () => SliceEventManagerApi;
173
+ ContextManager?: new () => SliceContextManagerApi;
174
+ Debugger?: new () => SliceDebuggerApi;
175
+ EventManagerDebugger?: new () => SlicePanelDebuggerApi;
176
+ ContextManagerDebugger?: new () => SlicePanelDebuggerApi;
177
+ ThemeManager?: new () => SliceThemeManagerApi;
178
+ [key: string]: unknown;
179
+ }
180
+
181
+ export interface SliceApi {
182
+ frameworkClasses: SliceFrameworkClasses | null;
183
+ controller: SliceControllerApi;
184
+ stylesManager: SliceStylesManagerApi;
185
+ logger: SliceLoggerApi;
186
+ router: SliceRouterApi;
187
+ events: SliceEventManagerApi;
188
+ context: SliceContextManagerApi;
189
+ debugger?: SliceDebuggerApi;
190
+ eventsDebugger?: SlicePanelDebuggerApi;
191
+ contextDebugger?: SlicePanelDebuggerApi;
192
+ leakInspector?: SlicePanelDebuggerApi;
193
+ loading?: SliceLoadingApi;
194
+ paths: SlicePaths;
195
+ _mode: SliceMode;
196
+ getClass<T = unknown>(module: string): Promise<T | undefined>;
197
+ isProduction(): boolean;
198
+ getEnv(name: string, fallbackValue?: string): string | undefined;
199
+ getPublicEnv(): Record<string, string>;
200
+ getComponent(componentSliceId: string): HTMLElement | undefined;
201
+ build<T = HTMLElement>(componentName: string, props?: Record<string, unknown>): Promise<T | null>;
202
+ setTheme(themeName: string): Promise<void>;
203
+ readonly theme: string | null;
204
+ attachTemplate(componentInstance: HTMLElement): void;
205
+ }
206
+
207
+ declare class Slice {
208
+ constructor(sliceConfig: Record<string, unknown>, frameworkClasses?: SliceFrameworkClasses | null);
209
+ }
210
+
211
+ export default Slice;
212
+
213
+ declare global {
214
+ interface Window {
215
+ slice: SliceApi;
216
+ }
217
+
218
+ const slice: SliceApi;
219
+ }