Skip to content

Commit 2f1e59b

Browse files
authored
Merge pull request #24 from OpenScriptJs/develop
Develop
2 parents 9facfaa + 850bb79 commit 2f1e59b

File tree

5 files changed

+317
-4
lines changed

5 files changed

+317
-4
lines changed

OpenScript.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* The OpenScript Namespace
33
* @namespace {OpenScript}
44
*/
5-
var OpenScript = {
5+
let OpenScript = {
66
/**
77
* Used to Run Classes upon creation
88
*/
@@ -2406,7 +2406,7 @@ var OpenScript = {
24062406
* Refreshes the whole context
24072407
*/
24082408
refresh() {
2409-
this.map.clear;
2409+
this.map.clear();
24102410
}
24112411
},
24122412

example/ojs-config.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ broker.removeStaleEvents();
133133
| in the console as they are fired
134134
|------------------------------------------
135135
*/
136-
if(/^(127\.0\.0\.1|localhost)$/.test(route.url().hostname)) {
136+
if(/^(127\.0\.0\.1|localhost|.*\.test)$/.test(route.url().hostname)) {
137137
broker.withLogs(true);
138138
}
139139

@@ -145,4 +145,12 @@ if(/^(127\.0\.0\.1|localhost)$/.test(route.url().hostname)) {
145145
* can be listened to and fire by the broker.
146146
* ---------------------------------------------
147147
*/
148-
broker.requireEventsRegistration(true);
148+
broker.requireEventsRegistration(true);
149+
150+
/**
151+
* ---------------------------------------------
152+
* Initialize the router if you need it to run.
153+
* ---------------------------------------------
154+
*
155+
*/
156+
//router.init();

grouper.js

Lines changed: 294 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,294 @@
1+
const fs = require("fs");
2+
const path = require("path");
3+
4+
const config = require("./ojs-config.json");
5+
6+
/**
7+
* Splits a file into smaller strings
8+
* based on the class in that file
9+
*/
10+
class Splitter {
11+
/**
12+
* Gets the class Signature
13+
* @param {string} content
14+
* @param {int} start
15+
* @param {object<>} signature {name: string, signature: string, start: number, end: number}
16+
*/
17+
classSignature(content, start) {
18+
const signature = {
19+
name: "",
20+
definition: "",
21+
start: -1,
22+
end: -1,
23+
parent: null,
24+
};
25+
26+
let startAt = start;
27+
28+
let output = [];
29+
let tmp = "";
30+
31+
let pushTmp = (index) => {
32+
if (tmp.length === 0) return;
33+
34+
if (output.length === 0) startAt = index;
35+
36+
output.push(tmp);
37+
tmp = "";
38+
};
39+
40+
for (let i = start; i < content.length; i++) {
41+
let ch = content[i];
42+
43+
if (/[\s\r\t\n]/.test(ch)) {
44+
pushTmp(i);
45+
46+
continue;
47+
}
48+
49+
if (/\{/.test(ch)) {
50+
pushTmp(i);
51+
signature.end = i;
52+
53+
break;
54+
}
55+
56+
tmp += ch;
57+
}
58+
59+
signature.start = startAt;
60+
61+
if (output.length && output[0] !== "class") {
62+
let temp = [];
63+
temp[0] = output[0];
64+
temp[1] = output.splice(1).join(" ");
65+
output = temp;
66+
}
67+
68+
if (output.length % 2 !== 0)
69+
throw Error(
70+
`Invalid Class File. Could not parse \`${content}\` from index ${start} because it doesn't have the proper syntax. ${content.substring(
71+
start
72+
)}`
73+
);
74+
75+
if (output.length > 2) {
76+
signature.parent = output[3];
77+
}
78+
79+
signature.name = output[1];
80+
signature.definition = output.join(" ");
81+
82+
return signature;
83+
}
84+
85+
/**
86+
* Splits the content of the file by
87+
* class
88+
* @param {string} content file content
89+
* @return {Map<string,string>} class map
90+
*/
91+
classes(content) {
92+
content = content.trim();
93+
94+
const stack = [];
95+
const map = new Map();
96+
const qMap = new Map([
97+
[`'`, true],
98+
[`"`, true],
99+
["`", true],
100+
]);
101+
102+
let index = 0;
103+
let code = "";
104+
105+
while (index < content.length) {
106+
let signature = this.classSignature(content, index);
107+
index = signature.end;
108+
109+
let ch = content[index];
110+
stack.push(ch);
111+
112+
code += signature.definition + " ";
113+
code += ch;
114+
115+
let text = [];
116+
117+
index++;
118+
119+
while (stack.length && index < content.length) {
120+
ch = content[index];
121+
code += ch;
122+
123+
if (qMap.has(ch)) {
124+
text.push(ch);
125+
index++;
126+
127+
while (text.length && index < content.length) {
128+
ch = content[index];
129+
code += ch;
130+
131+
let last = text.length - 1;
132+
133+
if (qMap.has(ch) && ch === text[last]) {
134+
text.pop();
135+
} else if (
136+
ch === "\n" &&
137+
(text[last] === '"' || text[last] === "'")
138+
) {
139+
text.pop();
140+
}
141+
142+
index++;
143+
}
144+
continue;
145+
}
146+
if (/\{/.test(ch)) stack.push(ch);
147+
if (/\}/.test(ch)) stack.pop();
148+
149+
index++;
150+
}
151+
152+
signature.name = signature.name.split(/\(/)[0];
153+
154+
map.set(signature.name, {
155+
extends: signature.parent,
156+
code,
157+
name: signature.name,
158+
signature: signature.definition,
159+
});
160+
161+
code = "";
162+
}
163+
164+
return map;
165+
}
166+
}
167+
168+
class Grouper extends Splitter {
169+
/**
170+
*
171+
* @param {array} filePaths
172+
* @returns all the classes from all the files with the filePaths array
173+
*/
174+
175+
async classesFromFilePath(filePaths) {
176+
let cls = "";
177+
const params = {};
178+
const names = {};
179+
let i = 1;
180+
181+
for (let filePath of filePaths) {
182+
const classesContent = fs.readFileSync(filePath, "utf-8");
183+
const map = this.classes(classesContent);
184+
185+
for(let [key, {code, name, extends: parent, signature}] of map) {
186+
187+
if(/OpenScript\.Mediator/.test(parent) && !/.*Mediator$/.test(name)) {
188+
let newName = `${name}Mediator`;
189+
let newSig = signature.replace(`${name} `, `${newName} `);
190+
let newCode = code.replace(signature, newSig);
191+
192+
code = newCode;
193+
name = newName;
194+
signature = newSig;
195+
}
196+
197+
if(name in names) {
198+
let newName = `${name}${i++}`;
199+
let newSig = signature.replace(`${name} `, `${newName} `);
200+
let newCode = code.replace(signature, newSig);
201+
202+
code = newCode;
203+
name = newName;
204+
signature = newSig;
205+
}
206+
207+
names[name] = true;
208+
209+
cls += code + "\n";
210+
params[name] = true;
211+
}
212+
}
213+
return {code: cls, params: Object.keys(params)};
214+
}
215+
216+
/**
217+
*
218+
* @param {*} filePaths wraps all the code from a specified file path in the ojs function
219+
*/
220+
221+
async wrapClassesFromFilePath(filePaths) {
222+
try {
223+
let {code, params} = await this.classesFromFilePath(filePaths);
224+
225+
let finalCode = `${code}\nojs(${params.join(',')});`
226+
227+
this.consolidateToFile(finalCode);
228+
} catch (error) {
229+
console.error("Error printing class names:", error);
230+
}
231+
}
232+
/**
233+
*
234+
* @param {string} consolidatedCode takes in the consolidated code and then creates a
235+
* dotOjs file with that has all the code from all the classes wrapped in the ojs function
236+
*/
237+
238+
async consolidateToFile(consolidatedCode) {
239+
const consolidatedFile = config.output_dir + "/" + config.output_file;
240+
fs.writeFileSync(consolidatedFile, consolidatedCode, "utf-8");
241+
console.log(`Wrapped code has been written to ${consolidatedFile}`);
242+
}
243+
244+
/**
245+
*
246+
* @param {string} dir
247+
* @param {string} files
248+
* @returns an array of all the paths in the given directory
249+
*/
250+
async getFilePaths(dir, files = []) {
251+
const fileList = fs.readdirSync(dir);
252+
for (const file of fileList) {
253+
const name = `${dir}/${file}`;
254+
if (fs.statSync(name).isDirectory()) {
255+
this.getFilePaths(name, files);
256+
} else {
257+
files.push(name);
258+
}
259+
}
260+
return files;
261+
}
262+
/**
263+
*
264+
* @returns all the grouped code by making use of the getFilePaths method and
265+
* wrapClassesFromFilePath
266+
*/
267+
268+
async group() {
269+
try {
270+
let AllPaths = [];
271+
for (let key in config.dir) {
272+
let dir = config.dir[key];
273+
let directories = await grouper.getFilePaths(dir);
274+
AllPaths.push(directories);
275+
}
276+
let paths = AllPaths;
277+
278+
let configPaths = [];
279+
for (let path of paths) {
280+
for (let directory of path) {
281+
configPaths.push(directory);
282+
}
283+
}
284+
console.log(configPaths);
285+
let code = await grouper.wrapClassesFromFilePath(configPaths);
286+
return code;
287+
} catch (error) {
288+
console.error("Error getting all classes:", error);
289+
}
290+
}
291+
}
292+
293+
const grouper = new Grouper();
294+
grouper.group();

ojs-config.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
{
2+
"dir": {
3+
"components": "./js/components",
4+
"mediators": "./js/mediators",
5+
"contexts": "./js/contexts"
6+
},
7+
"output_file": "consolidated-ojs.js",
8+
"output_dir": "./js/app"
9+
}

readme.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1055,6 +1055,8 @@ function Clock(...args) {
10551055
> You can even return a full `OSM` from the `v` function.
10561056
10571057
##### Component Events
1058+
During it's lifecycle, components emit events. You can listen to these events internally or from another component. Below are the events:
1059+
10581060
###### Listening to Internal Events
10591061
###### Listening to Other Components' Events
10601062
###### Late Reaction

0 commit comments

Comments
 (0)