vasille-web 7.0.0-rc.3 → 7.0.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 (210) hide show
  1. package/README.md +32 -16
  2. package/build/dev/communication.d.ts +9 -0
  3. package/build/dev/css-injector.d.ts +14 -0
  4. package/build/dev/css-injector.js +37 -0
  5. package/build/dev/css.d.ts +3 -0
  6. package/build/dev/css.js +32 -0
  7. package/build/dev/index.d.ts +55 -0
  8. package/build/dev/index.js +64 -0
  9. package/build/dev/inspector.d.ts +18 -0
  10. package/build/dev/inspector.js +226 -0
  11. package/build/dev/mount.d.ts +11 -0
  12. package/build/dev/mount.js +91 -0
  13. package/build/dev/router.d.ts +23 -0
  14. package/build/dev/router.js +67 -0
  15. package/build/dev/runner.d.ts +34 -0
  16. package/build/dev/runner.js +128 -0
  17. package/build/shadow/css.d.ts +23 -0
  18. package/build/shadow/css.js +77 -0
  19. package/build/shadow/index.d.ts +3 -0
  20. package/build/shadow/index.js +3 -0
  21. package/build/shadow/lib.d.ts +11 -0
  22. package/build/shadow/lib.js +145 -0
  23. package/build/shadow/types.d.ts +31 -0
  24. package/build/ssg/awaited.d.ts +3 -0
  25. package/build/ssg/awaited.js +24 -0
  26. package/build/ssg/css.d.ts +8 -0
  27. package/build/ssg/css.js +36 -0
  28. package/build/ssg/index.d.ts +21 -0
  29. package/build/ssg/index.js +37 -0
  30. package/build/ssg/router.d.ts +17 -0
  31. package/build/ssg/router.js +59 -0
  32. package/build/ssg/runner.d.ts +56 -0
  33. package/build/ssg/runner.js +337 -0
  34. package/build/types/index.d.ts +9 -0
  35. package/build/types/index.js +1 -0
  36. package/build/web/css/index.d.ts +21 -0
  37. package/build/web/css/index.js +53 -0
  38. package/build/web/css/lib.d.ts +10 -0
  39. package/build/web/css/lib.js +75 -0
  40. package/build/web/index.d.ts +6 -0
  41. package/build/web/index.js +6 -0
  42. package/{types → build/web/jsx}/jsx-runtime.d.ts +6 -6
  43. package/build/web/jsx/spec/css.d.ts +7 -0
  44. package/build/web/jsx/spec/css.js +1 -0
  45. package/{types → build/web/jsx}/spec/html.d.ts +1 -1
  46. package/build/web/jsx/spec/html.js +1 -0
  47. package/build/web/mount.d.ts +19 -0
  48. package/{lib/index.js → build/web/mount.js} +25 -20
  49. package/build/web/router/router.d.ts +45 -0
  50. package/build/web/router/router.js +131 -0
  51. package/build/web/runner/binding/attribute.d.ts +16 -0
  52. package/build/web/runner/binding/attribute.js +30 -0
  53. package/build/web/runner/binding/binding.d.ts +20 -0
  54. package/build/web/runner/binding/binding.js +28 -0
  55. package/build/web/runner/binding/class.d.ts +9 -0
  56. package/build/web/runner/binding/class.js +32 -0
  57. package/build/web/runner/binding/property.d.ts +16 -0
  58. package/build/web/runner/binding/property.js +20 -0
  59. package/build/web/runner/binding/style.d.ts +17 -0
  60. package/build/web/runner/binding/style.js +32 -0
  61. package/build/web/runner/runner.d.ts +45 -0
  62. package/build/web/runner/runner.js +176 -0
  63. package/coverage/clover.xml +754 -0
  64. package/coverage/coverage-final.json +20 -0
  65. package/coverage/lcov-report/base.css +224 -0
  66. package/coverage/lcov-report/block-navigation.js +87 -0
  67. package/coverage/lcov-report/dev/css-injector.ts.html +250 -0
  68. package/coverage/lcov-report/dev/css.ts.html +220 -0
  69. package/coverage/lcov-report/dev/index.html +131 -0
  70. package/coverage/lcov-report/favicon.png +0 -0
  71. package/coverage/lcov-report/index.html +221 -0
  72. package/coverage/lcov-report/prettify.css +1 -0
  73. package/coverage/lcov-report/prettify.js +2 -0
  74. package/coverage/lcov-report/shadow/css.ts.html +382 -0
  75. package/coverage/lcov-report/shadow/index.html +131 -0
  76. package/coverage/lcov-report/shadow/lib.ts.html +670 -0
  77. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  78. package/coverage/lcov-report/sorter.js +210 -0
  79. package/coverage/lcov-report/ssg/awaited.ts.html +169 -0
  80. package/coverage/lcov-report/ssg/css.ts.html +223 -0
  81. package/coverage/lcov-report/ssg/index.html +176 -0
  82. package/coverage/lcov-report/ssg/index.ts.html +370 -0
  83. package/coverage/lcov-report/ssg/router.ts.html +388 -0
  84. package/coverage/lcov-report/ssg/runner.ts.html +1405 -0
  85. package/coverage/lcov-report/web/css/index.html +131 -0
  86. package/coverage/lcov-report/web/css/index.ts.html +313 -0
  87. package/coverage/lcov-report/web/css/lib.ts.html +352 -0
  88. package/coverage/lcov-report/web/index.html +116 -0
  89. package/coverage/lcov-report/web/index.ts.html +574 -0
  90. package/coverage/lcov-report/web/mount.ts.html +454 -0
  91. package/coverage/lcov-report/web/router/index.html +116 -0
  92. package/coverage/lcov-report/web/router/router.ts.html +784 -0
  93. package/coverage/lcov-report/web/runner/binding/attribute.ts.html +190 -0
  94. package/coverage/lcov-report/web/runner/binding/binding.ts.html +193 -0
  95. package/coverage/lcov-report/web/runner/binding/class.ts.html +199 -0
  96. package/coverage/lcov-report/web/runner/binding/index.html +176 -0
  97. package/coverage/lcov-report/web/runner/binding/property.ts.html +154 -0
  98. package/coverage/lcov-report/web/runner/binding/style.ts.html +205 -0
  99. package/coverage/lcov-report/web/runner/index.html +116 -0
  100. package/coverage/lcov-report/web/runner/runner.ts.html +835 -0
  101. package/coverage/lcov.info +1554 -0
  102. package/jest.config.cjs +37 -0
  103. package/package.json +91 -60
  104. package/test/api/dev.test.ts +5 -0
  105. package/test/api/import-list.ts +106 -0
  106. package/test/api/shadow.test.ts +5 -0
  107. package/test/api/ssg.test.ts +5 -0
  108. package/test/api/web.test.ts +5 -0
  109. package/test/css/css-dev.test.ts +103 -0
  110. package/test/css/css.test.ts +27 -0
  111. package/test/mount/exported-web-router.test.ts +63 -0
  112. package/test/mount/modal-no-ctx.test.ts +14 -0
  113. package/test/mount/modal-which-throws.test.ts +33 -0
  114. package/test/mount/modal-with-slot.test.ts +39 -0
  115. package/test/mount/modal.test.ts +34 -0
  116. package/test/mount/prompt-error.test.ts +44 -0
  117. package/test/mount/prompt-timeout.test.ts +53 -0
  118. package/test/mount/prompt-which-trows.test.ts +33 -0
  119. package/test/mount/prompt.test.ts +44 -0
  120. package/test/page.ts +16 -0
  121. package/test/router/empty-router.test.ts +21 -0
  122. package/test/router/page.ts +19 -0
  123. package/test/router/router.test.ts +774 -0
  124. package/test/router/v7.test.ts +129 -0
  125. package/test/runner/destruction.test.ts +113 -0
  126. package/test/runner/runner.test.ts +403 -0
  127. package/test/shadow/components/Component.ts +72 -0
  128. package/test/shadow/css.test.ts +68 -0
  129. package/test/shadow/page.ts +21 -0
  130. package/test/shadow/shadow.test.ts +71 -0
  131. package/test/ssg/awaited/awaited.test.ts +11 -0
  132. package/test/ssg/awaited/element.test.ts +6 -0
  133. package/test/ssg/awaited/element.tsx +10 -0
  134. package/test/ssg/awaited/element.tsx.html +12 -0
  135. package/test/ssg/awaited/embed.test.ts +6 -0
  136. package/test/ssg/awaited/embed.tsx +14 -0
  137. package/test/ssg/awaited/embed.tsx.html +16 -0
  138. package/test/ssg/awaited/text.test.ts +6 -0
  139. package/test/ssg/awaited/text.tsx +8 -0
  140. package/test/ssg/awaited/text.tsx.html +7 -0
  141. package/test/ssg/awaited/throw-sync.tsx +10 -0
  142. package/test/ssg/awaited/throw-sync.tsx.html +7 -0
  143. package/test/ssg/awaited/throw.tsx +13 -0
  144. package/test/ssg/awaited/throw.tsx.html +7 -0
  145. package/test/ssg/compose/compose.test.ts +25 -0
  146. package/test/ssg/compose/modal.tsx +29 -0
  147. package/test/ssg/compose/modal.tsx.html +16 -0
  148. package/test/ssg/compose/view.tsx +35 -0
  149. package/test/ssg/compose/view.tsx.html +12 -0
  150. package/test/ssg/core/core.test.ts +31 -0
  151. package/test/ssg/core/div-embed.tsx +7 -0
  152. package/test/ssg/core/div-embed.tsx.html +9 -0
  153. package/test/ssg/core/div-with-class.tsx +5 -0
  154. package/test/ssg/core/div-with-class.tsx.html +9 -0
  155. package/test/ssg/core/div-with-text.tsx +5 -0
  156. package/test/ssg/core/div-with-text.tsx.html +9 -0
  157. package/test/ssg/core/div.tsx +5 -0
  158. package/test/ssg/core/div.tsx.html +7 -0
  159. package/test/ssg/core/text-join.tsx +9 -0
  160. package/test/ssg/core/text-join.tsx.html +10 -0
  161. package/test/ssg/core/text.tsx +5 -0
  162. package/test/ssg/core/text.tsx.html +7 -0
  163. package/test/ssg/css/css.test.ts +6 -0
  164. package/test/ssg/css/css.tsx +34 -0
  165. package/test/ssg/css/css.tsx.html +28 -0
  166. package/test/ssg/extra-tags/body.tsx +6 -0
  167. package/test/ssg/extra-tags/body.tsx.html +7 -0
  168. package/test/ssg/extra-tags/extra-tags.test.ts +11 -0
  169. package/test/ssg/extra-tags/head.tsx +9 -0
  170. package/test/ssg/extra-tags/head.tsx.html +12 -0
  171. package/test/ssg/markdown/blocks.tsx +12 -0
  172. package/test/ssg/markdown/blocks.tsx.md +12 -0
  173. package/test/ssg/markdown/css.tsx +11 -0
  174. package/test/ssg/markdown/css.tsx.md +1 -0
  175. package/test/ssg/markdown/external.tsx +7 -0
  176. package/test/ssg/markdown/external.tsx.md +3 -0
  177. package/test/ssg/markdown/heading.tsx +12 -0
  178. package/test/ssg/markdown/heading.tsx.md +13 -0
  179. package/test/ssg/markdown/hybrid.tsx +15 -0
  180. package/test/ssg/markdown/hybrid.tsx.md +11 -0
  181. package/test/ssg/markdown/lists.tsx +26 -0
  182. package/test/ssg/markdown/lists.tsx.md +16 -0
  183. package/test/ssg/markdown/markdown.test.ts +41 -0
  184. package/test/ssg/markdown/stylish.tsx +19 -0
  185. package/test/ssg/markdown/stylish.tsx.md +15 -0
  186. package/test/ssg/markdown/table.tsx +32 -0
  187. package/test/ssg/markdown/table.tsx.md +11 -0
  188. package/test/ssg/router/embed.html +7 -0
  189. package/test/ssg/router/embed.tsx +5 -0
  190. package/test/ssg/router/file-html.tsx +5 -0
  191. package/test/ssg/router/file.html +7 -0
  192. package/test/ssg/router/index.html +7 -0
  193. package/test/ssg/router/index.tsx +5 -0
  194. package/test/ssg/router/router.test.ts +26 -0
  195. package/test/ssg/run-test.ts +33 -0
  196. package/test/ssg/runner/attr.tsx +7 -0
  197. package/test/ssg/runner/attr.tsx.html +7 -0
  198. package/test/ssg/runner/class.tsx +8 -0
  199. package/test/ssg/runner/class.tsx.html +7 -0
  200. package/test/ssg/runner/runner.test.ts +16 -0
  201. package/test/ssg/runner/style.tsx +19 -0
  202. package/test/ssg/runner/style.tsx.html +7 -0
  203. package/test/tsconfig.json +20 -0
  204. package/lib/dev.js +0 -109
  205. package/types/dev.d.ts +0 -10
  206. package/types/index.d.ts +0 -21
  207. package/types/spec/css.d.ts +0 -7
  208. /package/{lib/spec/css.js → build/dev/communication.js} +0 -0
  209. /package/{lib/spec/html.js → build/shadow/types.js} +0 -0
  210. /package/{lib → build/web/jsx}/jsx-runtime.js +0 -0
package/README.md CHANGED
@@ -2,7 +2,9 @@
2
2
 
3
3
  ![Vasille.js logo](https://raw.githubusercontent.com/vasille-js/vasille-js/refs/heads/v5/doc/img/logo.png)
4
4
 
5
- `SteelFrameKit` is a front-end development kit, which is developed to provide fault tolerant web applications.
5
+ AI can produce code. Organizations still have to produce software.
6
+ Agentic development is changing how software gets made,
7
+ but it hasn't changed what it cost to be wrong, `Steel Frame` do it.
6
8
 
7
9
  [![npm](https://img.shields.io/npm/v/steel-frame?style=round-square)](https://www.npmjs.com/package/steel-frame)
8
10
  [![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/vasille-js/steel-frame)
@@ -13,12 +15,12 @@
13
15
  - [Steel Frame](#steel-frame)
14
16
  - [Table of content](#table-of-content)
15
17
  - [Installation](#installation)
16
- - [How to use SteelFramekit](#how-to-use-steelframekit)
18
+ - [How to use Steel Frame](#how-to-use-steel-frame)
17
19
  - [Full documentation:](#full-documentation)
18
20
  - [Examples](#examples)
19
- - [How SAFE is SteelFrameKit](#how-safe-is-steelframekit)
20
- - [How INTUITIVE is SteelFrameKit](#how-intuitive-is-steelframekit)
21
- - [How POWERFUL is SteelFrameKit](#how-powerful-is-steelframekit)
21
+ - [How SAFE is Steel Frame](#how-safe-is-steel-frame)
22
+ - [How INTUITIVE is Steel Frame](#how-intuitive-is-steel-frame)
23
+ - [How POWERFUL is Steel Frame](#how-powerful-is-steel-frame)
22
24
  - [Road map](#road-map)
23
25
  - [Change log](#change-log)
24
26
  - [7.0](#70)
@@ -38,7 +40,7 @@
38
40
  npm install steel-frame --save
39
41
  ```
40
42
 
41
- ## How to use SteelFramekit
43
+ ## How to use Steel Frame
42
44
 
43
45
  Create an app from a template
44
46
 
@@ -48,9 +50,10 @@ $ npm create steel-frame
48
50
 
49
51
  ### Full documentation:
50
52
 
51
- - [Learn `SteelFrameKit` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v5/doc/V4-API.md)
53
+ - [Learn `Steel Frame` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v5/doc/V7-API.md)
52
54
  - [Router Documentation](https://github.com/vasille-js/vasille-js/blob/v5/doc/Router-API.md)
53
- - [Compostion functions](https://github.com/vasille-js/vasille-js/blob/v5/doc/Compositions.md)
55
+ - [Compiler Hints](https://github.com/vasille-js/vasille-js/blob/v5/doc/CompilerHints.md)
56
+ - [Composition functions](https://github.com/vasille-js/vasille-js/blob/v5/doc/Compositions.md)
54
57
  - [Dependency injection](https://github.com/vasille-js/vasille-js/blob/v5/doc/Context.md)
55
58
 
56
59
  ### Examples
@@ -60,7 +63,7 @@ $ npm create steel-frame
60
63
 
61
64
  <hr>
62
65
 
63
- ## How SAFE is SteelFrameKit
66
+ ## How SAFE is Steel Frame
64
67
 
65
68
  The safe of your application is ensured by
66
69
 
@@ -68,7 +71,7 @@ The safe of your application is ensured by
68
71
  Each function, each branch is working as designed.
69
72
  - OOP, DRY, KISS and SOLID principles are applied.
70
73
  - `strong typing` makes your code safe.
71
- All entities of `SteelFrameKit` core library are strongly typed, including:
74
+ All entities of `Steel Frame` core library are strongly typed, including:
72
75
  - data fields & properties.
73
76
  - computed properties (function parameters and result).
74
77
  - methods.
@@ -78,7 +81,7 @@ The safe of your application is ensured by
78
81
  - references to children.
79
82
  - No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
80
83
 
81
- ## How INTUITIVE is SteelFrameKit
84
+ ## How INTUITIVE is Steel Frame
82
85
 
83
86
  There is the "Hello World":
84
87
 
@@ -92,7 +95,7 @@ const App = compose(() => {
92
95
  mount(document.body, App, {});
93
96
  ```
94
97
 
95
- ## How POWERFUL is SteelFrameKit
98
+ ## How POWERFUL is Steel Frame
96
99
 
97
100
  All of these are supported:
98
101
 
@@ -130,12 +133,25 @@ We respect semantic versioning:
130
133
  - A minor version is increased when we add functionality.
131
134
  - Patch version is increased when we fix bugs.
132
135
 
133
- ### 7.0 RC (WIP)
136
+ ### 7.0
134
137
 
135
- - Add `debounceRef`, `edgeRef` and `fieldRef` functions, which extend the reativity system.
138
+ - Add `debounced` and `field` functions, which extend the reativity system.
136
139
  - Add `Zombie` component, it keeps HTML elements alive some time after destruction.
137
140
  - Add `abortSignal` to cancel fetch requests and timers when component is destroyed.
138
- - Add `safeRef`, `safeExpr`, `safeInit` functions, they make the JSX much safer.
141
+ - Renamed `ref` to `state`, `bind` to `live`, `watch` to `effect`, depracated `calculate`.
142
+ - Add `safeState`, `safeLive`, `safeInit` functions, they make the JSX much safer.
143
+ - `callback` handler can return cleanup function.
144
+ - Navigation paths are now checked in compile time, missing paths are reported.
145
+ - Injected dependencies now are tracked in compile time, missing dependencies are reported.
146
+ - Support for wrapper in router, it can provide global dependencies.
147
+ - Reactive members are forbidden in live expressions. **[API change]**
148
+ - Reactive values are not unwrapped automatically, need `unwrap` call. **[API change]**
149
+ - Reactivity breaking is now reported in compile time. **[API change]**
150
+ - Writing to reactive states from effects is restricted,
151
+ workaround with `bypassWriteRestriction`. **[API change]**
152
+ - New reactivity marks `r_` & `wr_` insted of `$`,
153
+ workaround with `v4-naming` compilation flag. **[API change]**
154
+ - Component files have strict structure (imports, export, helpers, CSS). **[API change]**
139
155
 
140
156
  ### 6.0 RC (never released)
141
157
 
@@ -174,7 +190,7 @@ We respect semantic versioning:
174
190
  ### 1.0 - 1.2
175
191
 
176
192
  - Initial version of a core library.
177
- - Developemnt direction: `performance-first`.
193
+ - Development direction: `performance-first`.
178
194
 
179
195
  ## Questions
180
196
 
@@ -0,0 +1,9 @@
1
+ export interface AppSide {
2
+ highlight(ids: number[]): void;
3
+ setLookup(active: boolean): void;
4
+ }
5
+ export interface IdeSide {
6
+ clear(): void;
7
+ listDebugItems(ids: number[]): void;
8
+ callInspector(method: string, arg: object): void;
9
+ }
@@ -0,0 +1,14 @@
1
+ import { StaticPosition } from "vasille/dev";
2
+ import { CssStyleInjector } from "../web/css/index.js";
3
+ export declare class InspectedCssStyleInjector extends CssStyleInjector {
4
+ protected key: string;
5
+ readonly id: number;
6
+ constructor(key: string, rules: (string | [number, string])[], position: StaticPosition);
7
+ protected generateClassName(): string;
8
+ protected insertRule(rule: string | [number, string], className: string): void;
9
+ }
10
+ export declare function devStyleSheet<T extends {
11
+ [k: string]: [(string | [number, string])[], StaticPosition];
12
+ }>(styles: T): {
13
+ [K in keyof T]: InspectedCssStyleInjector;
14
+ };
@@ -0,0 +1,37 @@
1
+ import { inspector } from "vasille/dev";
2
+ import { CssStyleInjector } from "../web/css/index.js";
3
+ let injectorId = 0;
4
+ export class InspectedCssStyleInjector extends CssStyleInjector {
5
+ constructor(key, rules, position) {
6
+ super(rules);
7
+ this.key = key;
8
+ const id = (this.id = ++injectorId);
9
+ const name = this.inject();
10
+ inspector.cssInjector({
11
+ id: id,
12
+ position: position,
13
+ className: name,
14
+ time: Date.now(),
15
+ });
16
+ }
17
+ generateClassName() {
18
+ return `${super.generateClassName()}-${this.key}`;
19
+ }
20
+ insertRule(rule, className) {
21
+ let success = true;
22
+ try {
23
+ super.insertRule(rule, className);
24
+ }
25
+ catch (e) {
26
+ success = false;
27
+ }
28
+ inspector.cssRule({ id: this.id, rule, success });
29
+ }
30
+ }
31
+ export function devStyleSheet(styles) {
32
+ const result = {};
33
+ for (const key in styles) {
34
+ result[key] = new InspectedCssStyleInjector(key, ...styles[key]);
35
+ }
36
+ return result;
37
+ }
@@ -0,0 +1,3 @@
1
+ export declare function devSetMobileMaxWidth(value: number): void;
2
+ export declare function devSetTabletMaxWidth(value: number): void;
3
+ export declare function devSetLaptopMaxWidth(value: number): void;
@@ -0,0 +1,32 @@
1
+ import { laptopMaxWidth, mobileMaxWidth, setLaptopMaxWidth, setMobileMaxWidth, setTabletMaxWidth, tabletMaxWidth, } from "../web/css/index.js";
2
+ import { desktop, mobile, tablet } from "../web/css/lib.js";
3
+ function warn(device) {
4
+ console.warn(`[vasille-css] Setting of ${device} max width in production mode is not supported.`);
5
+ }
6
+ export function devSetMobileMaxWidth(value) {
7
+ setMobileMaxWidth(value);
8
+ if (mobile) {
9
+ mobile.media = `(max-width:${mobileMaxWidth}px)`;
10
+ }
11
+ if (tablet) {
12
+ tablet.media = `(min-width:${mobileMaxWidth}px) and (max-width:${tabletMaxWidth}px)`;
13
+ }
14
+ warn("mobile");
15
+ }
16
+ export function devSetTabletMaxWidth(value) {
17
+ setTabletMaxWidth(value);
18
+ if (tablet) {
19
+ tablet.media = `(min-width:${mobileMaxWidth}px) and (max-width:${tabletMaxWidth}px)`;
20
+ }
21
+ if (desktop) {
22
+ desktop.media = `(min-width:${tabletMaxWidth}px) and (max-width:${laptopMaxWidth}px)`;
23
+ }
24
+ warn("tablet");
25
+ }
26
+ export function devSetLaptopMaxWidth(value) {
27
+ setLaptopMaxWidth(value);
28
+ if (desktop) {
29
+ desktop.media = `(min-width:${tabletMaxWidth}px) and (max-width:${laptopMaxWidth}px)`;
30
+ }
31
+ warn("laptop");
32
+ }
@@ -0,0 +1,55 @@
1
+ import { devScreen } from "./router.js";
2
+ import { devModal, devPrompt } from "./mount.js";
3
+ import { DevWebTagOptions } from "./runner.js";
4
+ import { WebRouterInitialization } from "../web/router/router.js";
5
+ import { devArrayModel, DevArrayModelView, DevArrayView, devAwaited, devDebounceRef, DevDelay, devEnsure, devExpr, DevFor, devMapModel, DevMapModelView, devMatch, devModel, devRef, devSafeExpr, devSafeRef, devSet, devSetModel, DevSetModelView, DevSlot, devStore, DevSwitch, devView, DevWatch, DevZombie, toDevDeepFieldRef, toDevFieldRef, DevAppNode } from "vasille/dev";
6
+ export { Prompt, showPrompt } from "../web/index.js";
7
+ export { executionPosition, wrapFn, runFn, setupPosition } from "vasille/dev";
8
+ export { devSetErrorHandler as setErrorHandler } from "vasille/dev";
9
+ export { QueuedRender, Model, SteelContext } from "vasille";
10
+ export { devStyleSheet as styleSheet } from "./css-injector.js";
11
+ export { positionedText } from "./runner.js";
12
+ export { safe, abortSignal, safeInit } from "vasille";
13
+ export { devSetLaptopMaxWidth as setLaptopMaxWidth, devSetTabletMaxWidth as setTabletMaxWidth, devSetMobileMaxWidth as setMobileMaxWidth, } from "./css.js";
14
+ export { context, impute, receive, share, receiveOptional } from "vasille";
15
+ export declare const view: typeof devView;
16
+ export declare const component: typeof devView;
17
+ export declare const compose: typeof devView;
18
+ export declare const ensure: typeof devEnsure;
19
+ export declare const ref: typeof devRef;
20
+ export declare const state: typeof devRef;
21
+ export declare const expr: typeof devExpr;
22
+ export declare const bind: typeof devExpr;
23
+ export declare const calculate: typeof devExpr;
24
+ export declare const live: typeof devExpr;
25
+ export declare const watch: typeof devExpr;
26
+ export declare const effect: typeof devExpr;
27
+ export declare const safeLive: typeof devSafeExpr;
28
+ export declare const safeState: typeof devSafeRef;
29
+ export declare const set: typeof devSet;
30
+ export declare const Delay: typeof DevDelay;
31
+ export declare const For: typeof DevFor;
32
+ export declare const Slot: typeof DevSlot;
33
+ export declare const Watch: typeof DevWatch;
34
+ export declare const awaited: typeof devAwaited;
35
+ export declare const store: typeof devStore;
36
+ export declare const model: typeof devModel;
37
+ export declare const setModel: typeof devSetModel;
38
+ export declare const mapModel: typeof devMapModel;
39
+ export declare const arrayModel: typeof devArrayModel;
40
+ export declare const Switch: typeof DevSwitch;
41
+ export declare const match: typeof devMatch;
42
+ export declare const ArrayView: typeof DevArrayView;
43
+ export declare const MapModelView: typeof DevMapModelView;
44
+ export declare const SetModelView: typeof DevSetModelView;
45
+ export declare const ArrayModelView: typeof DevArrayModelView;
46
+ export declare const Zombie: typeof DevZombie;
47
+ export declare const debounced: typeof devDebounceRef;
48
+ export declare const toFieldRef: typeof toDevFieldRef;
49
+ export declare const toDeepFieldRef: typeof toDevDeepFieldRef;
50
+ export declare const screen: typeof devScreen;
51
+ export declare const page: typeof devScreen;
52
+ export declare const modal: typeof devModal;
53
+ export declare const prompt: typeof devPrompt;
54
+ export declare function mount<T>(element: Element, component: ($: T) => void, input: T): DevAppNode<Node, Element, DevWebTagOptions>;
55
+ export declare function routerApp<Routes extends string>(init: WebRouterInitialization<Routes>, element?: Element): DevAppNode<Node, Element, DevWebTagOptions>;
@@ -0,0 +1,64 @@
1
+ import { devScreen } from "./router.js";
2
+ import { devModal, devPrompt, webDevMountApp, webDevRouterApp } from "./mount.js";
3
+ import { Inspector } from "./inspector.js";
4
+ import { devArrayModel, DevArrayModelView, DevArrayView, devAwaited, devDebounceRef, DevDelay, devEnsure, devExpr, DevFor, devMapModel, DevMapModelView, devMatch, devModel, devRef, devSafeExpr, devSafeRef, devSet, devSetModel, DevSetModelView, DevSlot, devStore, DevSwitch, devView, DevWatch, DevZombie, toDevDeepFieldRef, toDevFieldRef, } from "vasille/dev";
5
+ export { Prompt, showPrompt } from "../web/index.js";
6
+ export { executionPosition, wrapFn, runFn, setupPosition } from "vasille/dev";
7
+ export { devSetErrorHandler as setErrorHandler } from "vasille/dev";
8
+ export { QueuedRender, Model, SteelContext } from "vasille";
9
+ export { devStyleSheet as styleSheet } from "./css-injector.js";
10
+ export { positionedText } from "./runner.js";
11
+ export { safe, abortSignal, safeInit } from "vasille";
12
+ export { devSetLaptopMaxWidth as setLaptopMaxWidth, devSetTabletMaxWidth as setTabletMaxWidth, devSetMobileMaxWidth as setMobileMaxWidth, } from "./css.js";
13
+ export { context, impute, receive, share, receiveOptional } from "vasille";
14
+ export const view = devView;
15
+ export const component = devView;
16
+ export const compose = devView;
17
+ export const ensure = devEnsure;
18
+ export const ref = devRef;
19
+ export const state = devRef;
20
+ export const expr = devExpr;
21
+ export const bind = devExpr;
22
+ export const calculate = devExpr;
23
+ export const live = devExpr;
24
+ export const watch = devExpr;
25
+ export const effect = devExpr;
26
+ export const safeLive = devSafeExpr;
27
+ export const safeState = devSafeRef;
28
+ export const set = devSet;
29
+ export const Delay = DevDelay;
30
+ export const For = DevFor;
31
+ export const Slot = DevSlot;
32
+ export const Watch = DevWatch;
33
+ export const awaited = devAwaited;
34
+ export const store = devStore;
35
+ export const model = devModel;
36
+ export const setModel = devSetModel;
37
+ export const mapModel = devMapModel;
38
+ export const arrayModel = devArrayModel;
39
+ export const Switch = DevSwitch;
40
+ export const match = devMatch;
41
+ export const ArrayView = DevArrayView;
42
+ export const MapModelView = DevMapModelView;
43
+ export const SetModelView = DevSetModelView;
44
+ export const ArrayModelView = DevArrayModelView;
45
+ export const Zombie = DevZombie;
46
+ export const debounced = devDebounceRef;
47
+ export const toFieldRef = toDevFieldRef;
48
+ export const toDeepFieldRef = toDevDeepFieldRef;
49
+ export const screen = devScreen;
50
+ export const page = devScreen;
51
+ export const modal = devModal;
52
+ export const prompt = devPrompt;
53
+ export function mount(element, component, input) {
54
+ const inspector = new Inspector();
55
+ const app = webDevMountApp(element, component, input, inspector);
56
+ inspector.setup(app);
57
+ return app;
58
+ }
59
+ export function routerApp(init, element) {
60
+ const inspector = new Inspector();
61
+ const app = webDevRouterApp(init, element ?? document.body, inspector);
62
+ inspector.setup(app);
63
+ return app;
64
+ }
@@ -0,0 +1,18 @@
1
+ import type { IdeSide } from "./communication.js";
2
+ import { AppNode } from "vasille";
3
+ import { AbstractInspector } from "vasille/dev";
4
+ import { WebTagOptions } from "../web/runner/runner.js";
5
+ export declare class Inspector extends AbstractInspector implements IdeSide {
6
+ private ws;
7
+ private queue;
8
+ private app;
9
+ private clean;
10
+ constructor();
11
+ setup(app: AppNode<Node, Element, WebTagOptions>): void;
12
+ callInspector(method: string, arg: object): void;
13
+ listDebugItems(ids: number[]): void;
14
+ clear(): void;
15
+ private _connect;
16
+ protected send(method: string, arg: object): void;
17
+ private sendMessage;
18
+ }
@@ -0,0 +1,226 @@
1
+ import { expr, Fragment, ref } from "vasille";
2
+ import { DevFragment, inspector } from "vasille/dev";
3
+ import { AbstractInspector } from "vasille/dev";
4
+ import { DevWebTag, DevWebTextNode } from "./runner.js";
5
+ class AppHandler {
6
+ constructor() {
7
+ this.canvas = null;
8
+ this.app = null;
9
+ this.active = ref(false);
10
+ this.$width = ref(window.innerWidth);
11
+ this.$height = ref(window.innerHeight);
12
+ window.addEventListener("resize", () => {
13
+ this.$width.V = window.innerWidth;
14
+ this.$height.V = window.innerHeight;
15
+ });
16
+ }
17
+ setup(app, bridge) {
18
+ this.app = app;
19
+ app.tag("canvas", {
20
+ a: {
21
+ width: this.$width,
22
+ height: this.$height,
23
+ },
24
+ s: {
25
+ "pointer-events": expr(app, active => (active ? "auto" : "none"), [this.active]),
26
+ position: "fixed",
27
+ inset: "0",
28
+ "z-index": "9999909",
29
+ },
30
+ k: canvas => {
31
+ this.canvas = canvas;
32
+ },
33
+ e: {
34
+ pointermove: (ev) => {
35
+ const canvas = this.canvas;
36
+ const ctx = canvas?.getContext("2d");
37
+ let element;
38
+ if (!ctx || !canvas) {
39
+ return;
40
+ }
41
+ ev.preventDefault();
42
+ this.active.V = false;
43
+ element = document.elementFromPoint(ev.clientX, ev.clientY);
44
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
45
+ ctx.fillStyle = "#ff000030";
46
+ if (element) {
47
+ const rect = element.getBoundingClientRect();
48
+ ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
49
+ }
50
+ this.active.V = true;
51
+ },
52
+ pointerdown: (ev) => {
53
+ const ids = [];
54
+ const key = "vasille";
55
+ let textNode = null;
56
+ let elements;
57
+ ev.preventDefault();
58
+ this.active.V = false;
59
+ elements = document.elementsFromPoint(ev.clientX, ev.clientY);
60
+ if (document.caretPositionFromPoint) {
61
+ textNode = document.caretPositionFromPoint(ev.clientX, ev.clientY)?.offsetNode;
62
+ }
63
+ else if (document.caretRangeFromPoint) {
64
+ textNode = document.caretRangeFromPoint(ev.clientX, ev.clientY)?.startContainer;
65
+ }
66
+ this.active.V = true;
67
+ if (textNode && key in textNode) {
68
+ ids.push(textNode[key]);
69
+ }
70
+ for (const element of elements) {
71
+ if (key in element) {
72
+ ids.push(element[key]);
73
+ }
74
+ }
75
+ bridge.listDebugItems(ids);
76
+ this.active.V = false;
77
+ const canvas = this.canvas;
78
+ const ctx = canvas?.getContext("2d");
79
+ if (ctx && canvas) {
80
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
81
+ }
82
+ },
83
+ },
84
+ });
85
+ }
86
+ highlight(ids) {
87
+ if (this.app === null) {
88
+ return;
89
+ }
90
+ const tags = new Set();
91
+ const texts = new Set();
92
+ this.iterateFragment(this.app, new Set(ids), tags, texts);
93
+ const canvas = this.canvas;
94
+ const ctx = canvas?.getContext("2d");
95
+ if (ctx && canvas) {
96
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
97
+ ctx.fillStyle = "#ff000030";
98
+ for (const tag of tags) {
99
+ const rect = tag.node?.getBoundingClientRect();
100
+ if (rect) {
101
+ ctx.fillRect(rect.x, rect.y, rect.width, rect.height);
102
+ }
103
+ }
104
+ }
105
+ const sel = window.getSelection();
106
+ if (sel) {
107
+ sel.removeAllRanges();
108
+ for (const text of texts) {
109
+ const range = document.createRange();
110
+ // @ts-expect-error node field is protected
111
+ range.selectNodeContents(text.node);
112
+ sel.addRange(range);
113
+ }
114
+ }
115
+ }
116
+ setLookup(active) {
117
+ this.active.V = active;
118
+ const canvas = this.canvas;
119
+ const ctx = canvas?.getContext("2d");
120
+ if (ctx && canvas) {
121
+ ctx.clearRect(0, 0, canvas.width, canvas.height);
122
+ if (active) {
123
+ ctx.fillStyle = "#ff000030";
124
+ ctx.fillRect(0, 0, canvas.width, canvas.height);
125
+ }
126
+ }
127
+ }
128
+ iterateFragment(node, ids, set, texts) {
129
+ for (const child of node.children) {
130
+ if ("id" in child && ids.has(child.id)) {
131
+ this.addReactive(child, set, texts);
132
+ }
133
+ else if (child instanceof Fragment) {
134
+ this.iterateFragment(child, ids, set, texts);
135
+ }
136
+ }
137
+ }
138
+ addTag(node, set) {
139
+ set.add(node);
140
+ }
141
+ addText(node, set) {
142
+ let it = node.parent;
143
+ while (it instanceof DevFragment) {
144
+ it = it.parent;
145
+ }
146
+ if (it instanceof DevWebTag) {
147
+ set.add(it);
148
+ }
149
+ }
150
+ addFragment(node, set, texts) {
151
+ for (const child of node.children) {
152
+ this.addReactive(child, set, texts);
153
+ }
154
+ }
155
+ addReactive(node, set, texts) {
156
+ if (node instanceof DevWebTag) {
157
+ this.addTag(node, set);
158
+ }
159
+ else if (node instanceof DevWebTextNode) {
160
+ this.addText(node, set);
161
+ texts.add(node);
162
+ }
163
+ else if (node instanceof DevFragment) {
164
+ this.addFragment(node, set, texts);
165
+ }
166
+ }
167
+ }
168
+ export class Inspector extends AbstractInspector {
169
+ constructor() {
170
+ super();
171
+ this.clean = false;
172
+ this.ws = null;
173
+ this.queue = [];
174
+ this.app = new AppHandler();
175
+ this._connect();
176
+ inspector.connect(this);
177
+ }
178
+ setup(app) {
179
+ this.app.setup(app, this);
180
+ }
181
+ callInspector(method, arg) {
182
+ this.sendMessage(this.callInspector.name, [method, arg]);
183
+ }
184
+ listDebugItems(ids) {
185
+ this.sendMessage(this.listDebugItems.name, [ids]);
186
+ }
187
+ clear() {
188
+ this.sendMessage(this.clear.name, []);
189
+ }
190
+ _connect() {
191
+ const ws = (this.ws = new WebSocket("ws://localhost:7374"));
192
+ ws.onopen = () => {
193
+ if (!this.clean) {
194
+ ws.send(JSON.stringify(["clear", []]));
195
+ this.clean = true;
196
+ }
197
+ // Send all queued messages
198
+ while (this.queue.length > 0) {
199
+ ws.send(JSON.stringify(this.queue.shift()));
200
+ }
201
+ };
202
+ ws.onmessage = ev => {
203
+ const [method, args] = JSON.parse(ev.data);
204
+ this.app[method](...args);
205
+ };
206
+ ws.onclose = () => {
207
+ setTimeout(() => this._connect(), 1000);
208
+ };
209
+ ws.onerror = () => {
210
+ ws.close();
211
+ };
212
+ }
213
+ send(method, arg) {
214
+ this.callInspector(method, arg);
215
+ }
216
+ sendMessage(method, args) {
217
+ const message = [method, args];
218
+ const ws = this.ws;
219
+ if (ws && ws.readyState === WebSocket.OPEN) {
220
+ ws.send(JSON.stringify(message));
221
+ }
222
+ else {
223
+ this.queue.push(message);
224
+ }
225
+ }
226
+ }
@@ -0,0 +1,11 @@
1
+ import { CompositionProps, Fragment, IRunner } from "vasille";
2
+ import { SsgTagOptions } from "../ssg/runner.js";
3
+ import { DevAppNode, Inspector, StaticPosition } from "vasille/dev";
4
+ import { Prompt } from "../web/index.js";
5
+ import { DevWebTagOptions } from "./runner.js";
6
+ import { WebRouterInitialization } from "../web/router/router.js";
7
+ import { PromptProps } from "../web/mount.js";
8
+ export declare function devModal<T extends CompositionProps>(modalFn: (node: Fragment<Node, Element, SsgTagOptions>, input: T) => void, declaration: StaticPosition, name: string): (input: T, node: Fragment<Node, Element, SsgTagOptions>, slot?: T["slot"], usage?: StaticPosition) => void;
9
+ export declare function devPrompt<T extends PromptProps>(modal: (node: Fragment<Node, Element, SsgTagOptions, IRunner<Node, Element, SsgTagOptions>>, input: T) => void, declaration: StaticPosition, name: string): Prompt<T, [number, StaticPosition]>;
10
+ export declare function webDevMountApp<T>(element: Element, component: ($: T) => void, input: T, inspector: Inspector): DevAppNode<Node, Element, DevWebTagOptions>;
11
+ export declare function webDevRouterApp<Routes extends string>(init: WebRouterInitialization<Routes>, element: Element, inspector: Inspector): DevAppNode<Node, Element, DevWebTagOptions>;