apprun 3.38.0 → 6.0.0-rc.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 (113) hide show
  1. package/CHANGELOG.md +12 -1
  2. package/README.md +18 -10
  3. package/apprun.d.ts +67 -23
  4. package/dist/apprun-code.js +1 -1
  5. package/dist/apprun-code.js.map +1 -1
  6. package/dist/apprun-dev-tools.js +1 -1
  7. package/dist/apprun-dev-tools.js.map +1 -1
  8. package/dist/apprun-html.esm.js +7 -7
  9. package/dist/apprun-html.esm.js.map +1 -1
  10. package/dist/apprun-html.js +1 -1
  11. package/dist/apprun-html.js.map +1 -1
  12. package/dist/apprun-play.js +1 -1
  13. package/dist/apprun-play.js.map +1 -1
  14. package/dist/apprun.esm.js +1 -1
  15. package/dist/apprun.esm.js.map +1 -1
  16. package/dist/apprun.js +1 -1
  17. package/dist/apprun.js.map +1 -1
  18. package/esm/add-components.js +7 -7
  19. package/esm/add-components.js.map +1 -1
  20. package/esm/app.js +81 -32
  21. package/esm/app.js.map +1 -1
  22. package/esm/apprun-code.js +8 -2
  23. package/esm/apprun-code.js.map +1 -1
  24. package/esm/apprun-html.js +14 -9
  25. package/esm/apprun-html.js.map +1 -1
  26. package/esm/apprun-play.js +7 -1
  27. package/esm/apprun-play.js.map +1 -1
  28. package/esm/apprun.js +38 -19
  29. package/esm/apprun.js.map +1 -1
  30. package/esm/component.js +90 -37
  31. package/esm/component.js.map +1 -1
  32. package/esm/directive.js +1 -1
  33. package/esm/directive.js.map +1 -1
  34. package/esm/router.js +73 -19
  35. package/esm/router.js.map +1 -1
  36. package/esm/types.js +2 -1
  37. package/esm/types.js.map +1 -1
  38. package/esm/vdom-my.js +52 -52
  39. package/esm/vdom-my.js.map +1 -1
  40. package/esm/vdom-to-html.js +8 -1
  41. package/esm/vdom-to-html.js.map +1 -1
  42. package/esm/vdom.js +3 -3
  43. package/esm/vdom.js.map +1 -1
  44. package/esm/version.js +1 -1
  45. package/esm/version.js.map +1 -1
  46. package/esm/web-component.js +23 -6
  47. package/esm/web-component.js.map +1 -1
  48. package/jsx-runtime.js +1 -1
  49. package/jsx-runtime.js.map +1 -1
  50. package/package.json +62 -2
  51. package/.clinerules +0 -1
  52. package/.travis.yml +0 -10
  53. package/BACKERS.md +0 -8
  54. package/CNAME +0 -1
  55. package/WHATSNEW.md +0 -367
  56. package/ai/apprun-html.prompt.md +0 -290
  57. package/ai/apprun.prompt.md +0 -602
  58. package/apprun-book.jpg +0 -0
  59. package/dist/apprun-dev-tools-tests.js +0 -1
  60. package/dist/apprun-dev-tools.js.LICENSE.txt +0 -1
  61. package/dist/apprun-play-html.esm.js +0 -34
  62. package/dist/apprun-play-html.esm.js.map +0 -1
  63. package/error.log +0 -0
  64. package/esm/apprun-play-html.js +0 -210
  65. package/esm/apprun-play-html.js.map +0 -1
  66. package/esm/shadow.js +0 -8
  67. package/esm/shadow.js.map +0 -1
  68. package/esm/vdom-html.js +0 -22
  69. package/esm/vdom-html.js.map +0 -1
  70. package/esm/vdom-my-new.js +0 -327
  71. package/esm/vdom-my-new.js.map +0 -1
  72. package/esm/vdom-patch.js +0 -103
  73. package/esm/vdom-patch.js.map +0 -1
  74. package/index.html +0 -87
  75. package/jest.config.js +0 -57
  76. package/jest.setup.js +0 -73
  77. package/logo.png +0 -0
  78. package/react.js +0 -13
  79. package/rollup.config.js +0 -62
  80. package/src/add-components.ts +0 -103
  81. package/src/app.ts +0 -173
  82. package/src/apprun-code.tsx +0 -177
  83. package/src/apprun-dev-tools-tests.tsx +0 -101
  84. package/src/apprun-dev-tools.tsx +0 -307
  85. package/src/apprun-html.ts +0 -25
  86. package/src/apprun-play.tsx +0 -249
  87. package/src/apprun.ts +0 -238
  88. package/src/component.ts +0 -388
  89. package/src/createState.ts +0 -11
  90. package/src/decorator.ts +0 -98
  91. package/src/directive.ts +0 -303
  92. package/src/global.d.ts +0 -22
  93. package/src/router.ts +0 -311
  94. package/src/shadow.tsx +0 -8
  95. package/src/tsconfig.json +0 -16
  96. package/src/type-utils.ts +0 -130
  97. package/src/types.ts +0 -151
  98. package/src/vdom-html.ts_ +0 -20
  99. package/src/vdom-lit-html.ts +0 -67
  100. package/src/vdom-my-new.ts +0 -311
  101. package/src/vdom-my-prop-attr.ts +0 -241
  102. package/src/vdom-my.ts +0 -286
  103. package/src/vdom-patch.ts +0 -108
  104. package/src/vdom-to-html.tsx +0 -49
  105. package/src/vdom.ts +0 -28
  106. package/src/version.ts +0 -16
  107. package/src/web-component.ts +0 -154
  108. package/tsconfig.jest.json +0 -49
  109. package/tsconfig.json +0 -16
  110. package/tslint.json +0 -114
  111. package/typescriptreact.json +0 -87
  112. package/viewEngine.js +0 -54
  113. package/webpack.config.cjs +0 -41
