onejs-core 2.0.19 → 2.0.21

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.
@@ -26,6 +26,7 @@ declare global {
26
26
  }
27
27
 
28
28
  const document: DocumentWrapper
29
+ const onejsDocument: DocumentWrapper
29
30
  const setTimeout: (callback: () => void, delay?: number) => number
30
31
  const clearTimeout: (id: number) => void
31
32
  const setInterval: (callback: () => void, delay?: number) => number
package/dist/index.js CHANGED
@@ -33,9 +33,12 @@ export function h(type, props, ...children) {
33
33
  return element;
34
34
  }
35
35
  export { emo } from "./styling/index";
36
- // @ts-ignore
37
- if (typeof ___document != "undefined") {
36
+ if (typeof globalThis.___document != "undefined") {
38
37
  // @ts-ignore
39
- globalThis.document = new DocumentWrapper(___document);
38
+ globalThis.onejsDocument = new DocumentWrapper(globalThis.___document);
39
+ if (!globalThis.ONEJS_WEBGL) {
40
+ // @ts-ignore
41
+ globalThis.document = globalThis.onejsDocument;
42
+ }
40
43
  }
41
44
  // puer.$extension(CS.UnityEngine.UIElements.VisualElement, CS.UnityEngine.UIElements.VisualElementExtensions)
@@ -1,5 +1,5 @@
1
1
  type float4 = CS.Unity.Mathematics.float4;
2
- declare var kCSSColorTable: {
2
+ declare const kCSSColorTable: {
3
3
  transparent: number[];
4
4
  aliceblue: number[];
5
5
  antiquewhite: number[];
@@ -27,7 +27,7 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27
27
  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28
28
  IN THE SOFTWARE.
29
29
  */
30
- var kCSSColorTable = {
30
+ const kCSSColorTable = {
31
31
  "transparent": [0, 0, 0, 0], "aliceblue": [240, 248, 255, 1],
32
32
  "antiquewhite": [250, 235, 215, 1], "aqua": [0, 255, 255, 1],
33
33
  "aquamarine": [127, 255, 212, 1], "azure": [240, 255, 255, 1],
package/index.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  /// <reference path="./definitions/index.d.ts" />
2
- import { DocumentWrapper } from "./dom/document";
3
- import { DomWrapper } from "./dom/dom";
2
+ import { DocumentWrapper } from "./dom/document"
3
+ import { DomWrapper } from "./dom/dom"
4
4
 
5
5
  /**
6
6
  * OneJS's own h function. Use this to quickly create elements in jsx-like syntax
@@ -10,29 +10,29 @@ import { DomWrapper } from "./dom/dom";
10
10
  * @returns
11
11
  */
12
12
  export function h(type: any, props: any, ...children: any[]): any {
13
- const element = typeof type === "string" ? document.createElement(type) : type;
13
+ const element = typeof type === "string" ? document.createElement(type) : type
14
14
 
15
15
  // Assign properties to the element
16
16
  for (const [key, value] of Object.entries(props || {})) {
17
17
  if (key.startsWith("on") && typeof value === "function") {
18
- element.addEventListener(key.substring(2).toLowerCase(), value);
18
+ element.addEventListener(key.substring(2).toLowerCase(), value)
19
19
  } else if (key === "style" && typeof value === "object") {
20
- Object.assign(element.style, value);
20
+ Object.assign(element.style, value)
21
21
  } else {
22
- element.setAttribute(key, value);
22
+ element.setAttribute(key, value)
23
23
  }
24
24
  }
25
25
 
26
26
  // Append children
27
27
  for (const child of children) {
28
28
  if (typeof child === "string") {
29
- element.appendChild(document.createTextNode(child));
29
+ element.appendChild(document.createTextNode(child))
30
30
  } else {
31
- element.appendChild(child);
31
+ element.appendChild(child)
32
32
  }
33
33
  }
34
34
 
35
- return element;
35
+ return element
36
36
  }
37
37
 
38
38
  export { emo } from "./styling/index"
@@ -46,10 +46,13 @@ declare global {
46
46
  const toJsArray: <T>(csArr: CS.System.Array) => T[]
47
47
  }
48
48
 
49
- // @ts-ignore
50
- if (typeof ___document != "undefined") {
49
+ if (typeof globalThis.___document != "undefined") {
51
50
  // @ts-ignore
52
- globalThis.document = new DocumentWrapper(___document)
51
+ globalThis.onejsDocument = new DocumentWrapper(globalThis.___document)
52
+ if (!globalThis.ONEJS_WEBGL) {
53
+ // @ts-ignore
54
+ globalThis.document = globalThis.onejsDocument
55
+ }
53
56
  }
54
57
 
55
58
  // puer.$extension(CS.UnityEngine.UIElements.VisualElement, CS.UnityEngine.UIElements.VisualElementExtensions)
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "onejs-core",
3
3
  "description": "The JS part of OneJS, a UI framework and Scripting Engine for Unity.",
4
- "version": "2.0.19",
4
+ "version": "2.0.21",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/Singtaa/onejs-core"
@@ -13,9 +13,9 @@ const projectDir = path.resolve(process.cwd(), '..')
13
13
  const manifestPath = path.join(projectDir, 'Packages', 'manifest.json')
14
14
 
15
15
  const backends = [
16
- { name: "QuickJS", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.1/PuerTS_Quickjs_2.2.1.tgz" },
17
- { name: "V8", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.1/PuerTS_V8_2.2.1.tgz" },
18
- { name: "NodeJS", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.1/PuerTS_Nodejs_2.2.1.tgz" }
16
+ { name: "QuickJS", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.2/PuerTS_Quickjs_2.2.2.tgz" },
17
+ { name: "V8", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.2/PuerTS_V8_2.2.2.tgz" },
18
+ { name: "NodeJS", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.2/PuerTS_Nodejs_2.2.2.tgz" }
19
19
  ]
20
20
 
21
21
  const args = process.argv.slice(2)
@@ -33,16 +33,16 @@ if (args.length > 0 && args[0].toLowerCase() == "clear") {
33
33
  } else if (
34
34
  args.length > 0 &&
35
35
  (["quickjs", "v8", "nodejs"].includes(args[0].toLowerCase()) ||
36
- (args[0].toLowerCase().endsWith('.tgz') || /^https?:\/\/.+\.tgz$/i.test(args[0])))
36
+ (args[0].toLowerCase().endsWith('.tgz') || /^https?:\/\/.+\.tgz$/i.test(args[0])))
37
37
  ) {
38
- let backend;
39
- const outputDir = "./tmp";
38
+ let backend
39
+ const outputDir = "./tmp"
40
40
  if (["quickjs", "v8", "nodejs"].includes(args[0].toLowerCase())) {
41
- backend = backends.find(b => b.name.toLowerCase() === args[0]);
41
+ backend = backends.find(b => b.name.toLowerCase() === args[0])
42
42
  } else {
43
- backend = { name: "Custom", tgzUrl: args[0] };
43
+ backend = { name: "Custom", tgzUrl: args[0] }
44
44
  }
45
- Process(backend, outputDir);
45
+ Process(backend, outputDir)
46
46
  } else {
47
47
  console.log("Usage: npm run switch <quickjs|v8|nodejs|clear|tgz-url>\n")
48
48
  console.log(" quickjs: Switch to QuickJS backend")
@@ -64,7 +64,7 @@ async function Process(backend, outputDir) {
64
64
  }
65
65
  await extractTgz(downloadedPath, outputDir)
66
66
 
67
- // Safe keep asmdef files
67
+ // Safe keep asmdef files, et al.
68
68
  const onejsDir = await getOneJSUnityDir()
69
69
  const a = path.join(onejsDir, 'Puerts/Editor/com.tencent.puerts.core.Editor.asmdef')
70
70
  const b = path.join(upmDir, 'Editor/com.tencent.puerts.core.Editor.asmdef')
@@ -72,6 +72,9 @@ async function Process(backend, outputDir) {
72
72
  const d = path.join(upmDir, 'Runtime/com.tencent.puerts.core.asmdef')
73
73
  await fse.copy(a, b)
74
74
  await fse.copy(c, d)
75
+ const e = path.join(onejsDir, 'Puerts/Runtime/Src/Default/JsEnv.cs')
76
+ const f = path.join(upmDir, 'Runtime/Src/Default/JsEnv.cs')
77
+ await fse.copy(e, f)
75
78
 
76
79
  // Replace OneJS/Puerts with the new one
77
80
  const puertsDir = path.join(onejsDir, "Puerts")
@@ -95,130 +98,138 @@ async function Process(backend, outputDir) {
95
98
  // }
96
99
 
97
100
  async function getOneJSUnityDir() {
98
- let oneJSPath = null;
101
+ let oneJSPath = null
99
102
 
100
103
  // Step 1: Check manifest.json
101
104
  if (fs.existsSync(manifestPath)) {
102
- const manifestContent = fs.readFileSync(manifestPath, 'utf8');
103
- const manifestJson = JSON.parse(manifestContent);
104
-
105
- const dependencies = manifestJson.dependencies;
106
- const oneJSKey = 'com.dragonground.onejs';
107
-
108
- if (dependencies && dependencies[oneJSKey]) {
109
- const packagePath = dependencies[oneJSKey]; // e.g., "file:PATH/TO/OneJS"
110
- if (packagePath.startsWith('file:')) {
111
- oneJSPath = packagePath.substring(5); // Remove "file:" prefix
112
- oneJSPath = path.resolve(projectDir, oneJSPath);
113
- return oneJSPath;
105
+ const manifestContent = fs.readFileSync(manifestPath, "utf8")
106
+ let manifestJson
107
+ try { manifestJson = JSON.parse(manifestContent) } catch {
108
+ console.error('Could not parse manifest.json at ' + manifestPath)
109
+ return null
110
+ }
111
+
112
+ const dependencies = manifestJson && manifestJson.dependencies
113
+ const oneJSKeys = ["com.dragonground.onejs", "com.singtaa.onejs"]
114
+
115
+ if (dependencies) {
116
+ for (const key of oneJSKeys) {
117
+ const packagePath = dependencies[key]
118
+ if (typeof packagePath === "string") {
119
+ const v = packagePath.trim() // e.g., "file:PATH/TO/OneJS"
120
+ if (v.startsWith("file:")) {
121
+ oneJSPath = path.resolve(projectDir, v.substring(5)) // strip "file:"
122
+ return oneJSPath
123
+ }
124
+ }
114
125
  }
115
126
  }
116
127
  }
117
128
 
118
129
  // Step 2: If not found, parse OneJS.Runtime.csproj
119
130
  if (!oneJSPath) {
120
- const csprojPath = path.join(projectDir, 'OneJS.Runtime.csproj');
131
+ const csprojPath = path.join(projectDir, 'OneJS.Runtime.csproj')
121
132
 
122
133
  if (fs.existsSync(csprojPath)) {
123
- const csprojContent = fs.readFileSync(csprojPath, 'utf8');
124
- const parser = new xml2js.Parser();
134
+ const csprojContent = fs.readFileSync(csprojPath, 'utf8')
135
+ const parser = new xml2js.Parser()
125
136
 
126
137
  try {
127
- const result = await parser.parseStringPromise(csprojContent);
138
+ const result = await parser.parseStringPromise(csprojContent)
128
139
 
129
- const project = result.Project;
130
- const itemGroups = project.ItemGroup;
140
+ const project = result.Project
141
+ const itemGroups = project.ItemGroup
131
142
 
132
143
  if (itemGroups && itemGroups.length > 0) {
133
144
  for (const itemGroup of itemGroups) {
134
145
  if (itemGroup.Compile) {
135
146
  for (const compileItem of itemGroup.Compile) {
136
- const includePath = compileItem.$.Include;
147
+ const includePath = compileItem.$.Include
137
148
 
138
149
  // Normalize path separators for cross-platform compatibility
139
- const normalizedIncludePath = includePath.replace(/\\/g, '/');
140
- const searchIndex = normalizedIncludePath.indexOf('OneJS/Runtime/Engine/ScriptEngine.cs');
150
+ const normalizedIncludePath = includePath.replace(/\\/g, '/')
151
+ const searchIndex = normalizedIncludePath.indexOf('OneJS/Runtime/Engine/ScriptEngine.cs')
141
152
 
142
153
  if (searchIndex !== -1) {
143
- oneJSPath = normalizedIncludePath.substring(0, searchIndex + 'OneJS'.length);
144
- oneJSPath = path.resolve(projectDir, oneJSPath);
145
- return oneJSPath;
154
+ oneJSPath = normalizedIncludePath.substring(0, searchIndex + 'OneJS'.length)
155
+ oneJSPath = path.resolve(projectDir, oneJSPath)
156
+ return oneJSPath
146
157
  }
147
158
  }
148
159
  }
149
160
  }
150
161
  }
151
162
 
152
- console.error('Could not find OneJS path in csproj file.');
153
- return null;
163
+ console.error('Could not find OneJS path in csproj file.')
164
+ return null
154
165
  } catch (err) {
155
- console.error('Error parsing csproj file:', err);
156
- return null;
166
+ console.error('Error parsing csproj file:', err)
167
+ return null
157
168
  }
158
169
  } else {
159
- console.error('OneJS.Runtime.csproj file does not exist.');
160
- return null;
170
+ console.error('OneJS.Runtime.csproj file does not exist.')
171
+ return null
161
172
  }
162
173
  }
163
174
 
164
- return oneJSPath;
175
+ return oneJSPath
165
176
  }
166
177
 
167
178
  function ensureDirectoryExistence(filePath) {
168
- const dirname = path.dirname(filePath);
179
+ const dirname = path.dirname(filePath)
169
180
  if (fs.existsSync(dirname)) {
170
- return true;
181
+ return true
171
182
  }
172
- fs.mkdirSync(dirname, { recursive: true });
183
+ fs.mkdirSync(dirname, { recursive: true })
173
184
  }
174
185
 
175
186
  function getFilenameFromUrl(fileUrl) {
176
- const parsedUrl = url.parse(fileUrl);
177
- return path.basename(parsedUrl.pathname);
187
+ const parsedUrl = url.parse(fileUrl)
188
+ return path.basename(parsedUrl.pathname)
178
189
  }
179
190
 
180
191
  async function downloadFile(fileUrl, outputDir) {
181
- const filename = getFilenameFromUrl(fileUrl);
182
- const outputLocationPath = path.join(outputDir, filename);
192
+ const filename = getFilenameFromUrl(fileUrl)
193
+ const outputLocationPath = path.join(outputDir, filename)
183
194
 
184
- ensureDirectoryExistence(outputLocationPath);
195
+ ensureDirectoryExistence(outputLocationPath)
185
196
 
186
197
  // Check if file exists (keep existing code)
187
198
  if (fs.existsSync(outputLocationPath)) {
188
- console.log(`Local .tgz found: ${outputLocationPath}`);
189
- return outputLocationPath;
199
+ console.log(`Local .tgz found: ${outputLocationPath}`)
200
+ return outputLocationPath
190
201
  }
191
202
 
192
- console.log(`Downloading ${filename}`);
193
- const response = await fetch(fileUrl);
203
+ console.log(`Downloading ${filename}`)
204
+ const response = await fetch(fileUrl)
194
205
 
195
206
  if (!response.ok) {
196
- throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`);
207
+ throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`)
197
208
  }
198
209
 
199
210
  // Get the total size for the progress bar
200
- const totalSize = parseInt(response.headers.get('content-length'), 10);
201
-
211
+ const totalSize = parseInt(response.headers.get('content-length'), 10)
212
+
202
213
  // Create progress bar
203
214
  const progressBar = new ProgressBar('[:bar] :percent ETA: :etas', {
204
215
  complete: '=',
205
216
  incomplete: ' ',
206
217
  width: 40,
207
218
  total: totalSize
208
- });
219
+ })
209
220
 
210
- const fileStream = fs.createWriteStream(outputLocationPath);
221
+ const fileStream = fs.createWriteStream(outputLocationPath)
211
222
  for await (const chunk of response.body) {
212
- fileStream.write(chunk);
213
- progressBar.tick(chunk.length);
223
+ fileStream.write(chunk)
224
+ progressBar.tick(chunk.length)
214
225
  }
215
226
 
216
- fileStream.end();
227
+ fileStream.end()
217
228
 
218
229
  return new Promise((resolve, reject) => {
219
- fileStream.on('close', () => resolve(outputLocationPath));
220
- fileStream.on('error', reject);
221
- });
230
+ fileStream.on('close', () => resolve(outputLocationPath))
231
+ fileStream.on('error', reject)
232
+ })
222
233
  }
223
234
 
224
235
  async function extractTgz(filePath, outputDir) {
@@ -226,47 +237,47 @@ async function extractTgz(filePath, outputDir) {
226
237
  file: filePath,
227
238
  cwd: outputDir,
228
239
  })
229
- console.log(`Extraction completed.`);
240
+ console.log(`Extraction completed.`)
230
241
  }
231
242
 
232
243
 
233
244
 
234
245
  async function checkFileInUse(file) {
235
246
  try {
236
- const handle = await fsp.open(file, 'r+');
237
- await handle.close();
247
+ const handle = await fsp.open(file, 'r+')
248
+ await handle.close()
238
249
  } catch (err) {
239
250
  if (err.code === 'EBUSY' || err.code === 'EPERM' || err.code === 'EACCES') {
240
- console.error('File is in use by another program or access is denied:', err);
241
- return false;
251
+ console.error('File is in use by another program or access is denied:', err)
252
+ return false
242
253
  } else {
243
- console.error('Cannot access file:', err);
244
- return false;
254
+ console.error('Cannot access file:', err)
255
+ return false
245
256
  }
246
257
  }
247
- return true;
258
+ return true
248
259
  }
249
260
 
250
261
  async function checkAllDeletable(currentPath) {
251
262
  try {
252
- const stats = await fsp.stat(currentPath);
263
+ const stats = await fsp.stat(currentPath)
253
264
 
254
265
  if (stats.isDirectory()) {
255
- const files = await fsp.readdir(currentPath);
266
+ const files = await fsp.readdir(currentPath)
256
267
 
257
268
  for (const file of files) {
258
- const deletable = await checkAllDeletable(path.join(currentPath, file));
269
+ const deletable = await checkAllDeletable(path.join(currentPath, file))
259
270
  if (!deletable) {
260
- return false;
271
+ return false
261
272
  }
262
273
  }
263
- return true;
274
+ return true
264
275
  } else {
265
- return await checkFileInUse(currentPath);
276
+ return await checkFileInUse(currentPath)
266
277
  }
267
278
  } catch (err) {
268
- console.log(`Error accessing: ${currentPath}, ${err}`);
269
- return false;
279
+ console.log(`Error accessing: ${currentPath}, ${err}`)
280
+ return false
270
281
  }
271
282
  }
272
283
 
@@ -31,7 +31,7 @@ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31
31
  IN THE SOFTWARE.
32
32
  */
33
33
 
34
- var kCSSColorTable = {
34
+ const kCSSColorTable = {
35
35
  "transparent": [0, 0, 0, 0], "aliceblue": [240, 248, 255, 1],
36
36
  "antiquewhite": [250, 235, 215, 1], "aqua": [0, 255, 255, 1],
37
37
  "aquamarine": [127, 255, 212, 1], "azure": [240, 255, 255, 1],