vasille 4.3.1 → 5.0.1
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 +71 -37
- package/lib/dev/components.js +82 -0
- package/lib/dev/core.js +15 -0
- package/lib/dev/index.js +8 -0
- package/lib/dev/inspectable.js +113 -0
- package/lib/dev/models.js +147 -0
- package/lib/dev/node.js +59 -0
- package/lib/dev/runner.js +141 -0
- package/lib/dev/state.js +194 -0
- package/lib/dev/views.js +62 -0
- package/lib/index.js +1 -2
- package/lib/models/set-model.js +1 -0
- package/lib/node/app.js +1 -1
- package/lib/node/node.js +14 -33
- package/lib/runner/web/binding/class.js +2 -15
- package/lib/runner/web/runner.js +25 -53
- package/lib/value/expression.js +3 -2
- package/lib/views/repeat-node.js +4 -1
- package/package.json +7 -1
- package/types/dev/components.d.ts +20 -0
- package/types/dev/core.d.ts +8 -0
- package/types/dev/index.d.ts +8 -0
- package/types/dev/inspectable.d.ts +244 -0
- package/types/dev/models.d.ts +38 -0
- package/types/dev/node.d.ts +12 -0
- package/types/dev/runner.d.ts +37 -0
- package/types/dev/state.d.ts +53 -0
- package/types/dev/views.d.ts +22 -0
- package/types/index.d.ts +2 -3
- package/types/node/app.d.ts +8 -9
- package/types/node/node.d.ts +17 -34
- package/types/node/runner.d.ts +2 -5
- package/types/node/watch.d.ts +5 -6
- package/types/runner/web/runner.d.ts +21 -25
- package/types/value/expression.d.ts +2 -1
- package/types/views/array-view.d.ts +3 -2
- package/types/views/base-view.d.ts +4 -4
- package/types/views/map-view.d.ts +2 -1
- package/types/views/repeat-node.d.ts +7 -6
- package/types/views/set-view.d.ts +3 -3
- package/lib/value/pointer.js +0 -61
- package/types/value/pointer.d.ts +0 -46
package/README.md
CHANGED
|
@@ -1,19 +1,32 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Steel Frame
|
|
2
2
|
|
|
3
|
-

