@yr-lang/yr 0.3.12 → 0.4.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/lib/@react.yr ADDED
@@ -0,0 +1,7 @@
1
+ %%
2
+
3
+ _@renderReact(#query) {
4
+ ReactDOM.createRoot(document.querySelector(#query)).render(
5
+ ___
6
+ );
7
+ @}
@@ -0,0 +1,29 @@
1
+ !! @react
2
+
3
+ ++
4
+
5
+ _ #root
6
+
7
+ @@r
8
+
9
+ import { useState, useEffect } from "react";
10
+ function App() {
11
+ const [count, setCount] = useState(0);
12
+ const [message, setMessage] = useState('Loading...');
13
+ useEffect(() => {
14
+ setMessage(`Count is ${count}`);
15
+ }, [count]);
16
+ return (
17
+ <div>
18
+ <h1>Simple React App</h1>
19
+ <p>{message}</p>
20
+ <button onClick={() => setCount(count + 1)}>
21
+ Count: {count}
22
+ </button>
23
+ </div>
24
+ );
25
+ }
26
+
27
+ _@renderReact('#root') {
28
+ <App />
29
+ @}
package/node.js CHANGED
@@ -127,7 +127,7 @@ module.exports = {
127
127
  let result = '';
128
128
  if (extensions) result += extensions + '\n';
129
129
 
130
- for (let item of ['nosection', 'extensions']) {
130
+ for (let item of ['nosection', 'extensions', 'pixel']) {
131
131
  if (sections[item]) {
132
132
  result += sections[item] + '\n';
133
133
  delete sections[item];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yr-lang/yr",
3
- "version": "0.3.12",
3
+ "version": "0.4.0",
4
4
  "description": "Yr is a modern structural language and parser",
5
5
  "main": "./node.js",
6
6
  "exports": {
@@ -10,5 +10,10 @@
10
10
  "repository": {
11
11
  "type": "git",
12
12
  "url": "git+https://github.com/yr-lang/yr.git"
13
+ },
14
+ "dependencies": {
15
+ "esbuild": "^0.28.2",
16
+ "react": "^19.2.8",
17
+ "react-dom": "^19.2.8"
13
18
  }
14
19
  }
package/yr.js CHANGED
@@ -36,6 +36,10 @@ const namespaces = {
36
36
  '@<': { name: 'jsfooter', parser: 'string', default: '', merge: true },
37
37
  '>@': { name: 'wrapperjs', parser: 'string', default: '', merge: true },
38
38
  '<@': { name: 'wrapperjscustom', parser: 'string', default: '', merge: true },
39
+ '@>r': { name: 'jsheaderreact', parser: 'string', default: '', merge: true },
40
+ '@@r': { name: 'jsreact', parser: 'string', default: '', merge: true },
41
+ '@<r': { name: 'jsfooterreact', parser: 'string', default: '', merge: true },
42
+ '<@r': { name: 'wrapperjscustomreact', parser: 'string', default: '', merge: true },
39
43
  '""': { name: 'documentation', parser: 'string', default: '' },
40
44
  '--': { name: 'modules', parser: 'object', default: [], merge: true },
41
45
  '==': { name: 'pixel', parser: 'string', default: '', merge: true },
@@ -69,6 +73,46 @@ for (let item of Object.keys(namespaces)) {
69
73
  }
70
74
  }
71
75
 
76
+ let viewType;
77
+ function transformReact(code, sections, section, config) {
78
+ code = module.exports.macros(sections, section);
79
+
80
+ if (viewType === 'cdn') {
81
+ if (!window.Babel) throw 'Babel unavailable';
82
+ return window.Babel.transform(code, { presets: ['react'] }).code;
83
+ }
84
+
85
+ if (viewType === 'npm') {
86
+ for (let item of ['react', 'react-dom']) {
87
+ if (sections.modules.includes(item)) continue;
88
+ sections.modules.push(item)
89
+ }
90
+ try {
91
+ const esbuild = require('esbuild');
92
+ code = "import React from 'react';\n"
93
+ + "import ReactDOM from 'react-dom/client';\n" + code;
94
+ const result = esbuild.buildSync({
95
+ stdin: {
96
+ contents: code, loader: 'jsx',
97
+ resolveDir: config.projectPath || process.cwd()
98
+ },
99
+ bundle: true, write: false, format: 'iife',
100
+ nodePaths: [path.join(__dirname, 'node_modules')]
101
+ });
102
+ return result.outputFiles[0].text;
103
+ } catch (error) {
104
+ console.log(error);
105
+ const unresolved = error.errors
106
+ && error.errors.some(item => item.text.startsWith('Could not resolve'));
107
+
108
+ if (!unresolved) throw error;
109
+
110
+ if (sections) sections.reactBuildFailed = true;
111
+ return '';
112
+ }
113
+ }
114
+ }
115
+
72
116
  function parseLine(line) {
73
117
  const indentation = line.search(/\S/);
74
118
 
@@ -1231,6 +1275,13 @@ const core = {
1231
1275
  if (section === 'macros')
1232
1276
  this.aux(sections, { macrosAux: sections.macrosAux });
1233
1277
 
1278
+ if (section.endsWith('react')) {
1279
+ sections[section.replace(/react/, '')] +=
1280
+ transformReact(sections[section], sections, section, config) + '\n';
1281
+ sections[section] = '';
1282
+ sections.reactUsed = true;
1283
+ }
1284
+
1234
1285
  section = parsers.namespaces[line].name;
1235
1286
  state.sectionChanged = true;
1236
1287
 
@@ -1328,6 +1379,13 @@ const core = {
1328
1379
  lineNumber++;
1329
1380
  }
1330
1381
 
1382
+ if (section.endsWith('react')) {
1383
+ sections[section.replace(/react/, '')] +=
1384
+ transformReact(sections[section], sections, section, config) + '\n';
1385
+ sections[section] = '';
1386
+ sections.reactUsed = true;
1387
+ }
1388
+
1331
1389
  section = false;
1332
1390
 
1333
1391
  if (config.wrapper && sections.wrappersAux
@@ -1812,6 +1870,10 @@ ${sections.pixel}
1812
1870
  <head>
1813
1871
  ${sections.parsedheader}
1814
1872
  ${(config.name) ? ` <link rel="stylesheet" href="./${config.cssname}.css">` : ` <style>\n${sections.parsedcss}\n</style>`}
1873
+ ${sections.reactUsed && viewType === 'cdn'
1874
+ ? ' <s' + 'cript src="https://unpkg.com/react@18/umd/react.production.min.js"></scri' + 'pt>\n' +
1875
+ ' <s' + 'cript src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></scri' + 'pt>'
1876
+ : ''}
1815
1877
  </head>
1816
1878
  <body style="display: none">
1817
1879
  ${sections.parsedbody}
@@ -1840,12 +1902,14 @@ document.addEventListener('DOMContentLoaded', () => {
1840
1902
  parsers
1841
1903
  };
1842
1904
 
1843
- if (typeof module !== 'undefined' && module.exports)
1905
+ if (typeof module !== 'undefined' && module.exports) {
1906
+ viewType = 'npm';
1844
1907
  module.exports = core;
1908
+ }
1845
1909
 
1846
1910
  if (typeof window !== 'undefined' && !window.yr) {
1847
- const parse = core.parse.bind(core);
1848
- window.yr = parse;
1911
+ viewType = 'cdn';
1912
+ window.yr = core.parse.bind(core);
1849
1913
 
1850
1914
  //const createLog = (text) => {
1851
1915
  // const parsed = parse(text);