@yr-lang/yr 0.4.0 → 0.5.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 (61) hide show
  1. package/CHANGELOG.md +9 -3
  2. package/lib/@react.yr +6 -3
  3. package/lib/cdn.json +1 -0
  4. package/lib/index.js +7 -0
  5. package/node.js +12 -1
  6. package/package.json +1 -1
  7. package/tests/.yrrc +2 -0
  8. package/{lib → tests}/Yrci/A1.yr +1 -1
  9. package/{lib → tests}/Yrci/React.yr +2 -9
  10. package/yr.js +140 -23
  11. /package/{lib → tests}/Ciyr/A1.yr +0 -0
  12. /package/{lib → tests}/Ciyr/B1.yr +0 -0
  13. /package/{lib → tests}/Ciyr/B2.yr +0 -0
  14. /package/{lib → tests}/Ciyr/C1.yr +0 -0
  15. /package/{lib → tests}/Ciyr/C2.yr +0 -0
  16. /package/{lib → tests}/Ciyr/C2_2.yr +0 -0
  17. /package/{lib → tests}/Ciyr/a1.yr +0 -0
  18. /package/{lib → tests}/Ciyr/b1.yr +0 -0
  19. /package/{lib → tests}/Ciyr/c1.yr +0 -0
  20. /package/{lib → tests}/Yrci/&app.yr +0 -0
  21. /package/{lib → tests}/Yrci/&app2.yr +0 -0
  22. /package/{lib → tests}/Yrci/@m1.yr +0 -0
  23. /package/{lib → tests}/Yrci/@m2.yr +0 -0
  24. /package/{lib → tests}/Yrci/A2.yr +0 -0
  25. /package/{lib → tests}/Yrci/A3.yr +0 -0
  26. /package/{lib → tests}/Yrci/B1.yr +0 -0
  27. /package/{lib → tests}/Yrci/C1.yr +0 -0
  28. /package/{lib → tests}/Yrci/C1.yrr +0 -0
  29. /package/{lib → tests}/Yrci/C2.yr +0 -0
  30. /package/{lib → tests}/Yrci/C3.yr +0 -0
  31. /package/{lib → tests}/Yrci/C4.yr +0 -0
  32. /package/{lib → tests}/Yrci/C5.yr +0 -0
  33. /package/{lib → tests}/Yrci/C6.yr +0 -0
  34. /package/{lib → tests}/Yrci/C7.yr +0 -0
  35. /package/{lib → tests}/Yrci/C8.yr +0 -0
  36. /package/{lib → tests}/Yrci/C9.yr +0 -0
  37. /package/{lib → tests}/Yrci/Index_.yr +0 -0
  38. /package/{lib → tests}/Yrci/Login.yr +0 -0
  39. /package/{lib → tests}/Yrci/M1.yr +0 -0
  40. /package/{lib → tests}/Yrci/Sp.yr +0 -0
  41. /package/{lib → tests}/Yrci/T1.yr +0 -0
  42. /package/{lib → tests}/Yrci/T2.yr +0 -0
  43. /package/{lib → tests}/Yrci/Ta1.yr +0 -0
  44. /package/{lib → tests}/Yrci/Ta2.yr +0 -0
  45. /package/{lib → tests}/Yrci/Tg.yr +0 -0
  46. /package/{lib → tests}/Yrci/Wr.yr +0 -0
  47. /package/{lib → tests}/Yrci/Wrapper.yr +0 -0
  48. /package/{lib → tests}/Yrci/Wrapper1.yr +0 -0
  49. /package/{lib → tests}/Yrci/Wrapper2.yr +0 -0
  50. /package/{lib → tests}/Yrci/Wrapper3.yr +0 -0
  51. /package/{lib → tests}/Yrci/Wrapperext.yr +0 -0
  52. /package/{lib → tests}/Yrci/Wrt.yr +0 -0
  53. /package/{lib → tests}/Yrci/Yrwm.yr +0 -0
  54. /package/{lib → tests}/Yrci/a1.yr +0 -0
  55. /package/{lib → tests}/Yrci/a2.yr +0 -0
  56. /package/{lib → tests}/Yrci/app.yr +0 -0
  57. /package/{lib → tests}/Yrci/b2.yr +0 -0
  58. /package/{lib → tests}/Yrci/j1.yr +0 -0
  59. /package/{lib → tests}/Yrci/j2.yr +0 -0
  60. /package/{lib → tests}/Yrci/j3.yr +0 -0
  61. /package/{lib → tests}/Yrci/modal.yr +0 -0