|
|
4
4
|
|
|
5
|
-
`
|
|
5
|
+
`SteelFrameKit` is a front-end development kit, which is developed to provide fault tolerant web applications.
|
|
6
6
|
|
|
7
|
-
[](https://www.npmjs.com/package/steel-frame)
|
|
8
|
+
[](https://deepwiki.com/vasille-js/steel-frame)
|
|
9
|
+
[](https://coveralls.io/github/vasille-js/steel-frame?branch=v5)
|
|
8
10
|
|
|
9
11
|
## Table of content
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
- [Steel Frame](#steel-frame)
|
|
14
|
+
- [Table of content](#table-of-content)
|
|
15
|
+
- [Installation](#installation)
|
|
16
|
+
- [How to use SteelFramekit](#how-to-use-steelframekit)
|
|
17
|
+
- [Full documentation:](#full-documentation)
|
|
18
|
+
- [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)
|
|
22
|
+
- [Road map](#road-map)
|
|
23
|
+
- [Change log](#change-log)
|
|
24
|
+
- [5.0](#50)
|
|
25
|
+
- [4.0 - 4.3](#40---43)
|
|
26
|
+
- [3.0 - 3.2](#30---32)
|
|
27
|
+
- [2.0 - 2.3](#20---23)
|
|
28
|
+
- [1.0 - 1.2](#10---12)
|
|
29
|
+
- [Questions](#questions)
|
|
17
30
|
|
|
18
31
|
|
|
19
32
|
<hr>
|
|
@@ -21,21 +34,22 @@
|
|
|
21
34
|
## Installation
|
|
22
35
|
|
|
23
36
|
```
|
|
24
|
-
npm install
|
|
37
|
+
npm install steel-frame --save
|
|
25
38
|
```
|
|
26
39
|
|
|
27
|
-
## How to use
|
|
40
|
+
## How to use SteelFramekit
|
|
28
41
|
|
|
29
42
|
Create an app from a template
|
|
30
43
|
|
|
31
44
|
```bash
|
|
32
|
-
$ npm create
|
|
45
|
+
$ npm create steel-frame
|
|
33
46
|
```
|
|
34
47
|
|
|
35
48
|
### Full documentation:
|
|
36
|
-
* [Learn `
|
|
37
|
-
* [
|
|
38
|
-
* [
|
|
49
|
+
* [Learn `SteelFrameKit` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v5/doc/V4-API.md)
|
|
50
|
+
* [Router Documentation](https://github.com/vasille-js/vasille-js/blob/v5/doc/Router-API.md)
|
|
51
|
+
* [Compostion functions](https://github.com/vasille-js/vasille-js/blob/v5/doc/Compositions.md)
|
|
52
|
+
* [Dependency injection](https://github.com/vasille-js/vasille-js/blob/v5/doc/Context.md)
|
|
39
53
|
|
|
40
54
|
### Examples
|
|
41
55
|
* [TypeScript Example](https://github.com/vasille-js/example-typescript)
|
|
@@ -43,14 +57,14 @@ $ npm create vasille
|
|
|
43
57
|
|
|
44
58
|
<hr>
|
|
45
59
|
|
|
46
|
-
## How SAFE is
|
|
60
|
+
## How SAFE is SteelFrameKit
|
|
47
61
|
|
|
48
62
|
The safe of your application is ensured by
|
|
49
63
|
* `100%` coverage of code by unit tests.
|
|
50
64
|
Each function, each branch is working as designed.
|
|
51
65
|
* OOP, DRY, KISS and SOLID principles are applied.
|
|
52
66
|
* `strong typing` makes your javascript/typescript code safe as C++ code.
|
|
53
|
-
All entities of `
|
|
67
|
+
All entities of `SteelFrameKit` core library are strongly typed, including:
|
|
54
68
|
* data fields & properties.
|
|
55
69
|
* computed properties (function parameters and result).
|
|
56
70
|
* methods.
|
|
@@ -60,11 +74,11 @@ All entities of `vasille` core library are strongly typed, including:
|
|
|
60
74
|
* references to children.
|
|
61
75
|
* No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
|
|
62
76
|
|
|
63
|
-
## How INTUITIVE is
|
|
77
|
+
## How INTUITIVE is SteelFrameKit
|
|
64
78
|
|
|
65
79
|
There is the "Hello World":
|
|
66
80
|
```typescript jsx
|
|
67
|
-
import { compose, mount } from "
|
|
81
|
+
import { compose, mount } from "steel-frame";
|
|
68
82
|
|
|
69
83
|
const App = compose(() => {
|
|
70
84
|
<p>Hello world</p>;
|
|
@@ -73,56 +87,76 @@ const App = compose(() => {
|
|
|
73
87
|
mount(document.body, App, {});
|
|
74
88
|
```
|
|
75
89
|
|
|
76
|
-
## How POWERFUL is
|
|
90
|
+
## How POWERFUL is SteelFrameKit
|
|
77
91
|
|
|
78
92
|
All of these are supported:
|
|
79
93
|
* Components.
|
|
80
94
|
* Reactive values (observables).
|
|
81
95
|
* Inline computed values.
|
|
82
96
|
* Multiline computed values.
|
|
83
|
-
* HTML
|
|
97
|
+
* HTML tags.
|
|
84
98
|
* Component custom slots.
|
|
85
99
|
* 2-way data binding in components.
|
|
86
100
|
* Logic block (if, else).
|
|
87
101
|
* Loops (array, map, set).
|
|
102
|
+
* Dependency injection.
|
|
88
103
|
|
|
89
104
|
<hr>
|
|
90
105
|
|
|
91
106
|
## Road map
|
|
92
107
|
|
|
93
|
-
* [x] Update the `Vasille Core` library to version 3.0.
|
|
94
108
|
* [x] `100%` Test Coverage for core Library v3.
|
|
95
|
-
* [x] Develop the `
|
|
109
|
+
* [x] Develop the `JSX` library.
|
|
96
110
|
* [x] `100%` Test Coverage for the JSX library.
|
|
97
|
-
* [x] Develop the `
|
|
111
|
+
* [x] Develop the `Babel Plugin`.
|
|
98
112
|
* [x] `100%` Test Coverage fot babel plugin.
|
|
99
113
|
* [x] Add CSS support (define styles in components).
|
|
100
114
|
* [x] Add router.
|
|
101
115
|
* [x] Add SSG (static site generation).
|
|
116
|
+
* [ ] Develop tools extension for debugging (WIP).
|
|
102
117
|
* [ ] Add SSR (server side rendering).
|
|
103
|
-
* [ ] Develop tools extension for debugging.
|
|
104
118
|
|
|
105
119
|
## Change log
|
|
106
120
|
|
|
107
|
-
|
|
121
|
+
We respect semantic versioning:
|
|
122
|
+
- Major version is increased when we make incompatible API changes.
|
|
123
|
+
- Minor version is increased when we add functionality.
|
|
124
|
+
- Patch version is increased when we fix bugs.
|
|
108
125
|
|
|
109
|
-
|
|
126
|
+
### 5.0
|
|
110
127
|
|
|
111
|
-
|
|
128
|
+
- Add support for context and dependencies injection.
|
|
129
|
+
- New developement direction: `fault tolerant`.
|
|
130
|
+
- Renamed to `steel-frame`. **[API change]**
|
|
131
|
+
- Removed `forward` and `backward` functions. **[API change]**
|
|
132
|
+
- Removed `Debug` component. **[API change]**
|
|
112
133
|
|
|
113
|
-
|
|
134
|
+
### 4.0 - 4.3
|
|
114
135
|
|
|
115
|
-
|
|
136
|
+
- Initial version of the framework with file based routing and building scripts (`web dev` and `web build spa`).
|
|
137
|
+
- Reactive values naming switched to `$` prefix. **[API change]**
|
|
138
|
+
- `4.1` Added SSG (static site generation) as build option `web build static`.
|
|
139
|
+
- `4.2` Add support for inlined conditions in JSX, binary `&&` and ternary `?:` operator.
|
|
140
|
+
- `4.3` Add new function `safe` which make functions safe, errors are reported automatically.
|
|
116
141
|
|
|
117
|
-
|
|
142
|
+
### 3.0 - 3.2
|
|
143
|
+
|
|
144
|
+
- Switch to a babel plugin to compile components code. **[API change]**
|
|
145
|
+
- 100% of code has been covered with unit tests.
|
|
146
|
+
- New developement direction: `keep it simple`.
|
|
147
|
+
|
|
148
|
+
### 2.0 - 2.3
|
|
149
|
+
|
|
150
|
+
- Introduces components compilation via a typescript plugin. **[API change]**
|
|
151
|
+
- New developement direction: `write less, do more`.
|
|
152
|
+
|
|
153
|
+
### 1.0 - 1.2
|
|
154
|
+
|
|
155
|
+
- Initial version of core library.
|
|
156
|
+
- Developemnt direction: `performance-first`.
|
|
118
157
|
|
|
119
158
|
## Questions
|
|
120
159
|
|
|
121
160
|
If you have questions, feel free to contact the maintainer of the project:
|
|
122
161
|
|
|
123
162
|
* [Author's Email](mailto:vas.lixcode@gmail.com)
|
|
124
|
-
* [Author's Telegram](https://t.me/lixcode)
|
|
125
|
-
|
|
126
|
-
<hr>
|
|
127
|
-
|
|
128
|
-
**Made in Moldova** 🇲🇩
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { App, Portal } from "../node/app.js";
|
|
2
|
+
import { SwitchedNode } from "../node/node.js";
|
|
3
|
+
import { Watch } from "../node/watch.js";
|
|
4
|
+
import { provideId, toDevIdOrValue, toDevObject, toDevValue, } from "./inspectable.js";
|
|
5
|
+
import { DevFragment } from "./node.js";
|
|
6
|
+
export class DevWatch extends Watch {
|
|
7
|
+
constructor(input, runner, usage) {
|
|
8
|
+
super(input, runner);
|
|
9
|
+
const id = provideId();
|
|
10
|
+
runner.inspector.createComponent({
|
|
11
|
+
id: id,
|
|
12
|
+
usage: usage,
|
|
13
|
+
name: "Watch",
|
|
14
|
+
props: toDevObject(input),
|
|
15
|
+
time: Date.now(),
|
|
16
|
+
});
|
|
17
|
+
this.runOnDestroy(() => {
|
|
18
|
+
runner.inspector.destroy({ id, time: Date.now() });
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
export class DevApp extends App {
|
|
23
|
+
constructor(node, runner) {
|
|
24
|
+
super(node, runner);
|
|
25
|
+
const id = provideId();
|
|
26
|
+
runner.inspector.createComponent({
|
|
27
|
+
id: id,
|
|
28
|
+
name: "App",
|
|
29
|
+
props: {},
|
|
30
|
+
time: Date.now(),
|
|
31
|
+
});
|
|
32
|
+
this.runOnDestroy(() => {
|
|
33
|
+
runner.inspector.destroy({ id, time: Date.now() });
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
export class DevPortal extends Portal {
|
|
38
|
+
id;
|
|
39
|
+
constructor(input, runner, declaration, usage, name) {
|
|
40
|
+
super(input, runner);
|
|
41
|
+
const id = (this.id = provideId());
|
|
42
|
+
runner.inspector.createComponent({
|
|
43
|
+
id: id,
|
|
44
|
+
name: name ?? "Portal",
|
|
45
|
+
props: {},
|
|
46
|
+
declaration: declaration,
|
|
47
|
+
usage: usage,
|
|
48
|
+
time: Date.now(),
|
|
49
|
+
});
|
|
50
|
+
this.runOnDestroy(() => {
|
|
51
|
+
runner.inspector.destroy({ id, time: Date.now() });
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
export class DevSwitchedNode extends SwitchedNode {
|
|
56
|
+
id;
|
|
57
|
+
constructor(usage, runner, cases, _default) {
|
|
58
|
+
super(runner, cases, _default);
|
|
59
|
+
const id = provideId();
|
|
60
|
+
const conditions = {};
|
|
61
|
+
cases.forEach((_case, index) => {
|
|
62
|
+
conditions[index] = _case.slot === _default ? toDevValue(true) : toDevIdOrValue(_case.$case);
|
|
63
|
+
});
|
|
64
|
+
this.id = id;
|
|
65
|
+
runner.inspector.createComponent({
|
|
66
|
+
id: id,
|
|
67
|
+
name: "Switch",
|
|
68
|
+
props: conditions,
|
|
69
|
+
usage: usage,
|
|
70
|
+
time: Date.now(),
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
destroy() {
|
|
74
|
+
this.runner.inspector.destroy({ id: this.id, time: Date.now() });
|
|
75
|
+
super.destroy();
|
|
76
|
+
}
|
|
77
|
+
newChild(index) {
|
|
78
|
+
const frag = new DevFragment(this.runner, null, null, "Case", { index });
|
|
79
|
+
this.runner.inspector.setElementParent({ parent: this.id, child: frag.id });
|
|
80
|
+
return frag;
|
|
81
|
+
}
|
|
82
|
+
}
|
package/lib/dev/core.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Reactive } from "../core/core.js";
|
|
2
|
+
import { provideId } from "./inspectable.js";
|
|
3
|
+
export class DevReactive extends Reactive {
|
|
4
|
+
id;
|
|
5
|
+
runner;
|
|
6
|
+
constructor(runner) {
|
|
7
|
+
super();
|
|
8
|
+
this.id = provideId();
|
|
9
|
+
this.runner = runner;
|
|
10
|
+
}
|
|
11
|
+
destroy() {
|
|
12
|
+
this.runner.inspector.destroy({ id: this.id, time: Date.now() });
|
|
13
|
+
super.destroy();
|
|
14
|
+
}
|
|
15
|
+
}
|
package/lib/dev/index.js
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { DevReactive } from "./core.js";
|
|
2
|
+
export { DevApp, DevPortal, DevSwitchedNode, DevWatch } from "./components.js";
|
|
3
|
+
export { executionPosition, provideId, runFn, wrapFn, registerReference, toDevId, toDevIdOrValue, toDevObject, toDevValue, } from "./inspectable.js";
|
|
4
|
+
export { DevArrayModel, DevMapModel, DevSetModel } from "./models.js";
|
|
5
|
+
export { DevFragment, ModelId, shareStateById } from "./node.js";
|
|
6
|
+
export { DevRunner, PositionedText, positionedText, remapObject, DevTextNode, DevTag, } from "./runner.js";
|
|
7
|
+
export { BaseDevReference, DevExpression, DevIValue, DevReference, ExpressionDevReference, } from "./state.js";
|
|
8
|
+
export { DevArrayView, DevMapView, DevSetView } from "./views.js";
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { DevExpression, DevReference } from "./state.js";
|
|
2
|
+
let positionId = 1;
|
|
3
|
+
function getErrorStack(error) {
|
|
4
|
+
return (error.stack
|
|
5
|
+
?.split("\n")
|
|
6
|
+
.slice(1)
|
|
7
|
+
.map(line => line.trim()) ?? []);
|
|
8
|
+
}
|
|
9
|
+
export function executionPosition(inspector, pathLineAndChar, error) {
|
|
10
|
+
const id = positionId++;
|
|
11
|
+
inspector.registerExecutionPosition({
|
|
12
|
+
id: id,
|
|
13
|
+
position: pathLineAndChar,
|
|
14
|
+
stack: getErrorStack(error),
|
|
15
|
+
});
|
|
16
|
+
return id;
|
|
17
|
+
}
|
|
18
|
+
let id = 0;
|
|
19
|
+
export function provideId() {
|
|
20
|
+
return id++;
|
|
21
|
+
}
|
|
22
|
+
const primitiveTypes = ["number", "string", "boolean"];
|
|
23
|
+
export function registerReference(value, declaration, inspector) {
|
|
24
|
+
inspector.newReference({
|
|
25
|
+
id: value.id,
|
|
26
|
+
value: toDevValue(value.V),
|
|
27
|
+
declaration: declaration,
|
|
28
|
+
time: Date.now(),
|
|
29
|
+
});
|
|
30
|
+
return value;
|
|
31
|
+
}
|
|
32
|
+
let executionId = 0;
|
|
33
|
+
export function wrapFn(fn, declaration, inspector) {
|
|
34
|
+
return (...args) => {
|
|
35
|
+
return runFn(fn, args, declaration, inspector);
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
export function runFn(fn, args, declaration, inspector) {
|
|
39
|
+
const id = ++executionId;
|
|
40
|
+
inspector.functionCall({
|
|
41
|
+
id: id,
|
|
42
|
+
position: declaration,
|
|
43
|
+
args: args.map(toDevValue),
|
|
44
|
+
time: Date.now(),
|
|
45
|
+
});
|
|
46
|
+
try {
|
|
47
|
+
let result = fn(...args);
|
|
48
|
+
if (result instanceof Promise) {
|
|
49
|
+
return new Promise((resolve, reject) => {
|
|
50
|
+
result.then(result => {
|
|
51
|
+
inspector.functionReturn({
|
|
52
|
+
id: id,
|
|
53
|
+
result: toDevValue(result),
|
|
54
|
+
async: true,
|
|
55
|
+
time: Date.now(),
|
|
56
|
+
});
|
|
57
|
+
resolve(result);
|
|
58
|
+
});
|
|
59
|
+
result.catch(e => {
|
|
60
|
+
inspector.functionThrows({
|
|
61
|
+
targetId: id,
|
|
62
|
+
error: e instanceof Error ? (e.stack ?? e.message) : `${e}`,
|
|
63
|
+
async: false,
|
|
64
|
+
time: Date.now(),
|
|
65
|
+
});
|
|
66
|
+
reject(e);
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
inspector.functionReturn({
|
|
72
|
+
id: id,
|
|
73
|
+
result: toDevValue(result),
|
|
74
|
+
async: false,
|
|
75
|
+
time: Date.now(),
|
|
76
|
+
});
|
|
77
|
+
return result;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
catch (e) {
|
|
81
|
+
inspector.functionThrows({
|
|
82
|
+
targetId: id,
|
|
83
|
+
error: e instanceof Error ? (e.stack ?? e.message) : `${e}`,
|
|
84
|
+
async: false,
|
|
85
|
+
time: Date.now(),
|
|
86
|
+
});
|
|
87
|
+
throw e;
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
export function toDevValue(value) {
|
|
91
|
+
const type = typeof value;
|
|
92
|
+
return {
|
|
93
|
+
type: type,
|
|
94
|
+
value: primitiveTypes.includes(type) || value === null ? JSON.stringify(value) : undefined,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
export function toDevId(value) {
|
|
98
|
+
if (value instanceof DevReference || value instanceof DevExpression) {
|
|
99
|
+
return value.id;
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
export function toDevIdOrValue(value) {
|
|
104
|
+
return toDevId(value) ?? toDevValue(value);
|
|
105
|
+
}
|
|
106
|
+
export function toDevObject(value) {
|
|
107
|
+
return Object.entries(value).reduce((obj, [prop, value]) => {
|
|
108
|
+
return {
|
|
109
|
+
...obj,
|
|
110
|
+
[prop]: toDevIdOrValue(value),
|
|
111
|
+
};
|
|
112
|
+
}, {});
|
|
113
|
+
}
|
|
@@ -0,0 +1,147 @@
|
|
|
1
|
+
import { ArrayModel } from "../models/array-model.js";
|
|
2
|
+
import { MapModel } from "../models/map-model.js";
|
|
3
|
+
import { SetModel } from "../models/set-model.js";
|
|
4
|
+
import { provideId, toDevValue } from "./inspectable.js";
|
|
5
|
+
export class DevArrayModel extends ArrayModel {
|
|
6
|
+
id;
|
|
7
|
+
inspector;
|
|
8
|
+
constructor(inspector, usage, data, ctx) {
|
|
9
|
+
super(data, ctx);
|
|
10
|
+
this.id = provideId();
|
|
11
|
+
this.inspector = inspector;
|
|
12
|
+
if (inspector) {
|
|
13
|
+
const values = [];
|
|
14
|
+
for (let i = 0; i < this.length; i++) {
|
|
15
|
+
values.push([toDevValue(i), toDevValue(this[i])]);
|
|
16
|
+
}
|
|
17
|
+
inspector.createModel({
|
|
18
|
+
id: this.id,
|
|
19
|
+
type: "array",
|
|
20
|
+
values: values,
|
|
21
|
+
usage: usage,
|
|
22
|
+
time: Date.now(),
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
destroy() {
|
|
27
|
+
this.inspector?.destroy({ id: this.id, time: Date.now() });
|
|
28
|
+
super.destroy();
|
|
29
|
+
}
|
|
30
|
+
fill(value, start, end) {
|
|
31
|
+
this.shareChange("fill", [value, start, end], undefined);
|
|
32
|
+
return super.fill(value, start, end);
|
|
33
|
+
}
|
|
34
|
+
pop() {
|
|
35
|
+
const result = super.pop();
|
|
36
|
+
this.shareChange("pop", [], result);
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
push(...items) {
|
|
40
|
+
const result = super.push(...items);
|
|
41
|
+
this.shareChange("push", items, result);
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
shift() {
|
|
45
|
+
const result = super.shift();
|
|
46
|
+
this.shareChange("shift", [], result);
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
splice(start, deleteCount, ...items) {
|
|
50
|
+
this.shareChange("splice", [start, deleteCount, ...items], undefined);
|
|
51
|
+
return super.splice(start, deleteCount, ...items);
|
|
52
|
+
}
|
|
53
|
+
unshift(...items) {
|
|
54
|
+
const result = super.unshift(...items);
|
|
55
|
+
this.shareChange("unshift", items, result);
|
|
56
|
+
return result;
|
|
57
|
+
}
|
|
58
|
+
shareChange(method, args, result) {
|
|
59
|
+
this.inspector?.updateModel({
|
|
60
|
+
id: this.id,
|
|
61
|
+
method: method,
|
|
62
|
+
args: args.map(toDevValue),
|
|
63
|
+
return: toDevValue(result),
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
export class DevSetModel extends SetModel {
|
|
68
|
+
id;
|
|
69
|
+
inspector;
|
|
70
|
+
constructor(inspector, usage, set, ctx) {
|
|
71
|
+
super(set, ctx);
|
|
72
|
+
this.id = provideId();
|
|
73
|
+
this.inspector = inspector;
|
|
74
|
+
inspector?.createModel({
|
|
75
|
+
id: this.id,
|
|
76
|
+
type: "set",
|
|
77
|
+
values: [...this].map(item => [toDevValue(0), toDevValue(item)]),
|
|
78
|
+
usage: usage,
|
|
79
|
+
time: Date.now(),
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
destroy() {
|
|
83
|
+
this.inspector?.destroy({ id: this.id, time: Date.now() });
|
|
84
|
+
super.destroy();
|
|
85
|
+
}
|
|
86
|
+
add(value) {
|
|
87
|
+
this.shareChange("add", [value], undefined);
|
|
88
|
+
return super.add(value);
|
|
89
|
+
}
|
|
90
|
+
clear() {
|
|
91
|
+
this.shareChange("clear", [], undefined);
|
|
92
|
+
return super.clear();
|
|
93
|
+
}
|
|
94
|
+
delete(value) {
|
|
95
|
+
const result = super.delete(value);
|
|
96
|
+
this.shareChange("delete", [value], result);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
shareChange(method, args, result) {
|
|
100
|
+
this.inspector?.updateModel({
|
|
101
|
+
id: this.id,
|
|
102
|
+
method: method,
|
|
103
|
+
args: args.map(toDevValue),
|
|
104
|
+
return: toDevValue(result),
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
export class DevMapModel extends MapModel {
|
|
109
|
+
id;
|
|
110
|
+
inspector;
|
|
111
|
+
constructor(inspector, usage, map, ctx) {
|
|
112
|
+
super(map, ctx);
|
|
113
|
+
this.id = provideId();
|
|
114
|
+
this.inspector = inspector;
|
|
115
|
+
inspector?.createModel({
|
|
116
|
+
id: this.id,
|
|
117
|
+
type: "map",
|
|
118
|
+
values: [...this.entries()].map(([key, value]) => [toDevValue(key), toDevValue(value)]),
|
|
119
|
+
usage: usage,
|
|
120
|
+
time: Date.now(),
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
destroy() {
|
|
124
|
+
this.inspector?.destroy({ id: this.id, time: Date.now() });
|
|
125
|
+
}
|
|
126
|
+
clear() {
|
|
127
|
+
this.shareChange("clear", [], undefined);
|
|
128
|
+
super.clear();
|
|
129
|
+
}
|
|
130
|
+
delete(key) {
|
|
131
|
+
const result = super.delete(key);
|
|
132
|
+
this.shareChange("delete", [key], result);
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
set(key, value) {
|
|
136
|
+
this.shareChange("set", [key, value], undefined);
|
|
137
|
+
return super.set(key, value);
|
|
138
|
+
}
|
|
139
|
+
shareChange(method, args, result) {
|
|
140
|
+
this.inspector?.updateModel({
|
|
141
|
+
id: this.id,
|
|
142
|
+
method: method,
|
|
143
|
+
args: args.map(toDevValue),
|
|
144
|
+
return: toDevValue(result),
|
|
145
|
+
});
|
|
146
|
+
}
|
|
147
|
+
}
|
package/lib/dev/node.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { Fragment } from "../node/node.js";
|
|
2
|
+
import { provideId, toDevObject, } from "./inspectable.js";
|
|
3
|
+
import { DevArrayModel, DevMapModel, DevSetModel } from "./models.js";
|
|
4
|
+
import { DevExpression, DevReference } from "./state.js";
|
|
5
|
+
export const ModelId = Symbol("model-id");
|
|
6
|
+
export function shareStateById(id, runner, name, value) {
|
|
7
|
+
const inspector = runner.inspector;
|
|
8
|
+
if (value instanceof DevReference ||
|
|
9
|
+
value instanceof DevExpression ||
|
|
10
|
+
value instanceof DevArrayModel ||
|
|
11
|
+
value instanceof DevSetModel ||
|
|
12
|
+
value instanceof DevMapModel) {
|
|
13
|
+
inspector.addContextState({
|
|
14
|
+
id: id ?? 0,
|
|
15
|
+
name: name,
|
|
16
|
+
stateId: value.id,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
else if (value && typeof value == "object" && ModelId in value) {
|
|
20
|
+
inspector.addContextState({
|
|
21
|
+
id: id ?? 0,
|
|
22
|
+
name: name,
|
|
23
|
+
stateId: value[ModelId],
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
export class DevFragment extends Fragment {
|
|
29
|
+
id;
|
|
30
|
+
declaration;
|
|
31
|
+
inspector;
|
|
32
|
+
constructor(runner, declaration, usage, name, props) {
|
|
33
|
+
super(runner);
|
|
34
|
+
this.id = provideId();
|
|
35
|
+
this.declaration = declaration;
|
|
36
|
+
this.inspector = runner.inspector;
|
|
37
|
+
runner.inspector.createComponent({
|
|
38
|
+
id: this.id,
|
|
39
|
+
declaration: declaration,
|
|
40
|
+
usage: usage,
|
|
41
|
+
name: name,
|
|
42
|
+
props: toDevObject(props),
|
|
43
|
+
time: Date.now(),
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
destroy() {
|
|
47
|
+
this.inspector.destroy({ id: this.id, time: Date.now() });
|
|
48
|
+
super.destroy();
|
|
49
|
+
}
|
|
50
|
+
pushNode(node) {
|
|
51
|
+
if ("id" in node && typeof node.id == "number") {
|
|
52
|
+
this.inspector.setElementParent({
|
|
53
|
+
parent: this.id,
|
|
54
|
+
child: node.id,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
super.pushNode(node);
|
|
58
|
+
}
|
|
59
|
+
}
|