babel-plugin-vasille 4.3.2 → 5.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 CHANGED
@@ -1,19 +1,30 @@
1
- # Vasille
1
+ # Steel Frame
2
2
 
3
- ![Vasille.js logo](https://raw.githubusercontent.com/vasille-js/vasille-js/refs/heads/v4/doc/img/logo.png)
3
+ ![Vasille.js logo](https://raw.githubusercontent.com/vasille-js/vasille-js/refs/heads/v5/doc/img/logo.png)
4
4
 
5
- `Vasille Web` is a front-end framework, which is developed to provide bulletproof frontends.
5
+ `SteelFrameKit` is a front-end development kit, which is developed to provide bulletproof frontends.
6
6
 
7
7
  [![npm](https://img.shields.io/npm/v/vasille?style=flat-square)](https://www.npmjs.com/package/vasille)
8
8
 
9
9
  ## Table of content
10
10
 
11
- * [Installation](#installation)
12
- * [How to use Vasille](#how-to-use-vasille)
13
- * [How SAFE is Vasille](#how-safe-is-vasille)
14
- * [How INTUITIVE is Vasille](#how-intuitive-is-vasille)
15
- * [How POWERFUL is Vasille](#how-powerful-is-vasille)
16
- * [Road Map](#road-map)
11
+ - [Steel Frame](#steel-frame)
12
+ - [Table of content](#table-of-content)
13
+ - [Installation](#installation)
14
+ - [How to use SteelFramekit](#how-to-use-steelframekit)
15
+ - [Full documentation:](#full-documentation)
16
+ - [Examples](#examples)
17
+ - [How SAFE is SteelFrameKit](#how-safe-is-steelframekit)
18
+ - [How INTUITIVE is SteelFrameKit](#how-intuitive-is-steelframekit)
19
+ - [How POWERFUL is SteelFrameKit](#how-powerful-is-steelframekit)
20
+ - [Road map](#road-map)
21
+ - [Change log](#change-log)
22
+ - [5.0.0](#500)
23
+ - [4.3.0](#430)
24
+ - [4.2.0](#420)
25
+ - [4.1.0](#410)
26
+ - [4.0.0](#400)
27
+ - [Questions](#questions)
17
28
 
18
29
 
19
30
  <hr>
@@ -21,21 +32,22 @@
21
32
  ## Installation
22
33
 
23
34
  ```
24
- npm install vasille-web --save
35
+ npm install steel-frame --save
25
36
  ```
26
37
 
27
- ## How to use Vasille
38
+ ## How to use SteelFramekit
28
39
 
29
40
  Create an app from a template
30
41
 
31
42
  ```bash
32
- $ npm create vasille
43
+ $ npm create steel-frame
33
44
  ```
34
45
 
35
46
  ### Full documentation:
36
- * [Learn `Vasille` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v4/doc/V4-API.md)
37
- * [Vasille Router Documentation](https://github.com/vasille-js/vasille-js/blob/v4/doc/Router-API.md)
38
- * [Vasille Compostion function](https://github.com/vasille-js/vasille-js/blob/v4/doc/Compositions.md)
47
+ * [Learn `SteelFrameKit` in 5 minutes](https://github.com/vasille-js/vasille-js/blob/v5/doc/V4-API.md)
48
+ * [Router Documentation](https://github.com/vasille-js/vasille-js/blob/v5/doc/Router-API.md)
49
+ * [Compostion functions](https://github.com/vasille-js/vasille-js/blob/v5/doc/Compositions.md)
50
+ * [Dependency injection](https://github.com/vasille-js/vasille-js/blob/v5/doc/Context.md)
39
51
 
40
52
  ### Examples
41
53
  * [TypeScript Example](https://github.com/vasille-js/example-typescript)
@@ -43,14 +55,14 @@ $ npm create vasille
43
55
 
44
56
  <hr>
45
57
 
46
- ## How SAFE is Vasille
58
+ ## How SAFE is SteelFrameKit
47
59
 
48
60
  The safe of your application is ensured by
49
61
  * `100%` coverage of code by unit tests.
50
62
  Each function, each branch is working as designed.
51
63
  * OOP, DRY, KISS and SOLID principles are applied.
52
64
  * `strong typing` makes your javascript/typescript code safe as C++ code.
53
- All entities of `vasille` core library are strongly typed, including:
65
+ All entities of `SteelFrameKit` core library are strongly typed, including:
54
66
  * data fields & properties.
55
67
  * computed properties (function parameters and result).
56
68
  * methods.
@@ -60,11 +72,11 @@ All entities of `vasille` core library are strongly typed, including:
60
72
  * references to children.
61
73
  * No asynchronous code, when the line of code is executed, the DOM and reactive things are already synced.
62
74
 
63
- ## How INTUITIVE is Vasille
75
+ ## How INTUITIVE is SteelFrameKit
64
76
 
65
77
  There is the "Hello World":
66
78
  ```typescript jsx
67
- import { compose, mount } from "vasille-dx";
79
+ import { compose, mount } from "steel-frame";
68
80
 
69
81
  const App = compose(() => {
70
82
  <p>Hello world</p>;
@@ -73,7 +85,7 @@ const App = compose(() => {
73
85
  mount(document.body, App, {});
74
86
  ```
75
87
 
76
- ## How POWERFUL is Vasille
88
+ ## How POWERFUL is SteelFrameKit
77
89
 
78
90
  All of these are supported:
79
91
  * Components.
@@ -85,25 +97,30 @@ All of these are supported:
85
97
  * 2-way data binding in components.
86
98
  * Logic block (if, else).
87
99
  * Loops (array, map, set).
100
+ * Dependency injection.
88
101
 
89
102
  <hr>
90
103
 
91
104
  ## Road map
92
105
 
93
- * [x] Update the `Vasille Core` library to version 3.0.
106
+ * [x] Update the `core` library to version 3.0.
94
107
  * [x] `100%` Test Coverage for core Library v3.
95
- * [x] Develop the `Vasille JSX` library.
108
+ * [x] Develop the `JSX` library.
96
109
  * [x] `100%` Test Coverage for the JSX library.
97
- * [x] Develop the `Vasille Babel Plugin`.
110
+ * [x] Develop the `Babel Plugin`.
98
111
  * [x] `100%` Test Coverage fot babel plugin.
99
112
  * [x] Add CSS support (define styles in components).
100
113
  * [x] Add router.
101
114
  * [x] Add SSG (static site generation).
115
+ * [ ] Develop tools extension for debugging (WIP).
102
116
  * [ ] Add SSR (server side rendering).
103
- * [ ] Develop tools extension for debugging.
104
117
 
105
118
  ## Change log
106
119
 
120
+ ### 5.0.0
121
+
122
+ Add support for context and dependencies injection.
123
+
107
124
  ### 4.3.0
108
125
 
109
126
  Add new function `safe` which make functions safe, errors are reported automatically.
@@ -114,19 +131,14 @@ Add support for inlined conditions in JSX, binary `&&` and ternary `?:` operator
114
131
 
115
132
  ### 4.1.0
116
133
 
117
- Added SSG (static site generation) as build option `vasille-web build static`.
134
+ Added SSG (static site generation) as build option `sf build static`.
118
135
 
119
136
  ### 4.0.0
120
137
 
121
- Initial version of the framework with file based routing and building scripts (`vasille-web dev` and `vasille-web build spa`).
138
+ Initial version of the framework with file based routing and building scripts (`sf dev` and `sf build spa`).
122
139
 
123
140
  ## Questions
124
141
 
125
142
  If you have questions, feel free to contact the maintainer of the project:
126
143
 
127
144
  * [Author's Email](mailto:vas.lixcode@gmail.com)
128
- * [Author's Telegram](https://t.me/lixcode)
129
-
130
- <hr>
131
-
132
- **Made in Moldova** 🇲🇩
package/lib/call.js CHANGED
@@ -33,7 +33,7 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.hintFunctions = exports.styleOnly = exports.composeOnly = exports.boundaryFunctions = exports.modelFunctions = exports.bindFunctions = exports.reactivityFunctions = exports.composeFunctions = void 0;
36
+ exports.hintFunctions = exports.dependencyInjections = exports.styleOnly = exports.composeOnly = exports.modelFunctions = exports.bindFunctions = exports.asyncFunctions = exports.refFunctions = exports.composeFunctions = void 0;
37
37
  exports.calls = calls;
38
38
  const t = __importStar(require("@babel/types"));
39
39
  exports.composeFunctions = [
@@ -47,10 +47,10 @@ exports.composeFunctions = [
47
47
  "prompt",
48
48
  "screen",
49
49
  ];
50
- exports.reactivityFunctions = ["ref", "awaited"];
50
+ exports.refFunctions = ["ref"];
51
+ exports.asyncFunctions = ["awaited"];
51
52
  exports.bindFunctions = ["watch", "calculate", "bind"];
52
53
  exports.modelFunctions = ["arrayModel", "mapModel", "setModel"];
53
- exports.boundaryFunctions = ["forward", "backward"];
54
54
  exports.composeOnly = ["router", "beforeMount", "afterMount", "beforeDestroy"];
55
55
  exports.styleOnly = [
56
56
  "theme",
@@ -62,14 +62,17 @@ exports.styleOnly = [
62
62
  "prefersLight",
63
63
  "styleSheet",
64
64
  ];
65
+ exports.dependencyInjections = ["share", "receive", "impute"];
65
66
  exports.hintFunctions = [
66
- ...exports.reactivityFunctions,
67
+ ...exports.refFunctions,
68
+ ...exports.asyncFunctions,
67
69
  ...exports.composeFunctions,
68
70
  ...exports.bindFunctions,
69
71
  ...exports.modelFunctions,
70
72
  ...exports.composeOnly,
71
73
  ...exports.styleOnly,
72
- ...exports.boundaryFunctions,
74
+ ...exports.dependencyInjections,
75
+ "raw",
73
76
  ];
74
77
  function checkCall(name, internal) {
75
78
  if (name === "store" || name === "model") {
package/lib/expression.js CHANGED
@@ -33,9 +33,9 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.encodeName = encodeName;
37
36
  exports.idIsIValue = idIsIValue;
38
37
  exports.memberIsIValue = memberIsIValue;
38
+ exports.memberIsIValueInExpr = memberIsIValueInExpr;
39
39
  exports.exprIsSure = exprIsSure;
40
40
  exports.checkNode = checkNode;
41
41
  exports.checkOrIgnoreAllExpressions = checkOrIgnoreAllExpressions;
@@ -48,48 +48,40 @@ exports.checkStatement = checkStatement;
48
48
  exports.checkFunction = checkFunction;
49
49
  const t = __importStar(require("@babel/types"));
50
50
  const call_js_1 = require("./call.js");
51
+ const internal_js_1 = require("./internal.js");
51
52
  const lib_1 = require("./lib");
52
53
  const mesh_1 = require("./mesh");
53
54
  const router_1 = require("./router");
54
55
  const utils_1 = require("./utils");
55
- function encodeName(name) {
56
- return insertName(name);
57
- }
58
56
  function insertName(name, search) {
59
- const id = t.identifier(`Vasille_${name}`);
57
+ const id = t.identifier(name);
60
58
  search?.inserted.add(id);
61
59
  return id;
62
60
  }
63
- function addIdentifier(path, search) {
64
- const name = unprefixedName(path.node.name);
65
- if (!search.found.has(name)) {
66
- search.found.set(name, path.node);
67
- }
68
- path.replaceWith(insertName(name, search));
69
- }
70
- function unprefixedName(name) {
71
- return name[0] === "$" ? name.slice(1) : name;
72
- }
73
- function extractMemberName(path, search) {
74
- const names = [];
75
- let it = path.node;
76
- while (t.isMemberExpression(it)) {
77
- names.push((0, utils_1.stringify)(it.property));
78
- it = it.object;
61
+ function addExpression(path, search) {
62
+ const name = path
63
+ .getSource()
64
+ .trim()
65
+ .replace(/\s*\n\s*/g, "");
66
+ const found = search.found.get(name);
67
+ if (path.isMemberExpression()) {
68
+ let it = path.node;
69
+ while (t.isMemberExpression(it) || t.isIdentifier(it)) {
70
+ const name = (0, utils_1.stringify)(t.isMemberExpression(it) ? it.property : it);
71
+ if (it !== path.node && name.startsWith("$")) {
72
+ (0, lib_1.err)(lib_1.Errors.RulesOfVasille, path, "The reactive/observable value is nested", search.external, null);
73
+ }
74
+ it = t.isMemberExpression(it) ? it.object : null;
75
+ }
79
76
  }
80
- names.push((0, utils_1.stringify)(it));
81
- if (names.filter(name => name.startsWith("$")).length > 1) {
82
- (0, lib_1.err)(lib_1.Errors.RulesOfVasille, path, "The reactive/observable value is nested", search.external, null);
77
+ if (!found) {
78
+ const paramName = insertName(`Vasille_${search.found.size}`, search);
79
+ search.found.set(name, { node: path.node, paramName: paramName });
80
+ path.replaceWith(paramName);
83
81
  }
84
- return names.reverse().map(unprefixedName).join("_");
85
- }
86
- function addMemberExpr(path, search) {
87
- const name = extractMemberName(path, search);
88
- /* istanbul ignore else */
89
- if (!search.found.has(name)) {
90
- search.found.set(name, path.node);
82
+ else {
83
+ path.replaceWith(found.paramName);
91
84
  }
92
- path.replaceWith(insertName(name, search));
93
85
  }
94
86
  function meshIdentifier(path) {
95
87
  if (idIsIValue(path)) {
@@ -104,10 +96,25 @@ function memberIsIValue(node) {
104
96
  return ((t.isIdentifier(node.property) && node.property.name.startsWith("$")) ||
105
97
  (t.isStringLiteral(node.property) && node.property.value.startsWith("$")));
106
98
  }
99
+ function memberIsIValueInExpr(path, search) {
100
+ const node = path.node;
101
+ const isIValue = memberIsIValue(node);
102
+ if (isIValue) {
103
+ let it = node;
104
+ while (t.isMemberExpression(it) || t.isOptionalMemberExpression(it)) {
105
+ it = it.object;
106
+ }
107
+ if (t.isIdentifier(it) && search.stack.get(it.name, true)) {
108
+ (0, lib_1.err)(lib_1.Errors.RulesOfVasille, path, "This value looks like a reactive but is not. Move code to standalone function or wrap value in raw call.", search.external);
109
+ }
110
+ }
111
+ return isIValue;
112
+ }
107
113
  function exprIsSure(path, internal) {
108
- if (path.isMemberExpression() &&
114
+ if ((path.isMemberExpression() &&
109
115
  path.node.computed &&
110
- (!t.isStringLiteral(path.node.property) || /^\d+$/.test(path.node.property.value))) {
116
+ (!t.isStringLiteral(path.node.property) || /^\d+$/.test(path.node.property.value))) ||
117
+ path.isOptionalMemberExpression()) {
111
118
  return false;
112
119
  }
113
120
  if (!path.isMemberExpression() || !(0, utils_1.stringify)(path.node.property).startsWith("$")) {
@@ -152,7 +159,7 @@ function meshLValue(path, internal) {
152
159
  meshLValue(path.get("argument"), internal);
153
160
  }
154
161
  }
155
- function checkNode(path, internal) {
162
+ function checkNode(path, internal, area, name) {
156
163
  const search = {
157
164
  external: internal,
158
165
  found: new Map(),
@@ -165,19 +172,21 @@ function checkNode(path, internal) {
165
172
  search.self = path.node;
166
173
  }
167
174
  }
168
- if (path.isMemberExpression()) {
175
+ if (path.isMemberExpression() || path.isOptionalMemberExpression()) {
169
176
  if (memberIsIValue(path.node)) {
170
177
  search.self = path.node;
171
178
  }
172
179
  }
173
180
  if (path.isExpression() && (0, call_js_1.calls)(path, ["ref"], internal)) {
181
+ const refValue = path.node.arguments[0];
174
182
  (0, mesh_1.meshAllUnknown)(path.get("arguments"), internal);
183
+ path.replaceWith((0, lib_1.ref)(refValue, internal, area, name));
175
184
  search.self = path.node;
176
185
  }
177
186
  if (search.self) {
178
187
  return search;
179
188
  }
180
- internal.stack.push();
189
+ internal.stack.push(true);
181
190
  /* istanbul ignore else */
182
191
  if (path.isExpression()) {
183
192
  checkExpression(path, search);
@@ -233,7 +242,7 @@ function checkExpression(nodePath, search) {
233
242
  /* istanbul ignore else */
234
243
  if (expr && nodePath.isIdentifier()) {
235
244
  if (idIsIValue(nodePath)) {
236
- addIdentifier(nodePath, search);
245
+ addExpression(nodePath, search);
237
246
  }
238
247
  }
239
248
  break;
@@ -253,6 +262,16 @@ function checkExpression(nodePath, search) {
253
262
  (0, lib_1.err)(lib_1.Errors.IncompatibleContext, path, "The router is not available in stores", search.external, null);
254
263
  }
255
264
  }
265
+ else if ((0, call_js_1.calls)(path, ["raw"], search.external) &&
266
+ path.node.arguments.length === 1 &&
267
+ t.isExpression(path.node.arguments[0])) {
268
+ (0, mesh_1.meshExpression)(path.get("arguments")[0], search.external);
269
+ path.replaceWith(path.node.arguments[0]);
270
+ }
271
+ else if (!search.external.stateOnly && (0, call_js_1.calls)(path, call_js_1.dependencyInjections, search.external)) {
272
+ (0, mesh_1.meshAllUnknown)(path.get("arguments"), search.external);
273
+ path.node.arguments.unshift(internal_js_1.ctx);
274
+ }
256
275
  else {
257
276
  if ((0, call_js_1.calls)(path, call_js_1.hintFunctions, search.external)) {
258
277
  (0, lib_1.err)(lib_1.Errors.IncompatibleContext, path, "Usage of hints is restricted here", search.external, null);
@@ -278,7 +297,7 @@ function checkExpression(nodePath, search) {
278
297
  checkExpression(right, search);
279
298
  /* istanbul ignore else */
280
299
  if (!t.isPrivateName(property)) {
281
- path.replaceWith(search.external.set(left.node.object, !left.node.computed && t.isIdentifier(property) ? t.stringLiteral(property.name) : property, right.node));
300
+ path.replaceWith(search.external.set(left.node.object, !left.node.computed && t.isIdentifier(property) ? t.stringLiteral(property.name) : property, right.node, path.node));
282
301
  }
283
302
  }
284
303
  else {
@@ -290,9 +309,8 @@ function checkExpression(nodePath, search) {
290
309
  case "MemberExpression":
291
310
  case "OptionalMemberExpression": {
292
311
  const path = nodePath;
293
- const node = path.node;
294
- if (memberIsIValue(node)) {
295
- addMemberExpr(path, search);
312
+ if (memberIsIValueInExpr(path, search)) {
313
+ addExpression(path, search);
296
314
  }
297
315
  else {
298
316
  checkExpression(path.get("object"), search);
package/lib/index.js CHANGED
@@ -8,7 +8,7 @@ function default_1() {
8
8
  visitor: {
9
9
  Program(path, params) {
10
10
  (0, transformer_js_1.transformProgram)(path, params.file.opts.filename, {
11
- devMode: params.opts.devMode !== false,
11
+ devLayer: params.opts.devLayer === true,
12
12
  strictFolders: params.opts.strictFolders !== false,
13
13
  replaceWeb: typeof params.opts.replaceWeb === "string" ? params.opts.replaceWeb : undefined,
14
14
  headTag: !!params.opts.headTag,
package/lib/internal.js CHANGED
@@ -33,21 +33,25 @@ var __importStar = (this && this.__importStar) || (function () {
33
33
  };
34
34
  })();
35
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
- exports.ctx = exports.StackedStates = void 0;
36
+ exports.inspector = exports.runner = exports.ctx = exports.StackedStates = void 0;
37
37
  const t = __importStar(require("@babel/types"));
38
38
  class StackedStates {
39
39
  maps = [];
40
+ checkingIndex = 0;
40
41
  constructor() {
41
42
  this.push();
42
43
  }
43
- push() {
44
+ push(startChecking) {
45
+ if (startChecking) {
46
+ this.checkingIndex = this.maps.length;
47
+ }
44
48
  this.maps.push(new Map());
45
49
  }
46
50
  pop() {
47
51
  this.maps.pop();
48
52
  }
49
- get(name) {
50
- for (let i = this.maps.length - 1; i >= 0; i--) {
53
+ get(name, checkingContextOnly) {
54
+ for (let i = this.maps.length - 1; i >= (checkingContextOnly ? this.checkingIndex : 0); i--) {
51
55
  if (this.maps[i].has(name)) {
52
56
  return this.maps[i].get(name);
53
57
  }
@@ -60,3 +64,5 @@ class StackedStates {
60
64
  }
61
65
  exports.StackedStates = StackedStates;
62
66
  exports.ctx = t.identifier("Vasille");
67
+ exports.runner = t.memberExpression(exports.ctx, t.identifier("runner"));
68
+ exports.inspector = t.memberExpression(exports.runner, t.identifier("inspector"));