package/CHANGELOG.md CHANGED
@@ -1,10 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.0] - 2026-08-18
4
+
5
+ Added React sections: `@@r`, `@@r`, `@<r`
6
+
7
+ See `/tests/Yrci/React.yr` to see an example
8
+
3
9
  ## [0.3.0] - 2026-04-27
4
10
 
5
- Remove `wrapperheader`, `header`, `scripts` and `footer` from parsedYr
6
- Created `wrapperheader` sections
7
- Added `VOID_TAGS` in order to not add elementId to all elements `if (preview === true)`
11
+ * Remove `wrapperheader`, `header`, `scripts` and `footer` from parsedYr
12
+ * Created `wrapperheader` sections
13
+ * Added `VOID_TAGS` in order to not add elementId to all elements `if (preview === true)`
8
14
 
9
15
  ## [0.2.0] - 2026-03-01
10
16
 
package/lib/@react.yr CHANGED
@@ -1,7 +1,10 @@
1
1
  %%
2
2
 
3
- _@renderReact(#query) {
4
- ReactDOM.createRoot(document.querySelector(#query)).render(
3
+ _@renderReact(#query, #app=App) {
4
+ import { useState, useEffect } from "react";
5
+ function #app() {
5
6
  ___
6
- );
7
+ }
8
+ ReactDOM.createRoot(document.querySelector(#query))
9
+ .render(<#app />);
7
10
  @}
package/lib/cdn.json ADDED
@@ -0,0 +1 @@
1
+ [{"isDir":false,"category":"Ciyr","option":"A1"},{"isDir":false,"category":"Ciyr","option":"B1"},{"isDir":false,"category":"Ciyr","option":"B2"},{"isDir":false,"category":"Ciyr","option":"C1"},{"isDir":false,"category":"Ciyr","option":"C2"},{"isDir":false,"category":"Ciyr","option":"C2_2"},{"isDir":false,"category":"Ciyr","option":"a1"},{"isDir":false,"category":"Ciyr","option":"b1"},{"isDir":false,"category":"Ciyr","option":"c1"},{"isDir":false,"category":"Yrci","option":"&app"},{"isDir":false,"category":"Yrci","option":"&app2"},{"isDir":false,"category":"Yrci","option":"@m1"},{"isDir":false,"category":"Yrci","option":"@m2"},{"isDir":false,"category":"Yrci","option":"A1"},{"isDir":false,"category":"Yrci","option":"A2"},{"isDir":false,"category":"Yrci","option":"A3"},{"isDir":false,"category":"Yrci","option":"B1"},{"isDir":false,"category":"Yrci","option":"C1"},{"isDir":false,"category":"Yrci","option":"C1r"},{"isDir":false,"category":"Yrci","option":"C2"},{"isDir":false,"category":"Yrci","option":"C3"},{"isDir":false,"category":"Yrci","option":"C4"},{"isDir":false,"category":"Yrci","option":"C5"},{"isDir":false,"category":"Yrci","option":"C6"},{"isDir":false,"category":"Yrci","option":"C7"},{"isDir":false,"category":"Yrci","option":"C8"},{"isDir":false,"category":"Yrci","option":"C9"},{"isDir":false,"category":"Yrci","option":"Index_"},{"isDir":false,"category":"Yrci","option":"Login"},{"isDir":false,"category":"Yrci","option":"M1"},{"isDir":false,"category":"Yrci","option":"React"},{"isDir":false,"category":"Yrci","option":"Sp"},{"isDir":false,"category":"Yrci","option":"T1"},{"isDir":false,"category":"Yrci","option":"T2"},{"isDir":false,"category":"Yrci","option":"Ta1"},{"isDir":false,"category":"Yrci","option":"Ta2"},{"isDir":false,"category":"Yrci","option":"Tg"},{"isDir":false,"category":"Yrci","option":"Wr"},{"isDir":false,"category":"Yrci","option":"Wrapper"},{"isDir":false,"category":"Yrci","option":"Wrapper1"},{"isDir":false,"category":"Yrci","option":"Wrapper2"},{"isDir":false,"category":"Yrci","option":"Wrapper3"},{"isDir":false,"category":"Yrci","option":"Wrapperext"},{"isDir":false,"category":"Yrci","option":"Wrt"},{"isDir":false,"category":"Yrci","option":"Yrwm"},{"isDir":false,"category":"Yrci","option":"a1"},{"isDir":false,"category":"Yrci","option":"a2"},{"isDir":false,"category":"Yrci","option":"app"},{"isDir":false,"category":"Yrci","option":"b2"},{"isDir":false,"category":"Yrci","option":"j1"},{"isDir":false,"category":"Yrci","option":"j2"},{"isDir":false,"category":"Yrci","option":"j3"},{"isDir":false,"category":"Yrci","option":"modal"},{"isDir":false,"category":false,"option":"%build"},{"isDir":false,"category":false,"option":"%deploy"},{"isDir":false,"category":false,"option":"%gh-pages"},{"isDir":false,"category":false,"option":"%nvm"},{"isDir":false,"category":false,"option":"%serve"},{"isDir":false,"category":false,"option":"@react"},{"isDir":false,"category":false,"option":"@try"},{"isDir":false,"category":false,"option":"@wrapper"},{"isDir":false,"category":false,"option":"bodyblock"},{"isDir":false,"category":false,"option":"ci"},{"isDir":false,"category":false,"option":"contenteditable"},{"isDir":false,"category":false,"option":"crypto"},{"isDir":false,"category":false,"option":"element"},{"isDir":false,"category":false,"option":"hidden"},{"isDir":false,"category":false,"option":"utils"}]
package/lib/index.js ADDED
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ const path = require('path');
3
+ const fs = require('fs');
4
+ const yr = require(path.join(__dirname, '../node'));
5
+
6
+ fs.writeFileSync(path.join(__dirname, 'cdn.json'),
7
+ JSON.stringify(yr.tree(__dirname, { yr: true })));
package/node.js CHANGED
@@ -501,7 +501,7 @@ for (let item of ['HOME', 'LIBS', 'BUILDS', 'TREE', 'CONFIG']) {
501
501
  env.BUILDS, projectPath,
502
502
  `${projectPath}/www`, `${projectPath}/www/assets`,
503
503
  `${projectPath}/app`, `${projectPath}/app/assets`,
504
- `${projectPath}/actions`
504
+ `${projectPath}/actions`, `${projectPath}/bin`
505
505
  ]) { if (!fs.existsSync(item)) fs.mkdirSync(item, { recursive: true }); }
506
506
 
507
507
  fs.writeFileSync(projectPath + '/.gitignore', `*/node_modules/
@@ -527,6 +527,17 @@ package*.json
527
527
  fs.writeFileSync(`${projectPath}/requirements.txt`, requirements);
528
528
 
529
529
  for (let item in result.devops) {
530
+ if (result.devops[item].split('\n')[0].endsWith('cpp')) {
531
+ let _code = result.devops[item].split('\n');
532
+ _code.shift();
533
+ _code = _code.join('\n').trim();
534
+ let filename = item;
535
+ if (!filename.endsWith('.cpp')) filename += '.cpp';
536
+ const srcPath= `${projectPath}/bin/${item}.cpp`;
537
+ fs.writeFileSync(srcPath, _code);
538
+ spawn('g++', [srcPath, '-o', `${projectPath}/bin/${item}.exe`, '-O2']);
539
+ continue;
540
+ }
530
541
  fs.writeFileSync(`${projectPath}/actions/${item}`, result.devops[item])
531
542
  spawn('chmod', ['+x', `${projectPath}/actions/${item}`]);
532
543
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yr-lang/yr",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "Yr is a modern structural language and parser",
5
5
  "main": "./node.js",
6
6
  "exports": {
package/tests/.yrrc ADDED
@@ -0,0 +1,2 @@
1
+ NAME=yrtests
2
+ DESCRIPTION=Built-in yr tests
@@ -1,6 +1,6 @@
1
1
  @@
2
2
 
3
- TesteA1
3
+ alert(1);
4
4
 
5
5
  ++
6
6
 
@@ -6,13 +6,10 @@ _ #root
6
6
 
7
7
  @@r
8
8
 
9
- import { useState, useEffect } from "react";
10
- function App() {
9
+ _@renderReact('#root') {
11
10
  const [count, setCount] = useState(0);
12
11
  const [message, setMessage] = useState('Loading...');
13
- useEffect(() => {
14
- setMessage(`Count is ${count}`);
15
- }, [count]);
12
+ useEffect(() => setMessage(`Count is ${count}`), [count]);
16
13
  return (
17
14
  <div>
18
15
  <h1>Simple React App</h1>
@@ -22,8 +19,4 @@ function App() {
22
19
  </button>
23
20
  </div>
24
21
  );
25
- }
26
-
27
- _@renderReact('#root') {
28
- <App />
29
22
  @}
package/yr.js CHANGED
@@ -40,6 +40,14 @@ const namespaces = {
40
40
  '@@r': { name: 'jsreact', parser: 'string', default: '', merge: true },
41
41
  '@<r': { name: 'jsfooterreact', parser: 'string', default: '', merge: true },
42
42
  '<@r': { name: 'wrapperjscustomreact', parser: 'string', default: '', merge: true },
43
+ '@@t': { name: 'jsts', parser: 'string', default: '', merge: true },
44
+ '@>t': { name: 'jsheaderts', parser: 'string', default: '', merge: true },
45
+ '@<t': { name: 'jsfooterts', parser: 'string', default: '', merge: true },
46
+ '<@t': { name: 'wrapperjscustomts', parser: 'string', default: '', merge: true },
47
+ '@@x': { name: 'jstsx', parser: 'string', default: '', merge: true },
48
+ '@>x': { name: 'jsheadertsx', parser: 'string', default: '', merge: true },
49
+ '@<x': { name: 'jsfootertsx', parser: 'string', default: '', merge: true },
50
+ '<@x': { name: 'wrapperjscustomtsx', parser: 'string', default: '', merge: true },
43
51
  '""': { name: 'documentation', parser: 'string', default: '' },
44
52
  '--': { name: 'modules', parser: 'object', default: [], merge: true },
45
53
  '==': { name: 'pixel', parser: 'string', default: '', merge: true },
@@ -73,27 +81,92 @@ for (let item of Object.keys(namespaces)) {
73
81
  }
74
82
  }
75
83
 
76
- let viewType;
77
- function transformReact(code, sections, section, config) {
78
- code = module.exports.macros(sections, section);
84
+ let viewType, scriptUrl, builtInLib = {};
85
+
86
+ const JS_KINDS = {
87
+ react: {
88
+ suffix: 'react',
89
+ loader: 'jsx',
90
+ babelPresets: [['react', { runtime: 'classic' }]],
91
+ modules: ['react', 'react-dom'],
92
+ npmImports: "import React from 'react';\nimport ReactDOM from 'react-dom/client';\n",
93
+ cdnShimModules: {
94
+ 'react': 'window.React',
95
+ 'react-dom': 'window.ReactDOM',
96
+ 'react-dom/client': 'window.ReactDOM'
97
+ }
98
+ },
99
+ ts: {
100
+ suffix: 'ts',
101
+ loader: 'ts',
102
+ babelPresets: ['typescript'],
103
+ modules: [],
104
+ npmImports: '',
105
+ cdnShimModules: {}
106
+ },
107
+ tsx: {
108
+ suffix: 'tsx',
109
+ loader: 'tsx',
110
+ babelPresets: [['react', { runtime: 'classic' }], 'typescript'],
111
+ modules: ['react', 'react-dom'],
112
+ npmImports: "import React from 'react';\nimport ReactDOM from 'react-dom/client';\n",
113
+ cdnShimModules: {
114
+ 'react': 'window.React',
115
+ 'react-dom': 'window.ReactDOM',
116
+ 'react-dom/client': 'window.ReactDOM'
117
+ }
118
+ }
119
+ };
120
+
121
+ function transformJS(code, kind, sections, section, config) {
122
+ const spec = JS_KINDS[kind];
123
+ if (!spec) throw `Yr: tipo desconhecido em transformJS: ${kind}`;
124
+
125
+ code = core.macros(sections, section);
79
126
 
80
127
  if (viewType === 'cdn') {
81
- if (!window.Babel) throw 'Babel unavailable';
82
- return window.Babel.transform(code, { presets: ['react'] }).code;
128
+ if (!window.Babel) return `alert("Babel unavailable (${kind})");`;
129
+
130
+ const needsShim = Object.keys(spec.cdnShimModules).length > 0;
131
+ const plugins = needsShim ? ['transform-modules-commonjs'] : [];
132
+
133
+ const transformed = window.Babel.transform(code, {
134
+ presets: spec.babelPresets, plugins,
135
+ filename: `file.${kind === 'react' ? 'jsx' : kind}`
136
+ }).code;
137
+
138
+ if (!needsShim) return transformed; // ts puro não importa nada shimável, não precisa embrulhar
139
+
140
+ const shimEntries = Object.entries(spec.cdnShimModules)
141
+ .map(([name, ref]) => `'${name}': ${ref}`).join(',\n ');
142
+
143
+ const shim = `
144
+ const require = (function () {
145
+ const modules = { ${shimEntries} };
146
+ return function (name) {
147
+ if (modules[name]) return modules[name];
148
+ throw new Error('Módulo não disponível no runtime cdn: ' + name);
149
+ };
150
+ })();
151
+ const exports = {};
152
+ const module = { exports };
153
+ `;
154
+
155
+ return `(function(){\n${shim}\n${transformed}\n})();`;
83
156
  }
84
157
 
85
158
  if (viewType === 'npm') {
86
- for (let item of ['react', 'react-dom']) {
159
+ for (let item of spec.modules) {
87
160
  if (sections.modules.includes(item)) continue;
88
- sections.modules.push(item)
161
+ sections.modules.push(item);
89
162
  }
163
+
90
164
  try {
91
165
  const esbuild = require('esbuild');
92
- code = "import React from 'react';\n"
93
- + "import ReactDOM from 'react-dom/client';\n" + code;
166
+ code = spec.npmImports + code;
94
167
  const result = esbuild.buildSync({
95
168
  stdin: {
96
- contents: code, loader: 'jsx',
169
+ contents: code, loader: spec.loader,
97
170
  resolveDir: config.projectPath || process.cwd()
98
171
  },
99
172
  bundle: true, write: false, format: 'iife',
@@ -108,7 +181,7 @@ function transformReact(code, sections, section, config) {
108
181
  if (!unresolved) throw error;
109
182
 
110
183
  if (sections) sections.reactBuildFailed = true;
111
- return '';
184
+ return `alert("esbuild error (${kind})");`;
112
185
  }
113
186
  }
114
187
  }
@@ -672,6 +745,12 @@ const parsers = {
672
745
  const core = {
673
746
  set(libFn) { this.lib = libFn },
674
747
  lib(category=false, option=false, parseConfig=false) {
748
+ if (typeof window !== 'undefined') {
749
+ return (category && option) ? builtInLib[`${
750
+ (category === '__') ? '' : category + '/'
751
+ }${option}`.replace(/\.yr/g, '')] : builtInLib;
752
+ }
753
+
675
754
  return { yr: '++\n\n_' };
676
755
  },
677
756
  macros(sections, key, obfuscate=false) {
@@ -1275,12 +1354,16 @@ const core = {
1275
1354
  if (section === 'macros')
1276
1355
  this.aux(sections, { macrosAux: sections.macrosAux });
1277
1356
 
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
- }
1357
+ for (let kind in JS_KINDS) {
1358
+ const suffix = JS_KINDS[kind].suffix;
1359
+ if (section.endsWith(suffix)) {
1360
+ sections[section.slice(0, -suffix.length)] +=
1361
+ transformJS(sections[section], kind, sections, config) + '\n';
1362
+ sections[section] = '';
1363
+ if (JS_KINDS[kind].modules.includes('react')) sections.reactUsed = true;
1364
+ break;
1365
+ }
1366
+ }
1284
1367
 
1285
1368
  section = parsers.namespaces[line].name;
1286
1369
  state.sectionChanged = true;
@@ -1379,12 +1462,16 @@ const core = {
1379
1462
  lineNumber++;
1380
1463
  }
1381
1464
 
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
- }
1465
+ for (let kind in JS_KINDS) {
1466
+ const suffix = JS_KINDS[kind].suffix;
1467
+ if (section.endsWith(suffix)) {
1468
+ sections[section.slice(0, -suffix.length)] +=
1469
+ transformJS(sections[section], kind, sections, config) + '\n';
1470
+ sections[section] = '';
1471
+ if (JS_KINDS[kind].modules.includes('react')) sections.reactUsed = true;
1472
+ break;
1473
+ }
1474
+ }
1388
1475
 
1389
1476
  section = false;
1390
1477
 
@@ -1910,6 +1997,36 @@ if (typeof module !== 'undefined' && module.exports) {
1910
1997
  if (typeof window !== 'undefined' && !window.yr) {
1911
1998
  viewType = 'cdn';
1912
1999
  window.yr = core.parse.bind(core);
2000
+ scriptUrl = document.currentScript?.src;
2001
+ const scripts = [
2002
+ 'https://unpkg.com/react@18/umd/react.production.min.js',
2003
+ 'https://unpkg.com/react-dom@18/umd/react-dom.production.min.js',
2004
+ 'https://unpkg.com/@babel/standalone/babel.min.js'
2005
+ ];
2006
+ scripts.forEach(src => {
2007
+ const script = document.createElement('script');
2008
+ script.src = src;
2009
+ document.head.appendChild(script);
2010
+ });
2011
+ function getWrapperName(item) {
2012
+ return (item.category && item.category !== 'yr')
2013
+ ? `${item.category}/${item.option}` : item.option;
2014
+ }
2015
+ async function setBuiltInLib() {
2016
+ const base = new URL('./lib/', scriptUrl);
2017
+ let lib = await fetch(new URL('./cdn.json', base));
2018
+ lib = await lib.json();
2019
+ for (let item of lib) {
2020
+ const wrapperName = getWrapperName(item);
2021
+ delete item.isDir;
2022
+ const res = await
2023
+ fetch(new URL(encodeURIComponent(`./${wrapperName}.yr`), base));
2024
+ item.yr = await res.text()
2025
+ //item.output = core.parse(item.yr);
2026
+ builtInLib[wrapperName] = item;
2027
+ }
2028
+ }
2029
+ setBuiltInLib();
1913
2030
 
1914
2031
  //const createLog = (text) => {
1915
2032
  // const parsed = parse(text);
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes