@builder.io/mitosis 0.0.47 → 0.0.50-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 (173) hide show
  1. package/CHANGELOG.md +4 -0
  2. package/dist/src/__tests__/angular.test.d.ts +1 -0
  3. package/dist/src/__tests__/angular.test.js +12 -0
  4. package/dist/src/__tests__/data/blocks/columns.raw.jsx +6 -0
  5. package/dist/src/__tests__/data/blocks/onUpdate.raw.d.ts +1 -0
  6. package/dist/src/__tests__/data/blocks/onUpdate.raw.jsx +10 -0
  7. package/dist/src/__tests__/data/blocks/onUpdateWithDeps.raw.d.ts +1 -0
  8. package/dist/src/__tests__/data/blocks/onUpdateWithDeps.raw.jsx +11 -0
  9. package/dist/src/__tests__/data/blocks/tabs.raw.d.ts +11 -0
  10. package/dist/src/__tests__/data/blocks/tabs.raw.jsx +24 -0
  11. package/dist/src/__tests__/qoot.test.d.ts +1 -0
  12. package/dist/src/__tests__/qoot.test.js +115 -0
  13. package/dist/src/__tests__/qwik.test.js +38 -10
  14. package/dist/src/__tests__/react.test.js +12 -0
  15. package/dist/src/__tests__/svelte.test.d.ts +1 -0
  16. package/dist/src/__tests__/svelte.test.js +12 -0
  17. package/dist/src/__tests__/vue.test.js +6 -0
  18. package/dist/src/generators/angular.js +7 -3
  19. package/dist/src/generators/builder.js +7 -7
  20. package/dist/src/generators/html.js +16 -7
  21. package/dist/src/generators/jsx-lite.d.ts +10 -0
  22. package/dist/src/generators/jsx-lite.js +176 -0
  23. package/dist/src/generators/minify.d.ts +1 -0
  24. package/dist/src/generators/minify.js +24 -0
  25. package/dist/src/generators/mitosis.js +5 -2
  26. package/dist/src/generators/qoot.d.ts +21 -0
  27. package/dist/src/generators/qoot.js +442 -0
  28. package/dist/src/generators/qwik/component.js +48 -6
  29. package/dist/src/generators/qwik/directives.d.ts +21 -1
  30. package/dist/src/generators/qwik/directives.js +80 -3
  31. package/dist/src/generators/qwik/jsx.d.ts +1 -1
  32. package/dist/src/generators/qwik/jsx.js +28 -5
  33. package/dist/src/generators/qwik/src-generator.d.ts +3 -1
  34. package/dist/src/generators/qwik/src-generator.js +34 -10
  35. package/dist/src/generators/qwik.d.ts +21 -0
  36. package/dist/src/generators/qwik.js +458 -0
  37. package/dist/src/generators/react-native.js +57 -41
  38. package/dist/src/generators/react.js +18 -8
  39. package/dist/src/generators/solid.js +5 -2
  40. package/dist/src/generators/svelte.js +10 -5
  41. package/dist/src/generators/vue.js +7 -5
  42. package/dist/src/helpers/create-jsx-lite-component.d.ts +2 -0
  43. package/dist/src/helpers/create-jsx-lite-component.js +16 -0
  44. package/dist/src/helpers/create-jsx-lite-context.d.ts +4 -0
  45. package/dist/src/helpers/create-jsx-lite-context.js +18 -0
  46. package/dist/src/helpers/create-jsx-lite-node.d.ts +2 -0
  47. package/dist/src/helpers/create-jsx-lite-node.js +16 -0
  48. package/dist/src/helpers/is-jsx-lite-node.d.ts +2 -0
  49. package/dist/src/helpers/is-jsx-lite-node.js +7 -0
  50. package/dist/src/helpers/map-refs.js +7 -6
  51. package/dist/src/helpers/process-http-requests.js +3 -3
  52. package/dist/src/helpers/process-tag-references.js +4 -3
  53. package/dist/src/index.d.ts +2 -1
  54. package/dist/src/index.js +4 -3
  55. package/dist/src/jsx-types.d.ts +1 -1
  56. package/dist/src/parsers/builder.d.ts +50 -10
  57. package/dist/src/parsers/builder.js +37 -7
  58. package/dist/src/parsers/jsx.js +43 -3
  59. package/dist/src/parsers/liquid.js +4 -4
  60. package/dist/src/plugins/compile-away-builder-components.js +40 -20
  61. package/dist/src/symbols/symbol-processor.d.ts +18 -0
  62. package/dist/src/symbols/symbol-processor.js +177 -0
  63. package/dist/src/types/jsx-lite-component.d.ts +63 -0
  64. package/dist/src/types/jsx-lite-component.js +2 -0
  65. package/dist/src/types/jsx-lite-context.d.ts +6 -0
  66. package/dist/src/types/jsx-lite-context.js +2 -0
  67. package/dist/src/types/jsx-lite-node.d.ts +13 -0
  68. package/dist/src/types/jsx-lite-node.js +2 -0
  69. package/dist/src/types/jsx-lite-styles.d.ts +1 -0
  70. package/dist/src/types/jsx-lite-styles.js +2 -0
  71. package/dist/src/types/mitosis-component.d.ts +10 -5
  72. package/dist/test/qoot/Todo/bundle.js +88 -0
  73. package/dist/test/qoot/Todo/component.ts +17 -0
  74. package/dist/test/qoot/Todo/onButtonClick.ts +13 -0
  75. package/dist/test/qoot/Todo/onInput2Blur.ts +11 -0
  76. package/dist/test/qoot/Todo/onInput2KeyUp.ts +10 -0
  77. package/dist/test/qoot/Todo/onInputClick.ts +10 -0
  78. package/dist/test/qoot/Todo/onLabelDblClick.ts +11 -0
  79. package/dist/test/qoot/Todo/public.ts +4 -0
  80. package/dist/test/qoot/Todo/template.tsx +46 -0
  81. package/dist/test/qoot/Todos/component.ts +9 -0
  82. package/dist/test/qoot/Todos/onInputClick.ts +14 -0
  83. package/dist/test/qoot/Todos/public.ts +3 -0
  84. package/dist/test/qoot/Todos/template.tsx +30 -0
  85. package/dist/test/qwik/Accordion/low.jsx +39 -33
  86. package/dist/test/qwik/Accordion/med.jsx +1 -0
  87. package/dist/test/qwik/For/low.jsx +22 -14
  88. package/dist/test/qwik/For/med.jsx +1 -0
  89. package/dist/test/qwik/Image/low.js +20 -47
  90. package/dist/test/qwik/Image/med.js +3 -1
  91. package/dist/test/qwik/Image.slow/low.js +20 -47
  92. package/dist/test/qwik/Image.slow/med.js +3 -1
  93. package/dist/test/qwik/{todo → Todo}/Todo.cjs/high.cjs +0 -0
  94. package/dist/test/qwik/{todo → Todo}/Todo.cjs/low.cjs +0 -0
  95. package/dist/test/qwik/Todo/Todo.cjs/med.cjs +64 -0
  96. package/dist/test/qwik/{todo → Todo}/Todo.js/high.js +0 -0
  97. package/dist/test/qwik/{todo → Todo}/Todo.js/low.js +0 -0
  98. package/dist/test/qwik/Todo/Todo.js/med.js +1 -0
  99. package/dist/test/qwik/{todo → Todo}/Todo.tsx/high.tsx +0 -0
  100. package/dist/test/qwik/{todo → Todo}/Todo.tsx/low.tsx +0 -0
  101. package/dist/test/qwik/Todo/Todo.tsx/med.tsx +39 -0
  102. package/dist/test/qwik/Todo/bundle.js +46 -0
  103. package/dist/test/qwik/Todo/component.ts +17 -0
  104. package/dist/test/qwik/Todo/onButtonClick.ts +10 -0
  105. package/dist/test/qwik/Todo/onInput2Blur.ts +14 -0
  106. package/dist/test/qwik/Todo/onInput2KeyUp.ts +10 -0
  107. package/dist/test/qwik/Todo/onInputClick.ts +13 -0
  108. package/dist/test/qwik/Todo/onLabelDblClick.ts +11 -0
  109. package/dist/test/qwik/Todo/public.ts +3 -0
  110. package/dist/test/qwik/Todo/template.tsx +46 -0
  111. package/dist/test/qwik/Todo.ts +4 -0
  112. package/dist/test/qwik/Todo_component.ts +17 -0
  113. package/dist/test/qwik/Todo_onButtonClick.ts +13 -0
  114. package/dist/test/qwik/Todo_onInput2Blur.ts +14 -0
  115. package/dist/test/qwik/Todo_onInput2KeyUp.ts +10 -0
  116. package/dist/test/qwik/Todo_onInputClick.ts +13 -0
  117. package/dist/test/qwik/Todo_onLabelDblClick.ts +14 -0
  118. package/dist/test/qwik/Todo_template.tsx +46 -0
  119. package/dist/test/qwik/{todos → Todos}/Todo.tsx/high.tsx +0 -0
  120. package/dist/test/qwik/Todos/Todo.tsx/low.tsx +33 -0
  121. package/dist/test/qwik/Todos/Todo.tsx/med.tsx +9 -0
  122. package/dist/test/qwik/Todos/component.ts +9 -0
  123. package/dist/test/qwik/Todos/onInputClick.ts +14 -0
  124. package/dist/test/qwik/Todos/public.ts +3 -0
  125. package/dist/test/qwik/Todos/template.tsx +30 -0
  126. package/dist/test/qwik/Todos.ts +3 -0
  127. package/dist/test/qwik/Todos_component.ts +9 -0
  128. package/dist/test/qwik/Todos_onInputClick.ts +14 -0
  129. package/dist/test/qwik/Todos_template.tsx +30 -0
  130. package/dist/test/qwik/button/low.js +18 -10
  131. package/dist/test/qwik/button/med.js +3 -1
  132. package/dist/test/qwik/component/bindings/high.jsx +1 -0
  133. package/dist/test/qwik/component/bindings/low.jsx +84 -0
  134. package/dist/test/qwik/component/bindings/med.jsx +47 -0
  135. package/dist/test/qwik/hello_world/stylesheet/low.jsx +10 -4
  136. package/dist/test/qwik/hello_world/stylesheet/med.jsx +1 -0
  137. package/dist/test/qwik/page-with-symbol/low.js +23 -17
  138. package/dist/test/qwik/page-with-symbol/med.js +1 -0
  139. package/dist/test/qwik/qwik/Image/high.js +1 -0
  140. package/dist/test/qwik/qwik/Image/low.js +75 -0
  141. package/dist/test/qwik/qwik/Image/med.js +9 -0
  142. package/dist/test/qwik/qwik/Image.slow/high.js +1 -0
  143. package/dist/test/qwik/qwik/Image.slow/low.js +75 -0
  144. package/dist/test/qwik/qwik/Image.slow/med.js +9 -0
  145. package/dist/test/qwik/qwik/button/high.js +8 -0
  146. package/dist/test/qwik/qwik/button/low.js +34 -0
  147. package/dist/test/qwik/qwik/button/med.js +9 -0
  148. package/dist/test/qwik/qwik/hello_world/stylesheet/high.jsx +1 -0
  149. package/dist/test/qwik/qwik/hello_world/stylesheet/low.jsx +24 -0
  150. package/dist/test/qwik/qwik/hello_world/stylesheet/med.jsx +9 -0
  151. package/dist/test/qwik/qwik/page-with-symbol/high.js +1 -0
  152. package/dist/test/qwik/qwik/page-with-symbol/low.js +49 -0
  153. package/dist/test/qwik/qwik/page-with-symbol/med.js +9 -0
  154. package/dist/test/qwik/qwik/svg/high.js +1 -0
  155. package/dist/test/qwik/qwik/svg/low.js +30 -0
  156. package/dist/test/qwik/qwik/svg/med.js +9 -0
  157. package/dist/test/qwik/qwik/todo/Todo.cjs/high.cjs +31 -0
  158. package/dist/test/qwik/qwik/todo/Todo.cjs/low.cjs +1 -0
  159. package/dist/test/qwik/{todo → qwik/todo}/Todo.cjs/med.cjs +0 -0
  160. package/dist/test/qwik/qwik/todo/Todo.js/high.js +5 -0
  161. package/dist/{src/types/generators.d.ts → test/qwik/qwik/todo/Todo.js/low.js} +0 -0
  162. package/dist/test/qwik/{todo → qwik/todo}/Todo.js/med.js +0 -0
  163. package/dist/test/qwik/qwik/todo/Todo.tsx/high.tsx +30 -0
  164. package/dist/test/qwik/qwik/todo/Todo.tsx/low.tsx +1 -0
  165. package/dist/test/qwik/{todo → qwik/todo}/Todo.tsx/med.tsx +0 -0
  166. package/dist/test/qwik/qwik/todos/Todo.tsx/high.tsx +12 -0
  167. package/dist/test/qwik/{todos → qwik/todos}/Todo.tsx/low.tsx +3 -4
  168. package/dist/test/qwik/{todos → qwik/todos}/Todo.tsx/med.tsx +0 -0
  169. package/dist/test/qwik/svg/low.js +16 -10
  170. package/dist/test/qwik/svg/med.js +1 -0
  171. package/dist/tsconfig.tsbuildinfo +1 -1
  172. package/package.json +1 -1
  173. package/dist/src/types/generators.js +0 -1
package/CHANGELOG.md ADDED
@@ -0,0 +1,4 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var angular_1 = require("../generators/angular");
4
+ var jsx_1 = require("../parsers/jsx");
5
+ var onUpdate = require('./data/blocks/onUpdate.raw');
6
+ describe('Angular', function () {
7
+ test('onUpdate', function () {
8
+ var component = (0, jsx_1.parseJsx)(onUpdate);
9
+ var output = (0, angular_1.componentToAngular)()({ component: component });
10
+ expect(output).toMatchSnapshot();
11
+ });
12
+ });
@@ -25,6 +25,12 @@ function Column(props) {
25
25
  flexDirection: 'column',
26
26
  alignItems: 'stretch',
27
27
  lineHeight: 'normal',
28
+ '@media (max-width: 999px)': {
29
+ flexDirection: 'row',
30
+ },
31
+ '@media (max-width: 639px)': {
32
+ flexDirection: 'row-reverse',
33
+ },
28
34
  }}>
29
35
  <mitosis_1.For each={props.columns}>
30
36
  {function (column) { return (<div class="builder-column" css={{ flexGrow: '1' }}>
@@ -0,0 +1 @@
1
+ export default function OnUpdate(): JSX.Element;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mitosis_1 = require("@builder.io/mitosis");
4
+ function OnUpdate() {
5
+ (0, mitosis_1.onUpdate)(function () {
6
+ console.log('Runs on every update/rerender');
7
+ });
8
+ return <div />;
9
+ }
10
+ exports.default = OnUpdate;
@@ -0,0 +1 @@
1
+ export default function OnUpdateWithDeps(): JSX.Element;
@@ -0,0 +1,11 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var mitosis_1 = require("@builder.io/mitosis");
4
+ function OnUpdateWithDeps() {
5
+ var a, b;
6
+ (0, mitosis_1.onUpdate)(function () {
7
+ console.log('Runs when a or b changes');
8
+ }, [a, b]);
9
+ return <div />;
10
+ }
11
+ exports.default = OnUpdateWithDeps;
@@ -0,0 +1,11 @@
1
+ export interface TabsProps {
2
+ tabs: {
3
+ label: any;
4
+ content: any;
5
+ }[];
6
+ defaultActiveTab?: number;
7
+ collapsible?: boolean;
8
+ tabHeaderLayout?: string;
9
+ activeTabStyle?: any;
10
+ }
11
+ export default function Tabs(props: TabsProps): JSX.Element;
@@ -0,0 +1,24 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var core_1 = require("@jsx-lite/core");
4
+ function Tabs(props) {
5
+ var state = core_1.useState({
6
+ activeTab: 0,
7
+ });
8
+ core_1.onMount(function () {
9
+ if (props.defaultActiveTab) {
10
+ state.activeTab = props.defaultActiveTab;
11
+ }
12
+ });
13
+ return (<span css={{
14
+ display: 'flex',
15
+ flexDirection: 'row',
16
+ overflow: 'auto',
17
+ overflowScrolling: 'touch',
18
+ }} style={{
19
+ justifyContent: props.tabHeaderLayout,
20
+ }} class="builder-tabs-wrap">
21
+ <core_1.For each={props.tabs}>{function (child) { return <div>{child.content}</div>; }}</core_1.For>
22
+ </span>);
23
+ }
24
+ exports.default = Tabs;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,115 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __generator = (this && this.__generator) || function (thisArg, body) {
12
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
13
+ return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
14
+ function verb(n) { return function (v) { return step([n, v]); }; }
15
+ function step(op) {
16
+ if (f) throw new TypeError("Generator is already executing.");
17
+ while (_) try {
18
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
19
+ if (y = 0, t) op = [op[0] & 2, t.value];
20
+ switch (op[0]) {
21
+ case 0: case 1: t = op; break;
22
+ case 4: _.label++; return { value: op[1], done: false };
23
+ case 5: _.label++; y = op[1]; op = [0]; continue;
24
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
25
+ default:
26
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
27
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
28
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
29
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
30
+ if (t[2]) _.ops.pop();
31
+ _.trys.pop(); continue;
32
+ }
33
+ op = body.call(thisArg, _);
34
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
35
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
36
+ }
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ var fs_extra_promise_1 = require("fs-extra-promise");
40
+ var qoot_1 = require("../generators/qoot");
41
+ var jsx_1 = require("../parsers/jsx");
42
+ var todo = require('../../../../examples/todo/src/components/todo.lite');
43
+ var todos = require('../../../../examples/todo/src/components/todos.lite');
44
+ var debugFiles = true;
45
+ var debugOutput = function (output) { return __awaiter(void 0, void 0, void 0, function () {
46
+ var _i, _a, file;
47
+ return __generator(this, function (_b) {
48
+ switch (_b.label) {
49
+ case 0:
50
+ if (!debugFiles) return [3 /*break*/, 4];
51
+ _i = 0, _a = output.files;
52
+ _b.label = 1;
53
+ case 1:
54
+ if (!(_i < _a.length)) return [3 /*break*/, 4];
55
+ file = _a[_i];
56
+ return [4 /*yield*/, fs_extra_promise_1.outputFileAsync('dist/test/qoot/' + file.path, file.contents)];
57
+ case 2:
58
+ _b.sent();
59
+ _b.label = 3;
60
+ case 3:
61
+ _i++;
62
+ return [3 /*break*/, 1];
63
+ case 4: return [2 /*return*/];
64
+ }
65
+ });
66
+ }); };
67
+ describe('Qoot', function () {
68
+ test('Todo', function () { return __awaiter(void 0, void 0, void 0, function () {
69
+ var json, output;
70
+ return __generator(this, function (_a) {
71
+ switch (_a.label) {
72
+ case 0:
73
+ json = jsx_1.parseJsx(todo);
74
+ return [4 /*yield*/, qoot_1.componentToQoot(json)];
75
+ case 1:
76
+ output = _a.sent();
77
+ expect(output).toMatchSnapshot();
78
+ debugOutput(output);
79
+ return [2 /*return*/];
80
+ }
81
+ });
82
+ }); });
83
+ test('Todo bundle', function () { return __awaiter(void 0, void 0, void 0, function () {
84
+ var json, output;
85
+ return __generator(this, function (_a) {
86
+ switch (_a.label) {
87
+ case 0:
88
+ json = jsx_1.parseJsx(todo);
89
+ return [4 /*yield*/, qoot_1.componentToQoot(json, {
90
+ bundle: true,
91
+ })];
92
+ case 1:
93
+ output = _a.sent();
94
+ expect(output).toMatchSnapshot();
95
+ debugOutput(output);
96
+ return [2 /*return*/];
97
+ }
98
+ });
99
+ }); });
100
+ test('Todos', function () { return __awaiter(void 0, void 0, void 0, function () {
101
+ var json, output;
102
+ return __generator(this, function (_a) {
103
+ switch (_a.label) {
104
+ case 0:
105
+ json = jsx_1.parseJsx(todos);
106
+ return [4 /*yield*/, qoot_1.componentToQoot(json)];
107
+ case 1:
108
+ output = _a.sent();
109
+ expect(output).toMatchSnapshot();
110
+ debugOutput(output);
111
+ return [2 /*return*/];
112
+ }
113
+ });
114
+ }); });
115
+ });
@@ -37,11 +37,12 @@ var __generator = (this && this.__generator) || function (thisArg, body) {
37
37
  };
38
38
  Object.defineProperty(exports, "__esModule", { value: true });
39
39
  var fs_extra_promise_1 = require("fs-extra-promise");
40
- var __1 = require("..");
41
40
  var index_1 = require("../generators/qwik/index");
42
41
  var src_generator_1 = require("../generators/qwik/src-generator");
42
+ var builder_1 = require("../parsers/builder");
43
43
  var jsx_1 = require("../parsers/jsx");
44
44
  var compile_away_builder_components_1 = require("../plugins/compile-away-builder-components");
45
+ var symbol_processor_1 = require("../symbols/symbol-processor");
45
46
  var todo = require('../../../../examples/todo/src/components/todo.lite');
46
47
  var todos = require('../../../../examples/todo/src/components/todos.lite');
47
48
  var debugFiles = true;
@@ -130,7 +131,7 @@ describe('qwik', function () {
130
131
  test('stylesheet', function () { return __awaiter(void 0, void 0, void 0, function () {
131
132
  var component, fileSet;
132
133
  return __generator(this, function (_a) {
133
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.hello_world.json'));
134
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.hello_world.json'));
134
135
  fileSet = (0, index_1.createFileSet)({ output: 'mjs' });
135
136
  (0, index_1.addComponent)(fileSet, component);
136
137
  debugOutput(fileSet);
@@ -142,7 +143,7 @@ describe('qwik', function () {
142
143
  test('page-with-symbol', function () { return __awaiter(void 0, void 0, void 0, function () {
143
144
  var component, fileSet;
144
145
  return __generator(this, function (_a) {
145
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.page-with-symbol.json'));
146
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.page-with-symbol.json'));
146
147
  fileSet = (0, index_1.createFileSet)({ output: 'mjs', jsx: false });
147
148
  (0, index_1.addComponent)(fileSet, component);
148
149
  debugOutput(fileSet);
@@ -153,7 +154,7 @@ describe('qwik', function () {
153
154
  test('button', function () { return __awaiter(void 0, void 0, void 0, function () {
154
155
  var component, fileSet;
155
156
  return __generator(this, function (_a) {
156
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.button.json'));
157
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.button.json'));
157
158
  fileSet = (0, index_1.createFileSet)({ output: 'mjs', jsx: false });
158
159
  (0, index_1.addComponent)(fileSet, component);
159
160
  debugOutput(fileSet);
@@ -164,7 +165,7 @@ describe('qwik', function () {
164
165
  test('svg', function () { return __awaiter(void 0, void 0, void 0, function () {
165
166
  var component, fileSet;
166
167
  return __generator(this, function (_a) {
167
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.svg.json'), {
168
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.svg.json'), {
168
169
  includeBuilderExtras: true,
169
170
  preserveTextBlocks: true,
170
171
  });
@@ -178,7 +179,7 @@ describe('qwik', function () {
178
179
  test('Image', function () { return __awaiter(void 0, void 0, void 0, function () {
179
180
  var component, fileSet;
180
181
  return __generator(this, function (_a) {
181
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.image.json'), {
182
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.image.json'), {
182
183
  includeBuilderExtras: true,
183
184
  preserveTextBlocks: true,
184
185
  });
@@ -192,11 +193,10 @@ describe('qwik', function () {
192
193
  test('Image.slow', function () { return __awaiter(void 0, void 0, void 0, function () {
193
194
  var component, fileSet;
194
195
  return __generator(this, function (_a) {
195
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.image.json'), {
196
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.image.json'), {
196
197
  includeBuilderExtras: true,
197
198
  preserveTextBlocks: true,
198
199
  });
199
- (0, compile_away_builder_components_1.compileAwayBuilderComponentsFromTree)(component, compile_away_builder_components_1.components);
200
200
  fileSet = (0, index_1.createFileSet)({ output: 'mjs', jsx: false });
201
201
  (0, index_1.addComponent)(fileSet, component);
202
202
  debugOutput(fileSet);
@@ -207,7 +207,7 @@ describe('qwik', function () {
207
207
  test('Accordion', function () { return __awaiter(void 0, void 0, void 0, function () {
208
208
  var component, fileSet;
209
209
  return __generator(this, function (_a) {
210
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.accordion.json'), {
210
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.accordion.json'), {
211
211
  includeBuilderExtras: true,
212
212
  preserveTextBlocks: true,
213
213
  });
@@ -222,7 +222,7 @@ describe('qwik', function () {
222
222
  test('For', function () { return __awaiter(void 0, void 0, void 0, function () {
223
223
  var component, fileSet;
224
224
  return __generator(this, function (_a) {
225
- component = (0, __1.builderContentToMitosisComponent)(require('./qwik.test.for-loop.json'), {
225
+ component = (0, builder_1.builderContentToMitosisComponent)(require('./qwik.test.for-loop.json'), {
226
226
  includeBuilderExtras: true,
227
227
  preserveTextBlocks: true,
228
228
  });
@@ -234,6 +234,34 @@ describe('qwik', function () {
234
234
  return [2 /*return*/];
235
235
  });
236
236
  }); });
237
+ describe('component', function () {
238
+ test('bindings', function () { return __awaiter(void 0, void 0, void 0, function () {
239
+ var content, state, hierarchy, fileSet, component;
240
+ return __generator(this, function (_a) {
241
+ content = require('./qwik.test.component-binding.json');
242
+ state = {};
243
+ hierarchy = (0, symbol_processor_1.convertBuilderContentToSymbolHierarchy)(content, {
244
+ collectComponentState: state,
245
+ });
246
+ expect(state).toMatchSnapshot();
247
+ fileSet = (0, index_1.createFileSet)({ output: 'mjs', jsx: true });
248
+ hierarchy.depthFirstSymbols.forEach(function (builderComponent) {
249
+ var mitosisComponent = (0, symbol_processor_1.convertBuilderElementToMitosisComponent)(builderComponent);
250
+ mitosisComponent &&
251
+ (0, index_1.addComponent)(fileSet, mitosisComponent, { isRoot: false });
252
+ });
253
+ component = (0, builder_1.builderContentToMitosisComponent)(content, {
254
+ includeBuilderExtras: true,
255
+ preserveTextBlocks: true,
256
+ });
257
+ (0, compile_away_builder_components_1.compileAwayBuilderComponentsFromTree)(component, compile_away_builder_components_1.components);
258
+ (0, index_1.addComponent)(fileSet, component);
259
+ debugOutput(fileSet);
260
+ expect(toObj(fileSet)).toMatchSnapshot();
261
+ return [2 /*return*/];
262
+ });
263
+ }); });
264
+ });
237
265
  describe('helper functions', function () {
238
266
  describe('isStatement', function () {
239
267
  test('is an expression', function () {
@@ -19,6 +19,8 @@ var customCode = require('./data/blocks/custom-code.raw');
19
19
  var embed = require('./data/blocks/embed.raw');
20
20
  var image = require('./data/blocks/image.raw');
21
21
  var columns = require('./data/blocks/columns.raw');
22
+ var onUpdate = require('./data/blocks/onUpdate.raw');
23
+ var onUpdateWithDeps = require('./data/blocks/onUpdateWithDeps.raw');
22
24
  describe('React', function () {
23
25
  test('Basic', function () {
24
26
  var component = (0, jsx_1.parseJsx)(basic);
@@ -108,4 +110,14 @@ describe('React', function () {
108
110
  var output = (0, react_1.componentToReact)()({ component: component });
109
111
  expect(output).toMatchSnapshot();
110
112
  });
113
+ test('onUpdate', function () {
114
+ var component = (0, jsx_1.parseJsx)(onUpdate);
115
+ var output = (0, react_1.componentToReact)()({ component: component });
116
+ expect(output).toMatchSnapshot();
117
+ });
118
+ test('onUpdateWithDeps', function () {
119
+ var component = (0, jsx_1.parseJsx)(onUpdateWithDeps);
120
+ var output = (0, react_1.componentToReact)()({ component: component });
121
+ expect(output).toMatchSnapshot();
122
+ });
111
123
  });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ var svelte_1 = require("../generators/svelte");
4
+ var jsx_1 = require("../parsers/jsx");
5
+ var onUpdate = require('./data/blocks/onUpdate.raw');
6
+ describe('Svelte', function () {
7
+ test('onUpdate', function () {
8
+ var component = (0, jsx_1.parseJsx)(onUpdate);
9
+ var output = (0, svelte_1.componentToSvelte)()({ component: component });
10
+ expect(output).toMatchSnapshot();
11
+ });
12
+ });
@@ -19,6 +19,7 @@ var customCode = require('./data/blocks/custom-code.raw');
19
19
  var embed = require('./data/blocks/embed.raw');
20
20
  var image = require('./data/blocks/image.raw');
21
21
  var columns = require('./data/blocks/columns.raw');
22
+ var onUpdate = require('./data/blocks/onUpdate.raw');
22
23
  var path = 'test-path';
23
24
  describe('Vue', function () {
24
25
  test('Basic', function () {
@@ -106,4 +107,9 @@ describe('Vue', function () {
106
107
  var output = (0, vue_1.componentToVue)()({ component: component, path: path });
107
108
  expect(output).toMatchSnapshot();
108
109
  });
110
+ test('onUpdate', function () {
111
+ var component = (0, jsx_1.parseJsx)(onUpdate);
112
+ var output = (0, vue_1.componentToVue)()({ component: component, path: path });
113
+ expect(output).toMatchSnapshot();
114
+ });
109
115
  });
@@ -150,7 +150,7 @@ var componentToAngular = function (options) {
150
150
  return (0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(code, { replaceWith: 'this.' });
151
151
  },
152
152
  });
153
- var str = (0, dedent_1.default)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n import { Component ", "", " } from '@angular/core';\n ", "\n\n @Component({\n selector: '", "',\n template: `\n ", "\n `,\n ", "\n })\n export default class ", " {\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n }\n "], ["\n import { Component ", "", " } from '@angular/core';\n ", "\n\n @Component({\n selector: '", "',\n template: \\`\n ", "\n \\`,\n ", "\n })\n export default class ", " {\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n }\n "])), refs.length ? ', ViewChild, ElementRef' : '', props.size ? ', Input' : '', (0, render_imports_1.renderPreComponent)(json), (0, lodash_1.kebabCase)(json.name || 'my-component'), indent(template, 8)
153
+ var str = (0, dedent_1.default)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n import { Component ", "", " } from '@angular/core';\n ", "\n\n @Component({\n selector: '", "',\n template: `\n ", "\n `,\n ", "\n })\n export default class ", " {\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n }\n "], ["\n import { Component ", "", " } from '@angular/core';\n ", "\n\n @Component({\n selector: '", "',\n template: \\`\n ", "\n \\`,\n ", "\n })\n export default class ", " {\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n\n ", "\n }\n "])), refs.length ? ', ViewChild, ElementRef' : '', props.size ? ', Input' : '', (0, render_imports_1.renderPreComponent)(json), (0, lodash_1.kebabCase)(json.name || 'my-component'), indent(template, 8)
154
154
  .replace(/`/g, '\\`')
155
155
  .replace(/\$\{/g, '\\${'), css.length
156
156
  ? "styles: [\n `".concat(indent(css, 8), "`\n ],")
@@ -160,11 +160,15 @@ var componentToAngular = function (options) {
160
160
  .map(function (refName) { return "@ViewChild('".concat(refName, "') ").concat(refName, ": ElementRef"); })
161
161
  .join('\n'), !component.hooks.onMount
162
162
  ? ''
163
- : "ngOnInit() {\n ".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(component.hooks.onMount, {
163
+ : "ngOnInit() {\n ".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(component.hooks.onMount.code, {
164
+ replaceWith: 'this.',
165
+ }), "\n }"), !component.hooks.onUpdate
166
+ ? ''
167
+ : "ngAfterContentChecked() {\n ".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(component.hooks.onUpdate.code, {
164
168
  replaceWith: 'this.',
165
169
  }), "\n }"), !component.hooks.onUnMount
166
170
  ? ''
167
- : "ngOnDestroy() {\n ".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(component.hooks.onUnMount, {
171
+ : "ngOnDestroy() {\n ".concat((0, strip_state_and_props_refs_1.stripStateAndPropsRefs)(component.hooks.onUnMount.code, {
168
172
  replaceWith: 'this.',
169
173
  }), "\n }"), dataString);
170
174
  if (options.plugins) {
@@ -236,28 +236,28 @@ exports.blockToBuilder = blockToBuilder;
236
236
  var componentToBuilder = function (options) {
237
237
  if (options === void 0) { options = {}; }
238
238
  return function (_a) {
239
- var _b, _c;
239
+ var _b, _c, _d, _e;
240
240
  var component = _a.component;
241
241
  var hasState = Boolean(Object.keys(component.state).length);
242
242
  var result = (0, fast_clone_1.fastClone)({
243
243
  data: {
244
244
  httpRequests: (_c = (_b = component === null || component === void 0 ? void 0 : component.meta) === null || _b === void 0 ? void 0 : _b.useMetadata) === null || _c === void 0 ? void 0 : _c.httpRequests,
245
- jsCode: tryFormat((0, dedent_1.default)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", "\n\n ", "\n\n ", "\n "], ["\n ", "\n\n ", "\n\n ", "\n "])), !(0, has_props_1.hasProps)(component) ? '' : "var props = state;", !hasState
245
+ jsCode: tryFormat((0, dedent_1.default)(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n ", "\n\n ", "\n \n ", "\n "], ["\n ", "\n\n ", "\n \n ", "\n "])), !(0, has_props_1.hasProps)(component) ? '' : "var props = state;", !hasState
246
246
  ? ''
247
- : "Object.assign(state, ".concat((0, get_state_object_string_1.getStateObjectStringFromComponent)(component), ");"), !component.hooks.onMount ? '' : component.hooks.onMount)),
247
+ : "Object.assign(state, ".concat((0, get_state_object_string_1.getStateObjectStringFromComponent)(component), ");"), !((_d = component.hooks.onMount) === null || _d === void 0 ? void 0 : _d.code) ? '' : component.hooks.onMount.code)),
248
248
  tsCode: tryFormat((0, dedent_1.default)(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n ", "\n\n ", "\n\n ", "\n "], ["\n ", "\n\n ", "\n\n ", "\n "])), !(0, has_props_1.hasProps)(component) ? '' : "var props = state;", !hasState
249
249
  ? ''
250
- : "useState(".concat((0, get_state_object_string_1.getStateObjectStringFromComponent)(component), ");"), !component.hooks.onMount
250
+ : "useState(".concat((0, get_state_object_string_1.getStateObjectStringFromComponent)(component), ");"), !((_e = component.hooks.onMount) === null || _e === void 0 ? void 0 : _e.code)
251
251
  ? ''
252
- : "onMount(() => {\n ".concat(component.hooks.onMount, "\n })"))),
252
+ : "onMount(() => {\n ".concat(component.hooks.onMount.code, "\n })"))),
253
253
  blocks: component.children
254
254
  .filter(filter_empty_text_nodes_1.filterEmptyTextNodes)
255
255
  .map(function (child) { return (0, exports.blockToBuilder)(child, options); }),
256
256
  },
257
257
  });
258
258
  var subComponentMap = {};
259
- for (var _i = 0, _d = component.subComponents; _i < _d.length; _i++) {
260
- var subComponent = _d[_i];
259
+ for (var _i = 0, _f = component.subComponents; _i < _f.length; _i++) {
260
+ var subComponent = _f[_i];
261
261
  var name_1 = subComponent.name;
262
262
  subComponentMap[name_1] = (0, exports.componentToBuilder)(options)({
263
263
  component: subComponent,
@@ -266,6 +266,7 @@ var htmlDecode = function (html) { return html.replace(/&quot;/gi, '"'); };
266
266
  var componentToHtml = function (options) {
267
267
  if (options === void 0) { options = {}; }
268
268
  return function (_a) {
269
+ var _b, _c, _d;
269
270
  var component = _a.component;
270
271
  var useOptions = __assign(__assign({}, options), { onChangeJsById: {}, js: '', namesMap: {}, format: 'script' });
271
272
  var json = (0, fast_clone_1.fastClone)(component);
@@ -290,7 +291,10 @@ var componentToHtml = function (options) {
290
291
  }
291
292
  var hasChangeListeners = Boolean(Object.keys(useOptions.onChangeJsById).length);
292
293
  var hasGeneratedJs = Boolean(useOptions.js.trim().length);
293
- if (hasChangeListeners || hasGeneratedJs || json.hooks.onMount || hasLoop) {
294
+ if (hasChangeListeners ||
295
+ hasGeneratedJs ||
296
+ ((_b = json.hooks.onMount) === null || _b === void 0 ? void 0 : _b.code) ||
297
+ hasLoop) {
294
298
  // TODO: collectJs helper for here and liquid
295
299
  str += "\n <script>\n (() => {\n const state = ".concat((0, get_state_object_string_1.getStateObjectStringFromComponent)(json, {
296
300
  valueMapper: function (value) {
@@ -306,10 +310,12 @@ var componentToHtml = function (options) {
306
310
  }
307
311
  return "\n document.querySelectorAll(\"[data-name='".concat(key, "']\").forEach((el) => {\n ").concat(value, "\n })\n ");
308
312
  })
309
- .join('\n\n'), "\n }\n\n ").concat(useOptions.js, "\n\n // Update with initial state on first load\n update();\n "), "\n\n ").concat(!json.hooks.onMount
313
+ .join('\n\n'), "\n\n ").concat(!((_c = json.hooks.onUpdate) === null || _c === void 0 ? void 0 : _c.code)
314
+ ? ''
315
+ : "\n ".concat(updateReferencesInCode(json.hooks.onUpdate.code, useOptions), " \n "), "\n }\n\n ").concat(useOptions.js, "\n\n // Update with initial state on first load\n update();\n "), "\n\n ").concat(!((_d = json.hooks.onMount) === null || _d === void 0 ? void 0 : _d.code)
310
316
  ? ''
311
317
  : // TODO: make prettier by grabbing only the function body
312
- "\n // onMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onMount, useOptions), useOptions), " \n "), "\n\n ").concat(!hasLoop
318
+ "\n // onMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onMount.code, useOptions), useOptions), " \n "), "\n\n ").concat(!hasLoop
313
319
  ? ''
314
320
  : "\n\n // Helper to render loops\n function renderLoop(el, array, template, itemName) {\n el.innerHTML = '';\n for (let value of array) {\n let tmp = document.createElement('span');\n tmp.innerHTML = template.innerHTML;\n Array.from(tmp.children).forEach(function (child) {\n contextMap.set(child, {\n ...contextMap.get(child),\n [itemName]: value\n });\n el.appendChild(child);\n });\n }\n }\n\n // Helper to pass context down for loops\n let contextMap = new WeakMap();\n function getContext(el, name) {\n let parent = el;\n do {\n let context = contextMap.get(parent);\n if (context && name in context) {\n return context[name];\n }\n } while (parent = parent.parentNode)\n }\n ", "\n })()\n </script>\n ");
315
321
  }
@@ -344,6 +350,7 @@ exports.componentToHtml = componentToHtml;
344
350
  var componentToCustomElement = function (options) {
345
351
  if (options === void 0) { options = {}; }
346
352
  return function (_a) {
353
+ var _b, _c, _d;
347
354
  var component = _a.component;
348
355
  var useOptions = __assign(__assign({}, options), { onChangeJsById: {}, js: '', namesMap: {}, format: 'class' });
349
356
  var json = (0, fast_clone_1.fastClone)(component);
@@ -405,12 +412,12 @@ var componentToCustomElement = function (options) {
405
412
  ? "this.props = {};"
406
413
  : '', "\n\n ").concat(!hasLoop
407
414
  ? ''
408
- : "\n // Helper to pass context down for loops\n this.contextMap = new WeakMap();\n ", "\n\n ").concat(useOptions.js, "\n }\n\n ").concat(!json.hooks.onUnMount
415
+ : "\n // Helper to pass context down for loops\n this.contextMap = new WeakMap();\n ", "\n\n ").concat(useOptions.js, "\n }\n\n ").concat(!((_b = json.hooks.onUnMount) === null || _b === void 0 ? void 0 : _b.code)
409
416
  ? ''
410
- : "\n disconnectedCallback() {\n // onUnMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onUnMount, useOptions), useOptions), "\n }\n "), "\n\n connectedCallback() {\n this.innerHTML = `\n ").concat(html, "`;\n this.update();\n\n ").concat(!json.hooks.onMount
417
+ : "\n disconnectedCallback() {\n // onUnMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onUnMount.code, useOptions), useOptions), "\n }\n "), "\n\n connectedCallback() {\n this.innerHTML = `\n ").concat(html, "`;\n this.update();\n\n ").concat(!((_c = json.hooks.onMount) === null || _c === void 0 ? void 0 : _c.code)
411
418
  ? ''
412
419
  : // TODO: make prettier by grabbing only the function body
413
- "\n // onMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onMount, useOptions), useOptions), "\n "), "\n }\n\n update() {\n ").concat(Object.keys(useOptions.onChangeJsById)
420
+ "\n // onMount\n ".concat(updateReferencesInCode(addUpdateAfterSetInCode(json.hooks.onMount.code, useOptions), useOptions), "\n "), "\n }\n\n update() {\n ").concat(Object.keys(useOptions.onChangeJsById)
414
421
  .map(function (key) {
415
422
  var value = useOptions.onChangeJsById[key];
416
423
  if (!value) {
@@ -418,7 +425,9 @@ var componentToCustomElement = function (options) {
418
425
  }
419
426
  return "\n this.querySelectorAll(\"[data-name='".concat(key, "']\").forEach((el) => {\n ").concat(updateReferencesInCode(value, useOptions), "\n })\n ");
420
427
  })
421
- .join('\n\n'), "\n }\n\n ").concat(!hasLoop
428
+ .join('\n\n'), "\n\n ").concat(!((_d = json.hooks.onUpdate) === null || _d === void 0 ? void 0 : _d.code)
429
+ ? ''
430
+ : "\n ".concat(updateReferencesInCode(json.hooks.onUpdate.code, useOptions), " \n "), " \n }\n\n ").concat(!hasLoop
422
431
  ? ''
423
432
  : "\n\n // Helper to render loops\n renderLoop(el, array, template, itemName) {\n el.innerHTML = '';\n for (let value of array) {\n let tmp = document.createElement('span');\n tmp.innerHTML = template.innerHTML;\n Array.from(tmp.children).forEach((child) => {\n this.contextMap.set(child, {\n ...this.contextMap.get(child),\n [itemName]: value\n });\n el.appendChild(child);\n });\n }\n }\n\n getContext(el, name) {\n let parent = el;\n do {\n let context = this.contextMap.get(parent);\n if (context && name in context) {\n return context[name];\n }\n } while (parent = parent.parentNode)\n }\n ", "\n }\n\n customElements.define('").concat(kebabName, "', ").concat(component.name, ");\n ");
424
433
  if (options.plugins) {
@@ -0,0 +1,10 @@
1
+ import { JSXLiteComponent } from '../types/jsx-lite-component';
2
+ import { JSXLiteNode } from '../types/jsx-lite-node';
3
+ export declare const DEFAULT_FORMAT = "legacy";
4
+ export declare type JsxLiteFormat = 'react' | 'legacy';
5
+ export declare type ToJsxLiteOptions = {
6
+ prettier?: boolean;
7
+ format: JsxLiteFormat;
8
+ };
9
+ export declare const blockToJsxLite: (json: JSXLiteNode, toJsxLiteOptions?: Partial<ToJsxLiteOptions>) => string;
10
+ export declare const componentToJsxLite: (componentJson: JSXLiteComponent, toJsxLiteOptions?: Partial<ToJsxLiteOptions>) => string;