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/decorator.ts DELETED
@@ -1,98 +0,0 @@
1
- import { CustomElementOptions } from './types';
2
- import webComponent from './web-component';
3
-
4
- /**
5
- * TypeScript Decorators for AppRun Components
6
- *
7
- * This file provides decorators that enable:
8
- * 1. Event Handler Registration
9
- * - @on(): Subscribe to events with options (global, once, delay)
10
- * - @update(): Define state updates with metadata and options
11
- * - Supports method and class decoration patterns
12
- *
13
- * 2. Web Component Integration
14
- * - @customElement(): Register as custom element with options
15
- * - Handles shadow DOM and attribute observation
16
- * - Automatic lifecycle management for web components
17
- *
18
- * 3. Metadata Management
19
- * - Custom Reflect implementation for decorator metadata
20
- * - Stores event handler and update metadata for runtime use
21
- * - Supports runtime reflection for dynamic behavior
22
- * - Metadata keys for event bindings and updates
23
- *
24
- * Features:
25
- * - Event handler decoration with options
26
- * - State update method decoration
27
- * - Web component registration
28
- * - Metadata-driven event binding
29
- * - Flexible decorator patterns
30
- * - Runtime metadata access
31
- *
32
- * Type Safety Improvements (v3.35.1):
33
- * - Enhanced decorator typing for better IDE support
34
- * - Improved metadata key management
35
- * - Better type inference for decorated methods
36
- *
37
- * Usage:
38
- * ```ts
39
- * @customElement('my-element')
40
- * class MyComponent extends Component {
41
- * @on('event', { global: true })
42
- * handler(state, ...args) {
43
- * // Handle event
44
- * }
45
- *
46
- * @update('event', { render: true })
47
- * updater(state, ...args) {
48
- * // Update state
49
- * return newState;
50
- * }
51
- * }
52
- * ```
53
- */
54
-
55
- // tslint:disable:no-invalid-this
56
- export const Reflect = {
57
-
58
- meta: new WeakMap(),
59
-
60
- defineMetadata(metadataKey, metadataValue, target) {
61
- if (!this.meta.has(target)) this.meta.set(target, {});
62
- this.meta.get(target)[metadataKey] = metadataValue;
63
- },
64
-
65
- getMetadataKeys(target) {
66
- target = Object.getPrototypeOf(target);
67
- return this.meta.get(target) ? Object.keys(this.meta.get(target)) : [];
68
- },
69
-
70
- getMetadata(metadataKey, target) {
71
- target = Object.getPrototypeOf(target);
72
- return this.meta.get(target) ? this.meta.get(target)[metadataKey] : null;
73
- }
74
- }
75
-
76
- export function update<E = string>(events?: E, options: any = {}) {
77
- return (target: any, key: string, descriptor: any) => {
78
- const name = events ? events.toString() : key;
79
- Reflect.defineMetadata(`apprun-update:${name}`,
80
- { name, key, options }, target);
81
- return descriptor;
82
- }
83
- }
84
-
85
- export function on<E = string>(events?: E, options: any = {}) {
86
- return function (target: any, key: string) {
87
- const name = events ? events.toString() : key;
88
- Reflect.defineMetadata(`apprun-update:${name}`,
89
- { name, key, options }, target)
90
- }
91
- }
92
-
93
- export function customElement(name: string, options?: CustomElementOptions) {
94
- return function _customElement<T extends { new(...args: any[]): {} }>(constructor: T) {
95
- webComponent(name, constructor, options);
96
- return constructor;
97
- }
98
- }
package/src/directive.ts DELETED
@@ -1,303 +0,0 @@
1
- /**
2
- * Component Directives Implementation
3
- *
4
- * This file provides built-in directives for components:
5
- * 1. Event Binding ($on directives)
6
- * - $on: Bind DOM events to component events
7
- * - Supports event delegation and parameters
8
- * - Handles function, string, and array event handlers
9
- * - Type-safe event target handling
10
- *
11
- * 2. Two-way Data Binding ($bind directive)
12
- * - $bind: Sync form elements with component state
13
- * - Handles input types: text, checkbox, radio, number, range
14
- * - Supports select (single/multiple) and textarea elements
15
- * - Automatic value type conversion for numbers
16
- * - Support for complex property paths
17
- *
18
- * 3. Custom Directives
19
- * - Extensible directive system via '$' events
20
- * - Processes virtual DOM during rendering
21
- * - Supports custom attribute directives
22
- *
23
- * Features:
24
- * - Automatic state synchronization
25
- * - Type conversion for form inputs
26
- * - Event delegation support
27
- * - Multiple event handler formats
28
- * - Nested property binding
29
- * - Custom directive extensibility
30
- *
31
- * Type Safety Improvements (v3.35.1):
32
- * - Added null checks for event targets before type assertions
33
- * - Proper typing for different HTML element types
34
- * - Enhanced error handling for invalid event targets
35
- * - Safer DOM element property access
36
- *
37
- * Nested State Binding Support (v3.37.4):
38
- * - Enhanced $bind directive to support nested object and array paths
39
- * - Supports dot notation: 'user.name', 'user.profile.settings.theme'
40
- * - Supports bracket notation: 'items[0]', 'users[1].name'
41
- * - Supports mixed notation: 'users[0].settings.theme', 'data["key"].value'
42
- * - Safe traversal with automatic intermediate object/array creation
43
- * - Maintains backward compatibility with simple property binding
44
- *
45
- * Usage:
46
- * ```tsx
47
- * // Event binding
48
- * <button $onclick="event-name">Click</button>
49
- * <input $oninput={e => setState(e.target.value)} />
50
- *
51
- * // Simple two-way binding
52
- * <input $bind="state.property" />
53
- * <select $bind="selected">...</select>
54
- *
55
- * // Nested object binding
56
- * <input $bind="user.profile.name" />
57
- * <input $bind="user.settings.theme" />
58
- *
59
- * // Array element binding
60
- * <input $bind="items[0]" />
61
- * <input $bind="todos[1].title" />
62
- *
63
- * // Mixed nested binding
64
- * <input $bind="users[0].profile.settings.notifications.email" />
65
- * <select $bind="config.display.mode">...</select>
66
- *
67
- * // Array handlers
68
- * <button $onclick={['handler', param1, param2]}>Click</button>
69
- * ```
70
- */
71
-
72
- import app from './app';
73
- import { safeEventTarget } from './type-utils';
74
-
75
- /**
76
- * Parse a path string into an array of keys and indices
77
- * Supports paths like: 'a.b', 'a[0]', 'a[0].b', 'a["key"]'
78
- */
79
- const parsePath = (path: string): Array<string | number> => {
80
- if (!path) return [];
81
-
82
- const keys: Array<string | number> = [];
83
- let current = '';
84
- let inBracket = false;
85
- let quoteChar = '';
86
-
87
- for (let i = 0; i < path.length; i++) {
88
- const char = path[i];
89
-
90
- if (char === '[' && !inBracket) {
91
- if (current) {
92
- keys.push(current);
93
- current = '';
94
- }
95
- inBracket = true;
96
- } else if (char === ']' && inBracket) {
97
- if (quoteChar) {
98
- // Remove quotes from string keys
99
- current = current.slice(1, -1);
100
- } else if (/^\d+$/.test(current)) {
101
- // Convert numeric strings to numbers
102
- current = parseInt(current, 10) as any;
103
- }
104
- keys.push(current);
105
- current = '';
106
- inBracket = false;
107
- quoteChar = '';
108
- } else if ((char === '"' || char === "'") && inBracket) {
109
- if (!quoteChar) {
110
- quoteChar = char;
111
- } else if (char === quoteChar) {
112
- quoteChar = '';
113
- }
114
- current += char;
115
- } else if (char === '.' && !inBracket) {
116
- if (current) {
117
- keys.push(current);
118
- current = '';
119
- }
120
- } else {
121
- current += char;
122
- }
123
- }
124
-
125
- if (current) {
126
- keys.push(current);
127
- }
128
-
129
- return keys;
130
- };
131
-
132
- /**
133
- * Safely get a nested value from an object using a path
134
- */
135
- const getNestedValue = (obj: any, path: Array<string | number>): any => {
136
- let current = obj;
137
- for (const key of path) {
138
- if (current == null) return undefined;
139
- current = current[key];
140
- }
141
- return current;
142
- };
143
-
144
- /**
145
- * Safely set a nested value in an object using a path
146
- * Creates intermediate objects/arrays as needed
147
- */
148
- const setNestedValue = (obj: any, path: Array<string | number>, value: any): any => {
149
- if (path.length === 0) return value;
150
-
151
- const result = { ...obj };
152
- let current = result;
153
-
154
- for (let i = 0; i < path.length - 1; i++) {
155
- const key = path[i];
156
- const nextKey = path[i + 1];
157
-
158
- if (current[key] == null) {
159
- // Create array if next key is numeric, object otherwise
160
- current[key] = typeof nextKey === 'number' ? [] : {};
161
- } else if (Array.isArray(current[key])) {
162
- current[key] = [...current[key]];
163
- } else if (typeof current[key] === 'object') {
164
- current[key] = { ...current[key] };
165
- }
166
-
167
- current = current[key];
168
- }
169
-
170
- current[path[path.length - 1]] = value;
171
- return result;
172
- };
173
-
174
- const getStateValue = (component, name) => {
175
- if (!name) return component['state'] || '';
176
-
177
- const path = parsePath(name);
178
- const value = getNestedValue(component['state'], path);
179
- return value !== undefined ? value : '';
180
- }
181
-
182
- const setStateValue = (component, name, value) => {
183
- if (!name) {
184
- component.setState(value);
185
- return;
186
- }
187
-
188
- const path = parsePath(name);
189
- const currentState = component['state'] || {};
190
- const newState = setNestedValue(currentState, path, value);
191
- component.setState(newState);
192
- }
193
-
194
- const apply_directive = (key: string, props: {}, tag, component) => {
195
- if (key.startsWith('$on')) {
196
- const event = props[key];
197
- key = key.substring(1)
198
- if (typeof event === 'boolean') {
199
- props[key] = e => component.run ? component.run(key, e) : app.run(key, e);
200
- } else if (typeof event === 'string') {
201
- props[key] = e => component.run ? component.run(event, e) : app.run(event, e);
202
- } else if (typeof event === 'function') {
203
- props[key] = e => component.setState(event(component.state, e));
204
- } else if (Array.isArray(event)) {
205
- const [handler, ...p] = event;
206
- if (typeof handler === 'string') {
207
- props[key] = e => component.run ? component.run(handler, ...p, e) : app.run(handler, ...p, e);
208
- } else if (typeof handler === 'function') {
209
- props[key] = e => component.setState(handler(component.state, ...p, e));
210
- }
211
- }
212
-
213
- } else if (key === '$bind') {
214
- const type = props['type'] || 'text';
215
- const name = typeof props[key] === 'string' ? props[key] : props['name'];
216
- if (tag === 'input') {
217
- switch (type) {
218
- case 'checkbox':
219
- props['checked'] = getStateValue(component, name);
220
- props['onclick'] = e => {
221
- const target = safeEventTarget<HTMLInputElement>(e);
222
- if (target) {
223
- setStateValue(component, name || target.name, target.checked);
224
- }
225
- };
226
- break;
227
- case 'radio':
228
- props['checked'] = getStateValue(component, name) === props['value'];
229
- props['onclick'] = e => {
230
- const target = safeEventTarget<HTMLInputElement>(e);
231
- if (target) {
232
- setStateValue(component, name || target.name, target.value);
233
- }
234
- };
235
- break;
236
- case 'number':
237
- case 'range':
238
- props['value'] = getStateValue(component, name);
239
- props['oninput'] = e => {
240
- const target = safeEventTarget<HTMLInputElement>(e);
241
- if (target) {
242
- setStateValue(component, name || target.name, Number(target.value));
243
- }
244
- };
245
- break;
246
- default:
247
- props['value'] = getStateValue(component, name);
248
- props['oninput'] = e => {
249
- const target = safeEventTarget<HTMLInputElement>(e);
250
- if (target) {
251
- setStateValue(component, name || target.name, target.value);
252
- }
253
- };
254
- }
255
- } else if (tag === 'select') {
256
- props['value'] = getStateValue(component, name);
257
- props['onchange'] = e => {
258
- const target = safeEventTarget<HTMLSelectElement>(e);
259
- if (target && !target.multiple) { // multiple selection use $bind on option
260
- setStateValue(component, name || target.name, target.value);
261
- }
262
- }
263
- } else if (tag === 'option') {
264
- props['selected'] = getStateValue(component, name);
265
- props['onclick'] = e => {
266
- const target = safeEventTarget<HTMLOptionElement>(e);
267
- if (target) {
268
- setStateValue(component, name || (target as any).name, target.selected);
269
- }
270
- };
271
- } else if (tag === 'textarea') {
272
- props['innerHTML'] = getStateValue(component, name);
273
- props['oninput'] = e => {
274
- const target = safeEventTarget<HTMLTextAreaElement>(e);
275
- if (target) {
276
- setStateValue(component, name || target.name, target.value);
277
- }
278
- };
279
- }
280
- } else {
281
- app.run('$', { key, tag, props, component });
282
- }
283
- }
284
-
285
- const directive = (vdom, component) => {
286
- if (Array.isArray(vdom)) {
287
- return vdom.map(element => directive(element, component));
288
- } else {
289
- let { type, tag, props, children } = vdom;
290
- tag = tag || type;
291
- children = children || props?.children;
292
- if (props) Object.keys(props).forEach(key => {
293
- if (key.startsWith('$')) {
294
- apply_directive(key, props, tag, component);
295
- delete props[key];
296
- }
297
- });
298
- if (children) directive(children, component);
299
- return vdom;
300
- }
301
- }
302
-
303
- export default directive;
package/src/global.d.ts DELETED
@@ -1,22 +0,0 @@
1
- import { App } from './app';
2
- import { Component } from './component';
3
-
4
- declare global {
5
- var app: App;
6
- var _AppRunVersions: string;
7
- interface Window {
8
- app: App;
9
- _AppRunVersions: string;
10
- Component: typeof Component & {
11
- <T = unknown>(options?: any): (constructor: Function) => void;
12
- };
13
- _React: any;
14
- React: App;
15
- on: {
16
- <T = unknown>(options?: any): (constructor: Function) => void;
17
- <E = string>(events?: E, options?: any): (target: any, key: string) => void;
18
- };
19
- customElement: (name: string) => (constructor: Function) => void;
20
- safeHTML: (html: string) => any[];
21
- }
22
- }