@yr-lang/yr 0.3.15 → 0.4.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/lib/@react.yr ADDED
@@ -0,0 +1,10 @@
1
+ %%
2
+
3
+ _@renderReact(#query, #app=App) {
4
+ import { useState, useEffect } from "react";
5
+ function #app() {
6
+ ___
7
+ }
8
+ ReactDOM.createRoot(document.querySelector(#query))
9
+ .render(<#app />);
10
+ @}
package/lib/Yrci/A1.yr CHANGED
@@ -1,6 +1,6 @@
1
1
  @@
2
2
 
3
- TesteA1
3
+ alert(1);
4
4
 
5
5
  ++
6
6
 
@@ -0,0 +1,22 @@
1
+ !! @react
2
+
3
+ ++
4
+
5
+ _ #root
6
+
7
+ @@r
8
+
9
+ _@renderReact('#root') {
10
+ const [count, setCount] = useState(0);
11
+ const [message, setMessage] = useState('Loading...');
12
+ useEffect(() => setMessage(`Count is ${count}`), [count]);
13
+ return (
14
+ <div>
15
+ <h1>Simple React App</h1>
16
+ <p>{message}</p>
17
+ <button onClick={() => setCount(count + 1)}>
18
+ Count: {count}
19
+ </button>
20
+ </div>
21
+ );
22
+ @}
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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yr-lang/yr",
3
- "version": "0.3.15",
3
+ "version": "0.4.1",
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,67 @@ for (let item of Object.keys(namespaces)) {
69
73
  }
70
74
  }
71
75
 
76
+ let viewType, scriptUrl, builtInLib = {};
77
+ function transformReact(code, sections, section, config) {
78
+ code = core.macros(sections, section);
79
+
80
+ if (viewType === 'cdn') {
81
+ if (!window.Babel) return 'alert("Babel unavailable");';
82
+ const transformed = window.Babel.transform(code, {
83
+ presets: [['react', { runtime: 'classic' }]],
84
+ plugins: ['transform-modules-commonjs']
85
+ }).code;
86
+
87
+ const shim = `
88
+ const require = (function () {
89
+ const modules = {
90
+ 'react': window.React,
91
+ 'react-dom': window.ReactDOM,
92
+ 'react-dom/client': window.ReactDOM
93
+ };
94
+ return function (name) {
95
+ if (modules[name]) return modules[name];
96
+ throw new Error('Módulo não disponível no runtime cdn: ' + name);
97
+ };
98
+ })();
99
+ const exports = {};
100
+ const module = { exports };
101
+ `;
102
+
103
+ return `(function(){\n${shim}\n${transformed}\n})();`;
104
+ }
105
+
106
+ if (viewType === 'npm') {
107
+ for (let item of ['react', 'react-dom']) {
108
+ if (sections.modules.includes(item)) continue;
109
+ sections.modules.push(item)
110
+ }
111
+ try {
112
+ const esbuild = require('esbuild');
113
+ code = "import React from 'react';\n"
114
+ + "import ReactDOM from 'react-dom/client';\n" + code;
115
+ const result = esbuild.buildSync({
116
+ stdin: {
117
+ contents: code, loader: 'jsx',
118
+ resolveDir: config.projectPath || process.cwd()
119
+ },
120
+ bundle: true, write: false, format: 'iife',
121
+ nodePaths: [path.join(__dirname, 'node_modules')]
122
+ });
123
+ return result.outputFiles[0].text;
124
+ } catch (error) {
125
+ console.log(error);
126
+ const unresolved = error.errors
127
+ && error.errors.some(item => item.text.startsWith('Could not resolve'));
128
+
129
+ if (!unresolved) throw error;
130
+
131
+ if (sections) sections.reactBuildFailed = true;
132
+ return 'alert("esbuild error");';
133
+ }
134
+ }
135
+ }
136
+
72
137
  function parseLine(line) {
73
138
  const indentation = line.search(/\S/);
74
139
 
@@ -628,6 +693,12 @@ const parsers = {
628
693
  const core = {
629
694
  set(libFn) { this.lib = libFn },
630
695
  lib(category=false, option=false, parseConfig=false) {
696
+ if (typeof window !== 'undefined') {
697
+ return (category && option) ? builtInLib[`${
698
+ (category === '__') ? '' : category + '/'
699
+ }${option}`.replace(/\.yr/g, '')] : builtInLib;
700
+ }
701
+
631
702
  return { yr: '++\n\n_' };
632
703
  },
633
704
  macros(sections, key, obfuscate=false) {
@@ -1231,6 +1302,13 @@ const core = {
1231
1302
  if (section === 'macros')
1232
1303
  this.aux(sections, { macrosAux: sections.macrosAux });
1233
1304
 
1305
+ if (section.endsWith('react')) {
1306
+ sections[section.replace(/react/, '')] +=
1307
+ transformReact(sections[section], sections, section, config) + '\n';
1308
+ sections[section] = '';
1309
+ sections.reactUsed = true;
1310
+ }
1311
+
1234
1312
  section = parsers.namespaces[line].name;
1235
1313
  state.sectionChanged = true;
1236
1314
 
@@ -1328,6 +1406,13 @@ const core = {
1328
1406
  lineNumber++;
1329
1407
  }
1330
1408
 
1409
+ if (section.endsWith('react')) {
1410
+ sections[section.replace(/react/, '')] +=
1411
+ transformReact(sections[section], sections, section, config) + '\n';
1412
+ sections[section] = '';
1413
+ sections.reactUsed = true;
1414
+ }
1415
+
1331
1416
  section = false;
1332
1417
 
1333
1418
  if (config.wrapper && sections.wrappersAux
@@ -1812,6 +1897,10 @@ ${sections.pixel}
1812
1897
  <head>
1813
1898
  ${sections.parsedheader}
1814
1899
  ${(config.name) ? ` <link rel="stylesheet" href="./${config.cssname}.css">` : ` <style>\n${sections.parsedcss}\n</style>`}
1900
+ ${sections.reactUsed && viewType === 'cdn'
1901
+ ? ' <s' + 'cript src="https://unpkg.com/react@18/umd/react.production.min.js"></scri' + 'pt>\n' +
1902
+ ' <s' + 'cript src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js"></scri' + 'pt>'
1903
+ : ''}
1815
1904
  </head>
1816
1905
  <body style="display: none">
1817
1906
  ${sections.parsedbody}
@@ -1840,12 +1929,44 @@ document.addEventListener('DOMContentLoaded', () => {
1840
1929
  parsers
1841
1930
  };
1842
1931
 
1843
- if (typeof module !== 'undefined' && module.exports)
1932
+ if (typeof module !== 'undefined' && module.exports) {
1933
+ viewType = 'npm';
1844
1934
  module.exports = core;
1935
+ }
1845
1936
 
1846
1937
  if (typeof window !== 'undefined' && !window.yr) {
1847
- const parse = core.parse.bind(core);
1848
- window.yr = parse;
1938
+ viewType = 'cdn';
1939
+ window.yr = core.parse.bind(core);
1940
+ scriptUrl = document.currentScript?.src;
1941
+ const scripts = [
1942
+ 'https://unpkg.com/react@18/umd/react.production.min.js',
1943
+ 'https://unpkg.com/react-dom@18/umd/react-dom.production.min.js',
1944
+ 'https://unpkg.com/@babel/standalone/babel.min.js'
1945
+ ];
1946
+ scripts.forEach(src => {
1947
+ const script = document.createElement('script');
1948
+ script.src = src;
1949
+ document.head.appendChild(script);
1950
+ });
1951
+ function getWrapperName(item) {
1952
+ return (item.category && item.category !== 'yr')
1953
+ ? `${item.category}/${item.option}` : item.option;
1954
+ }
1955
+ async function setBuiltInLib() {
1956
+ const base = new URL('./lib/', scriptUrl);
1957
+ let lib = await fetch(new URL('./cdn.json', base));
1958
+ lib = await lib.json();
1959
+ for (let item of lib) {
1960
+ const wrapperName = getWrapperName(item);
1961
+ delete item.isDir;
1962
+ const res = await
1963
+ fetch(new URL(encodeURIComponent(`./${wrapperName}.yr`), base));
1964
+ item.yr = await res.text()
1965
+ //item.output = core.parse(item.yr);
1966
+ builtInLib[wrapperName] = item;
1967
+ }
1968
+ }
1969
+ setBuiltInLib();
1849
1970
 
1850
1971
  //const createLog = (text) => {
1851
1972
  // const parsed = parse(text);