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.
- package/README.md +32 -16
- package/build/dev/communication.d.ts +9 -0
- package/build/dev/css-injector.d.ts +14 -0
- package/build/dev/css-injector.js +37 -0
- package/build/dev/css.d.ts +3 -0
- package/build/dev/css.js +32 -0
- package/build/dev/index.d.ts +55 -0
- package/build/dev/index.js +64 -0
- package/build/dev/inspector.d.ts +18 -0
- package/build/dev/inspector.js +226 -0
- package/build/dev/mount.d.ts +11 -0
- package/build/dev/mount.js +91 -0
- package/build/dev/router.d.ts +23 -0
- package/build/dev/router.js +67 -0
- package/build/dev/runner.d.ts +34 -0
- package/build/dev/runner.js +128 -0
- package/build/shadow/css.d.ts +23 -0
- package/build/shadow/css.js +77 -0
- package/build/shadow/index.d.ts +3 -0
- package/build/shadow/index.js +3 -0
- package/build/shadow/lib.d.ts +11 -0
- package/build/shadow/lib.js +145 -0
- package/build/shadow/types.d.ts +31 -0
- package/build/ssg/awaited.d.ts +3 -0
- package/build/ssg/awaited.js +24 -0
- package/build/ssg/css.d.ts +8 -0
- package/build/ssg/css.js +36 -0
- package/build/ssg/index.d.ts +21 -0
- package/build/ssg/index.js +37 -0
- package/build/ssg/router.d.ts +17 -0
- package/build/ssg/router.js +59 -0
- package/build/ssg/runner.d.ts +56 -0
- package/build/ssg/runner.js +337 -0
- package/build/types/index.d.ts +9 -0
- package/build/types/index.js +1 -0
- package/build/web/css/index.d.ts +21 -0
- package/build/web/css/index.js +53 -0
- package/build/web/css/lib.d.ts +10 -0
- package/build/web/css/lib.js +75 -0
- package/build/web/index.d.ts +6 -0
- package/build/web/index.js +6 -0
- package/{types → build/web/jsx}/jsx-runtime.d.ts +6 -6
- package/build/web/jsx/spec/css.d.ts +7 -0
- package/build/web/jsx/spec/css.js +1 -0
- package/{types → build/web/jsx}/spec/html.d.ts +1 -1
- package/build/web/jsx/spec/html.js +1 -0
- package/build/web/mount.d.ts +19 -0
- package/{lib/index.js → build/web/mount.js} +25 -20
- package/build/web/router/router.d.ts +45 -0
- package/build/web/router/router.js +131 -0
- package/build/web/runner/binding/attribute.d.ts +16 -0
- package/build/web/runner/binding/attribute.js +30 -0
- package/build/web/runner/binding/binding.d.ts +20 -0
- package/build/web/runner/binding/binding.js +28 -0
- package/build/web/runner/binding/class.d.ts +9 -0
- package/build/web/runner/binding/class.js +32 -0
- package/build/web/runner/binding/property.d.ts +16 -0
- package/build/web/runner/binding/property.js +20 -0
- package/build/web/runner/binding/style.d.ts +17 -0
- package/build/web/runner/binding/style.js +32 -0
- package/build/web/runner/runner.d.ts +45 -0
- package/build/web/runner/runner.js +176 -0
- package/coverage/clover.xml +754 -0
- package/coverage/coverage-final.json +20 -0
- package/coverage/lcov-report/base.css +224 -0
- package/coverage/lcov-report/block-navigation.js +87 -0
- package/coverage/lcov-report/dev/css-injector.ts.html +250 -0
- package/coverage/lcov-report/dev/css.ts.html +220 -0
- package/coverage/lcov-report/dev/index.html +131 -0
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +221 -0
- package/coverage/lcov-report/prettify.css +1 -0
- package/coverage/lcov-report/prettify.js +2 -0
- package/coverage/lcov-report/shadow/css.ts.html +382 -0
- package/coverage/lcov-report/shadow/index.html +131 -0
- package/coverage/lcov-report/shadow/lib.ts.html +670 -0
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +210 -0
- package/coverage/lcov-report/ssg/awaited.ts.html +169 -0
- package/coverage/lcov-report/ssg/css.ts.html +223 -0
- package/coverage/lcov-report/ssg/index.html +176 -0
- package/coverage/lcov-report/ssg/index.ts.html +370 -0
- package/coverage/lcov-report/ssg/router.ts.html +388 -0
- package/coverage/lcov-report/ssg/runner.ts.html +1405 -0
- package/coverage/lcov-report/web/css/index.html +131 -0
- package/coverage/lcov-report/web/css/index.ts.html +313 -0
- package/coverage/lcov-report/web/css/lib.ts.html +352 -0
- package/coverage/lcov-report/web/index.html +116 -0
- package/coverage/lcov-report/web/index.ts.html +574 -0
- package/coverage/lcov-report/web/mount.ts.html +454 -0
- package/coverage/lcov-report/web/router/index.html +116 -0
- package/coverage/lcov-report/web/router/router.ts.html +784 -0
- package/coverage/lcov-report/web/runner/binding/attribute.ts.html +190 -0
- package/coverage/lcov-report/web/runner/binding/binding.ts.html +193 -0
- package/coverage/lcov-report/web/runner/binding/class.ts.html +199 -0
- package/coverage/lcov-report/web/runner/binding/index.html +176 -0
- package/coverage/lcov-report/web/runner/binding/property.ts.html +154 -0
- package/coverage/lcov-report/web/runner/binding/style.ts.html +205 -0
- package/coverage/lcov-report/web/runner/index.html +116 -0
- package/coverage/lcov-report/web/runner/runner.ts.html +835 -0
- package/coverage/lcov.info +1554 -0
- package/jest.config.cjs +37 -0
- package/package.json +91 -60
- package/test/api/dev.test.ts +5 -0
- package/test/api/import-list.ts +106 -0
- package/test/api/shadow.test.ts +5 -0
- package/test/api/ssg.test.ts +5 -0
- package/test/api/web.test.ts +5 -0
- package/test/css/css-dev.test.ts +103 -0
- package/test/css/css.test.ts +27 -0
- package/test/mount/exported-web-router.test.ts +63 -0
- package/test/mount/modal-no-ctx.test.ts +14 -0
- package/test/mount/modal-which-throws.test.ts +33 -0
- package/test/mount/modal-with-slot.test.ts +39 -0
- package/test/mount/modal.test.ts +34 -0
- package/test/mount/prompt-error.test.ts +44 -0
- package/test/mount/prompt-timeout.test.ts +53 -0
- package/test/mount/prompt-which-trows.test.ts +33 -0
- package/test/mount/prompt.test.ts +44 -0
- package/test/page.ts +16 -0
- package/test/router/empty-router.test.ts +21 -0
- package/test/router/page.ts +19 -0
- package/test/router/router.test.ts +774 -0
- package/test/router/v7.test.ts +129 -0
- package/test/runner/destruction.test.ts +113 -0
- package/test/runner/runner.test.ts +403 -0
- package/test/shadow/components/Component.ts +72 -0
- package/test/shadow/css.test.ts +68 -0
- package/test/shadow/page.ts +21 -0
- package/test/shadow/shadow.test.ts +71 -0
- package/test/ssg/awaited/awaited.test.ts +11 -0
- package/test/ssg/awaited/element.test.ts +6 -0
- package/test/ssg/awaited/element.tsx +10 -0
- package/test/ssg/awaited/element.tsx.html +12 -0
- package/test/ssg/awaited/embed.test.ts +6 -0
- package/test/ssg/awaited/embed.tsx +14 -0
- package/test/ssg/awaited/embed.tsx.html +16 -0
- package/test/ssg/awaited/text.test.ts +6 -0
- package/test/ssg/awaited/text.tsx +8 -0
- package/test/ssg/awaited/text.tsx.html +7 -0
- package/test/ssg/awaited/throw-sync.tsx +10 -0
- package/test/ssg/awaited/throw-sync.tsx.html +7 -0
- package/test/ssg/awaited/throw.tsx +13 -0
- package/test/ssg/awaited/throw.tsx.html +7 -0
- package/test/ssg/compose/compose.test.ts +25 -0
- package/test/ssg/compose/modal.tsx +29 -0
- package/test/ssg/compose/modal.tsx.html +16 -0
- package/test/ssg/compose/view.tsx +35 -0
- package/test/ssg/compose/view.tsx.html +12 -0
- package/test/ssg/core/core.test.ts +31 -0
- package/test/ssg/core/div-embed.tsx +7 -0
- package/test/ssg/core/div-embed.tsx.html +9 -0
- package/test/ssg/core/div-with-class.tsx +5 -0
- package/test/ssg/core/div-with-class.tsx.html +9 -0
- package/test/ssg/core/div-with-text.tsx +5 -0
- package/test/ssg/core/div-with-text.tsx.html +9 -0
- package/test/ssg/core/div.tsx +5 -0
- package/test/ssg/core/div.tsx.html +7 -0
- package/test/ssg/core/text-join.tsx +9 -0
- package/test/ssg/core/text-join.tsx.html +10 -0
- package/test/ssg/core/text.tsx +5 -0
- package/test/ssg/core/text.tsx.html +7 -0
- package/test/ssg/css/css.test.ts +6 -0
- package/test/ssg/css/css.tsx +34 -0
- package/test/ssg/css/css.tsx.html +28 -0
- package/test/ssg/extra-tags/body.tsx +6 -0
- package/test/ssg/extra-tags/body.tsx.html +7 -0
- package/test/ssg/extra-tags/extra-tags.test.ts +11 -0
- package/test/ssg/extra-tags/head.tsx +9 -0
- package/test/ssg/extra-tags/head.tsx.html +12 -0
- package/test/ssg/markdown/blocks.tsx +12 -0
- package/test/ssg/markdown/blocks.tsx.md +12 -0
- package/test/ssg/markdown/css.tsx +11 -0
- package/test/ssg/markdown/css.tsx.md +1 -0
- package/test/ssg/markdown/external.tsx +7 -0
- package/test/ssg/markdown/external.tsx.md +3 -0
- package/test/ssg/markdown/heading.tsx +12 -0
- package/test/ssg/markdown/heading.tsx.md +13 -0
- package/test/ssg/markdown/hybrid.tsx +15 -0
- package/test/ssg/markdown/hybrid.tsx.md +11 -0
- package/test/ssg/markdown/lists.tsx +26 -0
- package/test/ssg/markdown/lists.tsx.md +16 -0
- package/test/ssg/markdown/markdown.test.ts +41 -0
- package/test/ssg/markdown/stylish.tsx +19 -0
- package/test/ssg/markdown/stylish.tsx.md +15 -0
- package/test/ssg/markdown/table.tsx +32 -0
- package/test/ssg/markdown/table.tsx.md +11 -0
- package/test/ssg/router/embed.html +7 -0
- package/test/ssg/router/embed.tsx +5 -0
- package/test/ssg/router/file-html.tsx +5 -0
- package/test/ssg/router/file.html +7 -0
- package/test/ssg/router/index.html +7 -0
- package/test/ssg/router/index.tsx +5 -0
- package/test/ssg/router/router.test.ts +26 -0
- package/test/ssg/run-test.ts +33 -0
- package/test/ssg/runner/attr.tsx +7 -0
- package/test/ssg/runner/attr.tsx.html +7 -0
- package/test/ssg/runner/class.tsx +8 -0
- package/test/ssg/runner/class.tsx.html +7 -0
- package/test/ssg/runner/runner.test.ts +16 -0
- package/test/ssg/runner/style.tsx +19 -0
- package/test/ssg/runner/style.tsx.html +7 -0
- package/test/tsconfig.json +20 -0
- package/lib/dev.js +0 -109
- package/types/dev.d.ts +0 -10
- package/types/index.d.ts +0 -21
- package/types/spec/css.d.ts +0 -7
- /package/{lib/spec/css.js → build/dev/communication.js} +0 -0
- /package/{lib/spec/html.js → build/shadow/types.js} +0 -0
- /package/{lib → build/web/jsx}/jsx-runtime.js +0 -0
package/README.md
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|

|
|
4
4
|
|
|
5
|
-
|
|
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
|
[](https://www.npmjs.com/package/steel-frame)
|
|
8
10
|
[](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
|
|
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
|
|
20
|
-
- [How INTUITIVE is
|
|
21
|
-
- [How POWERFUL is
|
|
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
|
|
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 `
|
|
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
|
-
- [
|
|
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
|
|
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 `
|
|
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
|
|
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
|
|
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
|
|
136
|
+
### 7.0
|
|
134
137
|
|
|
135
|
-
- Add `
|
|
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
|
-
-
|
|
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
|
-
-
|
|
193
|
+
- Development direction: `performance-first`.
|
|
178
194
|
|
|
179
195
|
## Questions
|
|
180
196
|
|
|
@@ -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
|
+
}
|
package/build/dev/css.js
ADDED
|
@@ -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>;
|