package/src/router.ts DELETED
@@ -1,311 +0,0 @@
1
- /**
2
- * AppRun Router Implementation with Hierarchical Matching
3
- *
4
- * This file provides URL routing capabilities:
5
- * 1. Hash-based routing (#/path)
6
- * - Works with SPA mode using hash fragments
7
- * - Handles hashchange events automatically
8
- * - No server configuration required
9
- * 2. Path-based routing (/path)
10
- * - Works with browser history API
11
- * - Requires server configuration for SPA routing
12
- * - Handles popstate events automatically
13
- * 3. Event-based navigation
14
- * - Routes trigger corresponding component events
15
- * - Automatic route parameter extraction
16
- * - Fallback to 404 handling for unknown routes
17
- *
18
- * Features:
19
- * - Automatic route event firing with ROUTER_EVENT
20
- * - 404 handling via ROUTER_404_EVENT for unmatched routes
21
- * - History API integration for seamless navigation
22
- * - Route parameter parsing and injection into events
23
- * - URL pattern matching with parameter support
24
- * - Global and component-level route handling
25
- * - **NEW: Hierarchical route matching** - progressively tries parent routes
26
- *
27
- * Type Safety Improvements (v3.35.1):
28
- * - Enhanced route type definitions
29
- * - Better parameter type inference
30
- * - Improved URL validation and error handling
31
- *
32
- * Usage:
33
- * ```ts
34
- * // Basic routing
35
- * app.on('#/home', () => // Show home page);
36
- * app.on('#/users/:id', (id) => // Show user profile);
37
- * app.on('/api/*', (path) => // Handle API routes);
38
- *
39
- * // Navigate programmatically
40
- * app.run('route', '#/home');
41
- * route('/users/123'); // Direct routing
42
- *
43
- * // Hierarchical matching examples
44
- * app.on('/api', (operation, id) => // Handle /api/users/123);
45
- * app.on('#users', (id, action) => // Handle #users/123/edit);
46
- *
47
- * // Hierarchical Route Matching (NEW):
48
- * // For URL: /api/v1/users/123
49
- * // Router tries: /api/v1/users/123 → /api/v1/users → /api/v1 → /api → 404
50
- * // If handler found at /api, it receives: ('v1', 'users', '123')
51
- *
52
- * // Base Path Support (NEW):
53
- * app.basePath = '/myapp'; // For sub-directory deployments
54
- * // Links: <a href="/users/123"> (relative paths)
55
- * // Navigation: /myapp/users/123 (full path)
56
- * // Routing: /users/123 (base path stripped)
57
- *
58
- * // Empty Path Handling (NEW):
59
- * // For URL: "" (empty)
60
- * // Router tries: # → / → #/ → 404 (in priority order)
61
- *
62
- * // 404 Behavior (ENHANCED):
63
- * // Fires only at minimal levels: /a, #a, #/a, a
64
- * // Never tries root handlers: /, #, #/
65
- * ```
66
- */
67
-
68
- import app from './app';
69
-
70
- // Helper functions for hierarchical routing
71
-
72
- /**
73
- * Extract clean path segments from URL
74
- * @param url - The URL to parse
75
- * @returns Array of path segments
76
- */
77
- function parsePathSegments(url: string): string[] {
78
- if (!url) return [];
79
-
80
- // Handle different URL types
81
- if (url.startsWith('#/')) {
82
- return url.substring(2).split('/');
83
- } else if (url.startsWith('#')) {
84
- return url.substring(1).split('/');
85
- } else if (url.startsWith('/')) {
86
- return url.substring(1).split('/');
87
- } else {
88
- return url.split('/');
89
- }
90
- }
91
-
92
- /**
93
- * Normalize trailing slash - convert /a/ to /a
94
- * @param url - The URL to normalize
95
- * @returns Normalized URL
96
- */
97
- function normalizeTrailingSlash(url: string): string {
98
- if (!url || url === '/' || url === '#' || url === '#/') return url;
99
- if (url.endsWith('/')) return url.slice(0, -1);
100
- return url;
101
- }
102
-
103
- /**
104
- * Validate hierarchy depth and warn if too deep
105
- * @param segments - Path segments to validate
106
- */
107
- function validateHierarchyDepth(segments: string[]): void {
108
- // Count non-empty segments for depth validation
109
- const nonEmptySegments = segments.filter(Boolean);
110
- if (nonEmptySegments.length > 11) {
111
- console.warn(`Deep route hierarchy detected: ${nonEmptySegments.join('/')} (${nonEmptySegments.length} levels)`);
112
- }
113
- }
114
-
115
- /**
116
- * Strip base path from URL
117
- * @param url - The URL to process
118
- * @param basePath - The base path to remove
119
- * @returns URL with base path removed
120
- */
121
- function stripBasePath(url: string, basePath: string): string {
122
- if (!basePath || basePath === '/' || basePath === '') return url;
123
-
124
- // Normalize base path
125
- const normalizedBasePath = basePath.startsWith('/') ? basePath : '/' + basePath;
126
-
127
- if (url.startsWith(normalizedBasePath)) {
128
- const stripped = url.substring(normalizedBasePath.length);
129
- return stripped.startsWith('/') ? stripped : '/' + stripped;
130
- }
131
-
132
- return url;
133
- }
134
-
135
- /**
136
- * Generate hierarchy of routes to try (stops at minimal level)
137
- * @param segments - Array of path segments
138
- * @param routeType - Type of route (path, hash, hash-slash, non-prefixed)
139
- * @returns Array of route names to try in order
140
- */
141
- function generateRouteHierarchy(segments: string[], routeType: 'path' | 'hash' | 'hash-slash' | 'non-prefixed'): string[] {
142
- const hierarchy: string[] = [];
143
-
144
- // Build hierarchy from most specific to least specific
145
- for (let i = segments.length; i > 0; i--) {
146
- const currentSegments = segments.slice(0, i);
147
- let routeName = '';
148
-
149
- switch (routeType) {
150
- case 'path':
151
- routeName = '/' + currentSegments.join('/');
152
- break;
153
- case 'hash':
154
- routeName = '#' + currentSegments.join('/');
155
- break;
156
- case 'hash-slash':
157
- routeName = '#/' + currentSegments.join('/');
158
- break;
159
- case 'non-prefixed':
160
- routeName = currentSegments.join('/');
161
- break;
162
- }
163
-
164
- hierarchy.push(routeName);
165
- }
166
-
167
- return hierarchy;
168
- }
169
-
170
- /**
171
- * Find handler in hierarchy and return handler info
172
- * @param hierarchy - Array of route names to try
173
- * @param originalSegments - Original path segments
174
- * @returns Handler info if found, null otherwise
175
- */
176
- function findHandlerInHierarchy(hierarchy: string[], originalSegments: string[]): { eventName: string; parameters: string[] } | null {
177
- for (let i = 0; i < hierarchy.length; i++) {
178
- const routeName = hierarchy[i];
179
- const subscribers = app.find(routeName);
180
-
181
- if (subscribers && subscribers.length > 0) {
182
- // Found handler - calculate remaining parameters
183
- const handlerDepth = hierarchy.length - i;
184
- const parameters = originalSegments.slice(handlerDepth);
185
-
186
- return {
187
- eventName: routeName,
188
- parameters: parameters
189
- };
190
- }
191
- }
192
-
193
- return null;
194
- }
195
-
196
- /**
197
- * Handle empty path with priority order: # → / → #/ → 404
198
- */
199
- function handleEmptyPath(): void {
200
- // Try # first
201
- const hashSubscribers = app.find('#');
202
- if (hashSubscribers && hashSubscribers.length > 0) {
203
- app.run('#');
204
- app.run(ROUTER_EVENT, '#');
205
- return;
206
- }
207
-
208
- // Try / second
209
- const pathSubscribers = app.find('/');
210
- if (pathSubscribers && pathSubscribers.length > 0) {
211
- app.run('/');
212
- app.run(ROUTER_EVENT, '/');
213
- return;
214
- }
215
-
216
- // Try #/ third
217
- const hashSlashSubscribers = app.find('#/');
218
- if (hashSlashSubscribers && hashSlashSubscribers.length > 0) {
219
- app.run('#/');
220
- app.run(ROUTER_EVENT, '#/');
221
- return;
222
- }
223
-
224
- // Fire 404 if no handlers found
225
- console.warn('No subscribers for event: ');
226
- app.run(ROUTER_404_EVENT, '');
227
- app.run(ROUTER_EVENT, '');
228
- }
229
-
230
- /**
231
- * Main hierarchical routing logic
232
- * @param url - The URL to route
233
- */
234
- function routeWithHierarchy(url: string): void {
235
- // Handle empty path
236
- if (!url) {
237
- handleEmptyPath();
238
- return;
239
- }
240
-
241
- // Normalize trailing slash
242
- url = normalizeTrailingSlash(url);
243
-
244
- // Strip base path if configured
245
- const basePath = app['basePath'];
246
- if (basePath) {
247
- url = stripBasePath(url, basePath);
248
- }
249
-
250
- // Parse segments and validate depth
251
- const segments = parsePathSegments(url);
252
- validateHierarchyDepth(segments);
253
-
254
- // Determine route type
255
- let routeType: 'path' | 'hash' | 'hash-slash' | 'non-prefixed';
256
- if (url.startsWith('#/')) {
257
- routeType = 'hash-slash';
258
- } else if (url.startsWith('#')) {
259
- routeType = 'hash';
260
- } else if (url.startsWith('/')) {
261
- routeType = 'path';
262
- } else {
263
- routeType = 'non-prefixed';
264
- }
265
-
266
- // Generate hierarchy
267
- const hierarchy = generateRouteHierarchy(segments, routeType);
268
-
269
- // Find handler in hierarchy
270
- const handlerInfo = findHandlerInHierarchy(hierarchy, segments);
271
-
272
- if (handlerInfo) {
273
- // Found handler - publish route with parameters
274
- publishRoute(handlerInfo.eventName, ...handlerInfo.parameters);
275
- } else {
276
- // No handler found - fire 404 with original URL
277
- if (hierarchy.length > 0) {
278
- const minimalRoute = hierarchy[hierarchy.length - 1];
279
- console.warn(`No subscribers for event: ${minimalRoute}`);
280
- app.run(ROUTER_404_EVENT, url);
281
- app.run(ROUTER_EVENT, url);
282
- } else {
283
- handleEmptyPath();
284
- }
285
- }
286
- }
287
-
288
- const publishRoute = (name: string, ...args: any[]) => {
289
- if (!name || name === ROUTER_EVENT || name === ROUTER_404_EVENT) return;
290
- const subscribers = app.find(name);
291
- if (!subscribers || subscribers.length === 0) {
292
- console.warn(`No subscribers for event: ${name}`);
293
- app.run(ROUTER_404_EVENT, name, ...args);
294
- } else {
295
- app.run(name, ...args);
296
- }
297
- app.run(ROUTER_EVENT, name, ...args);
298
- }
299
-
300
- import { Router } from './types';
301
-
302
- export const ROUTER_EVENT: string = '//';
303
- export const ROUTER_404_EVENT: string = '///';
304
- export const route: Router = (url: string) => {
305
- if (app['lastUrl'] === url) return; // Prevent duplicate routing
306
- app['lastUrl'] = url;
307
-
308
- // Use hierarchical routing logic
309
- routeWithHierarchy(url);
310
- }
311
- export default route;
package/src/shadow.tsx DELETED
@@ -1,8 +0,0 @@
1
- import app from './apprun';
2
-
3
- export default (_, children) => {
4
- const el = document.createElement('section');
5
- el.attachShadow({ mode: 'open' });
6
- app.render(el.shadowRoot, children);
7
- return <>{el}</>;
8
- };
package/src/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "es2020",
4
- "module": "esnext",
5
- "moduleResolution": "node",
6
- "jsx": "react",
7
- "jsxFactory": "app.h",
8
- "jsxFragmentFactory": "app.Fragment",
9
- "lib": ["esnext","dom"],
10
- "experimentalDecorators": true,
11
- "esModuleInterop": true,
12
- "outDir": "../esm",
13
- "sourceMap": true,
14
- "skipLibCheck": true
15
- }
16
- }
package/src/type-utils.ts DELETED
@@ -1,130 +0,0 @@
1
- /**
2
- * Type Safety Utilities for AppRun
3
- *
4
- * This file provides utility functions and types to improve type safety
5
- * across the AppRun framework, including:
6
- * 1. Safe type assertions with null checks
7
- * 2. Global object assignment helpers
8
- * 3. Event target type guards
9
- * 4. Function validation utilities
10
- */
11
-
12
- /**
13
- * Safely cast event target to specific HTML element type with null check
14
- */
15
- export function safeEventTarget<T extends HTMLElement = HTMLElement>(event: Event): T | null {
16
- return event?.target instanceof HTMLElement ? event.target as T : null;
17
- }
18
-
19
- /**
20
- * Type guard to check if an object is a valid function
21
- */
22
- export function isFunction(obj: any): obj is Function {
23
- return typeof obj === 'function';
24
- }
25
-
26
- /**
27
- * Type guard to check if an object is a valid HTML element
28
- */
29
- export function isHTMLElement(obj: any): obj is HTMLElement {
30
- return obj instanceof HTMLElement;
31
- }
32
-
33
- /**
34
- * Safely assign properties to global object with type checking
35
- */
36
- export function safeGlobalAssign<T extends Record<string, any>>(
37
- globalObj: any,
38
- assignments: T
39
- ): void {
40
- if (typeof globalObj === 'object' && globalObj !== null) {
41
- Object.keys(assignments).forEach(key => {
42
- globalObj[key] = assignments[key];
43
- });
44
- }
45
- }
46
-
47
- /**
48
- * Safely get property from global object with fallback
49
- */
50
- export function safeGlobalGet<T>(
51
- globalObj: any,
52
- property: string,
53
- fallback?: T
54
- ): T | undefined {
55
- if (typeof globalObj === 'object' && globalObj !== null) {
56
- return globalObj[property] ?? fallback;
57
- }
58
- return fallback;
59
- }
60
-
61
- /**
62
- * Type-safe wrapper for DOM element queries
63
- */
64
- export function safeQuerySelector<T extends Element = Element>(
65
- selector: string,
66
- context: Document | Element = document
67
- ): T | null {
68
- try {
69
- return context.querySelector<T>(selector);
70
- } catch (error) {
71
- console.warn(`Invalid selector: ${selector}`, error);
72
- return null;
73
- }
74
- }
75
-
76
- /**
77
- * Type-safe wrapper for DOM element by ID
78
- */
79
- export function safeGetElementById<T extends HTMLElement = HTMLElement>(
80
- id: string
81
- ): T | null {
82
- try {
83
- return document.getElementById(id) as T | null;
84
- } catch (error) {
85
- console.warn(`Error getting element by id: ${id}`, error);
86
- return null;
87
- }
88
- }
89
-
90
- /**
91
- * Validate and safely execute a function with error handling
92
- */
93
- export function safeExecute<T extends any[], R>(
94
- fn: ((...args: T) => R) | undefined | null,
95
- args: T,
96
- context?: any,
97
- errorMessage?: string
98
- ): R | undefined {
99
- if (!isFunction(fn)) {
100
- if (errorMessage) {
101
- console.warn(errorMessage, fn);
102
- }
103
- return undefined;
104
- }
105
-
106
- try {
107
- return context ? fn.apply(context, args) : fn(...args);
108
- } catch (error) {
109
- console.error(errorMessage || 'Error executing function:', error);
110
- return undefined;
111
- }
112
- }
113
-
114
- /**
115
- * Type definitions for improved global object safety
116
- */
117
- export interface SafeGlobalWindow {
118
- Component?: any;
119
- _React?: any;
120
- React?: any;
121
- on?: any;
122
- customElement?: any;
123
- safeHTML?: any;
124
- html?: any;
125
- svg?: any;
126
- run?: any;
127
- [key: string]: any;
128
- }
129
-
130
- export type SafeGlobalContext = SafeGlobalWindow | typeof globalThis | any;
package/src/types.ts DELETED
@@ -1,151 +0,0 @@
1
- /**
2
- * Core TypeScript Type Definitions
3
- *
4
- * This file defines the fundamental types used across AppRun:
5
- * 1. Component Types
6
- * - View: Function that renders state to VDOM
7
- * - Action: Function that updates state (sync/async/generator)
8
- * - Update: Collection of actions (array or object format)
9
- * - ActionDef: Tuple definition for action arrays
10
- *
11
- * 2. Virtual DOM Types
12
- * - VNode: Virtual DOM node structure with tag/props/children
13
- * - VDOM: Union of possible VDOM types (false, string, VNode, array)
14
- * - Element: DOM element references (HTMLElement or string selector)
15
- * - TemplateResult: Lit-html template support
16
- *
17
- * 3. Configuration Types
18
- * - EventOptions: Event handler options (once, delay, transition)
19
- * - ActionOptions: Action behavior options (render, history, global, callback)
20
- * - MountOptions: Component mounting options (global events, routing, transitions)
21
- * - AppStartOptions: Application startup configuration with lifecycle hooks
22
- *
23
- * Features:
24
- * - Strong typing for component lifecycle
25
- * - Flexible action definition formats
26
- * - Comprehensive event options
27
- * - Integration with external libraries (lit-html)
28
- * - Type-safe component mounting
29
- * - Lifecycle hook typing
30
- *
31
- * Type Safety Improvements (v3.35.1):
32
- * - Enhanced generic constraints for better type inference
33
- * - Improved union types for VDOM flexibility
34
- * - Better callback typing in options
35
- * - Stricter typing for lifecycle methods
36
- * - Added support for async generator and generator functions in Action types
37
- *
38
- * Usage:
39
- * ```ts
40
- * class MyComponent extends Component<State, Events> {
41
- * view: View<State>;
42
- * update: Update<State, Events>;
43
- * }
44
- *
45
- * // Type-safe action definitions with async generators
46
- * const update: Update<State> = {
47
- * 'event': (state: State, ...args) => newState,
48
- * 'stream-event': async function* (state: State, ...args) {
49
- * yield { ...state, loading: true };
50
- * const data = await fetchData();
51
- * yield { ...state, data, loading: false };
52
- * }
53
- * };
54
- * ```
55
- */
56
-
57
- import { TemplateResult } from 'lit-html';
58
- export type Element = HTMLElement | string;
59
- export type State<T> = T | Promise<T> | (() => T) | (() => Promise<T>);
60
- export type VNode = {
61
- tag: string | Function,
62
- props: {},
63
- children: Array<VNode | string>
64
- }
65
- export type VDOM = false | string | VNode | Array<VNode | string> | TemplateResult;
66
- export type View<T> = (state: T) => VDOM | void;
67
- export type Action<T> = (state: T, ...p: any[]) => T | Promise<T> | void | AsyncGenerator<T> | Generator<T>;
68
- export type ActionDef<T, E> = (readonly [E, Action<T>, {}?]);
69
- export type Update<T, E = unknown> = ActionDef<T, E>[] | { [name: string]: Action<T> | {}[] } | (E | Action<T> | {})[];
70
- export type ActionOptions = {
71
- render?: boolean, history?, global?: boolean;
72
- callback?: (state: any) => void;
73
- };
74
- export type EventOptions = {
75
- once?: boolean;
76
- transition?: boolean;
77
- delay?: number;
78
- } | any;
79
- export type MountOptions = {
80
- render?: boolean, history?, global_event?: boolean, route?: string;
81
- transition?: boolean;
82
- };
83
-
84
- export type AppStartOptions<T> = {
85
- render?: boolean;
86
- history?;
87
- transition?: boolean;
88
- route?: string;
89
- rendered?: (state: T) => void
90
- mounted?: (props: any, children: any, state: T) => T
91
- };
92
- export type Router = (url: string, ...args: any[]) => any;
93
-
94
- export type CustomElementOptions = {
95
- render?: boolean;
96
- shadow?: boolean;
97
- history?: boolean;
98
- global_event?: boolean;
99
- observedAttributes?: string[];
100
- };
101
-
102
- export interface IApp {
103
- // Event system methods
104
- on(name: string, fn: (...args: any[]) => any, options?: EventOptions): void;
105
- off(name: string, fn: (...args: any[]) => any): void;
106
- run(name: string, ...args: any[]): number;
107
- runAsync(name: string, ...args: any[]): Promise<any[]>;
108
- once(name: string, fn: (...args: any[]) => any, options?: EventOptions): void;
109
- find(name: string): any;
110
-
111
- /** @deprecated Use runAsync() instead */
112
- query(name: string, ...args: any[]): Promise<any[]>;
113
-
114
- start<T, E = unknown>(element?: Element | string, model?: T, view?: View<T>, update?: Update<T, E>,
115
- options?: AppStartOptions<T>): any;
116
-
117
- h(tag: string | Function, props?: any, ...children: any[]): VNode | VNode[];
118
- createElement(tag: string | Function, props?: any, ...children: any[]): VNode | VNode[];
119
- render(element: Element | ShadowRoot, node: VNode, component?: {}): void;
120
- Fragment(props: any, ...children: any[]): any[];
121
- route: Router;
122
- webComponent(name: string, componentClass: any, options?: CustomElementOptions): void;
123
- safeHTML(html: string): any[];
124
- use_render(render: any, mode?: 0 | 1): void;
125
- use_react(React: any, ReactDOM: any): void;
126
- version: string;
127
- basePath?: string;
128
- addComponents: (element: Element | string, components: ComponentRoute) => void;
129
- }
130
-
131
- // Define what constitutes a mountable component
132
- interface ComponentLike {
133
- mount(element?: Element | string, options?: any): any;
134
- }
135
-
136
- // Define component constructor type
137
- type ComponentConstructor<T = unknown> = new (
138
- state?: T,
139
- view?: any,
140
- update?: any,
141
- options?: any
142
- ) => ComponentLike;
143
-
144
- // Enhanced ComponentRoute type with clear distinctions
145
- export type ComponentRoute = {
146
- [route: string]:
147
- | ComponentLike // Component instance
148
- | ComponentConstructor // Component class constructor
149
- | (() => ComponentLike | ComponentConstructor | Promise<ComponentLike | ComponentConstructor>) // Factory function
150
- | ((...args: any[]) => any) // Event handler function
151
- };
package/src/vdom-html.ts_ DELETED
@@ -1,20 +0,0 @@
1
- import { createElement, updateElement, Fragment } from './vdom-my';
2
- import morphdom from 'morphdom';
3
-
4
- export function render(element, html, parent?) {
5
- if (!element) return;
6
- if (typeof html === 'string') {
7
- html = html.trim();
8
- if (element.firstChild) {
9
- const el = element.cloneNode(false);
10
- el.innerHTML = html;
11
- morphdom(element, el);
12
- } else {
13
- element.innerHTML = html;
14
- }
15
- } else {
16
- updateElement(element, html, parent);
17
- }
18
- }
19
- export { createElement, Fragment };
20
-
@@ -1,67 +0,0 @@
1
- import { createElement, updateElement, Fragment } from './vdom-my';
2
-
3
-
4
- import { render, svg, html, noChange, nothing } from 'lit';
5
- import { directive, Directive, PartInfo, ElementPart, DirectiveResult, EventPart, PartType } from 'lit/directive.js';
6
- import { unsafeHTML } from 'lit/directives/unsafe-html.js';
7
- import app from './apprun';
8
-
9
- function _render(element, vdom, parent?) {
10
- if (!vdom) return;
11
- if (typeof vdom === 'string') {
12
- if (!element['_$litPart$']) element.replaceChildren();
13
- render(html`${unsafeHTML(vdom)}`, element);
14
- } else if (vdom['_$litType$']) {
15
- if (!element['_$litPart$']) element.replaceChildren();
16
- render(vdom, element);
17
- } else {
18
- updateElement(element, vdom, parent);
19
- element['_$litPart$'] = undefined;
20
- }
21
- }
22
-
23
- export class RunDirective extends Directive {
24
- // State stored in class field
25
- value: number | undefined;
26
- constructor(partInfo: PartInfo) {
27
- super(partInfo);
28
- // When necessary, validate part in constructor using `part.type`
29
- if (partInfo.type !== PartType.EVENT) { // In lit v3, use PartType.EVENT
30
- throw new Error('run() can only be used in event handlers');
31
- }
32
- }
33
- // Override update to perform any direct DOM manipulation
34
- update(part: EventPart, props: Array<any>): DirectiveResult {
35
- /* Any imperative updates to DOM/parts would go here */
36
- const element = part.element;
37
- const name = part.name;
38
- const [eventOrFn, ...args] = props;
39
-
40
- const getComponent = () => {
41
- let el = element;
42
- let component = el['_component'];
43
- while (!component && el) {
44
- el = el.parentElement;
45
- component = el && el['_component'];
46
- }
47
- console.assert(!!component, 'Component not found.');
48
- return component;
49
- }
50
-
51
- if (typeof eventOrFn === 'string') {
52
- element[`on${name}`] = e => {
53
- const component = getComponent();
54
- component ? component.run(eventOrFn, ...args, e) : app.run(eventOrFn, ...args, e)
55
- }
56
- } else if (typeof eventOrFn === 'function') {
57
- element[`on${name}`] = e => getComponent().setState(eventOrFn(getComponent().state, ...args, e));
58
- }
59
- return this.render();
60
- }
61
- render() {
62
- return noChange;
63
- }
64
- }
65
-
66
- const run = directive(RunDirective) as any;
67
- export { createElement, Fragment, html, svg, _render as render, run };