onejs-core 3.0.1 → 3.0.3

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 (110) hide show
  1. package/.gitattributes +2 -2
  2. package/.prettierrc +5 -5
  3. package/.vscode/settings.json +5 -5
  4. package/LICENSE +20 -20
  5. package/README.md +102 -102
  6. package/definitions/Assemblies/OneJS.Runtime.Ext.d.ts +6 -6
  7. package/definitions/Assemblies/OneJS.Runtime.d.ts +826 -826
  8. package/definitions/Assemblies/OneJS.Samples.d.ts +20 -20
  9. package/definitions/Assemblies/Unity.Mathematics.d.ts +9221 -9221
  10. package/definitions/Assemblies/UnityEditor.CoreModule.d.ts +32614 -32614
  11. package/definitions/Assemblies/UnityEngine.AIModule.d.ts +998 -998
  12. package/definitions/Assemblies/UnityEngine.AnimationModule.d.ts +3308 -3308
  13. package/definitions/Assemblies/UnityEngine.AssetBundleModule.d.ts +337 -337
  14. package/definitions/Assemblies/UnityEngine.AudioModule.d.ts +1154 -1154
  15. package/definitions/Assemblies/UnityEngine.CoreModule.d.ts +29587 -29587
  16. package/definitions/Assemblies/UnityEngine.PhysicsModule.d.ts +3137 -3137
  17. package/definitions/Assemblies/UnityEngine.TerrainModule.d.ts +1270 -1270
  18. package/definitions/Assemblies/UnityEngine.UIElementsModule.d.ts +32718 -32718
  19. package/definitions/Assemblies/UnityEngine.UnityAnalyticsCommonModule.d.ts +274 -274
  20. package/definitions/Assemblies/index.d.ts +16 -16
  21. package/definitions/Assemblies/mscorlib.d.ts +19416 -19416
  22. package/definitions/augments.d.ts +66 -66
  23. package/definitions/globals.d.ts +53 -53
  24. package/definitions/index.d.ts +11 -11
  25. package/definitions/jsx.d.ts +570 -570
  26. package/definitions/modules.d.ts +32 -32
  27. package/definitions/onejs.d.ts +171 -171
  28. package/definitions/preact.jsx.d.ts +6 -6
  29. package/definitions/proto-overrides.d.ts +41 -41
  30. package/definitions/puerts.d.ts +30 -30
  31. package/definitions/unity-engine.d.ts +22 -22
  32. package/dom/document.ts +115 -115
  33. package/dom/dom-style.ts +36 -36
  34. package/dom/dom.ts +376 -376
  35. package/dom/index.ts +3 -3
  36. package/index.ts +59 -58
  37. package/jsr.json +9 -9
  38. package/math/README.md +212 -212
  39. package/math/index.ts +487 -487
  40. package/package.json +33 -33
  41. package/preloads/inject.ts +43 -43
  42. package/scripts/esbuild/copy-assets.mjs +94 -94
  43. package/scripts/esbuild/decorator-fix.mjs +17 -17
  44. package/scripts/esbuild/import-transform.mjs +100 -100
  45. package/scripts/esbuild/index.mjs +3 -3
  46. package/scripts/esbuild/watch-output.mjs +38 -38
  47. package/scripts/postcss/cleanup-plugin.cjs +89 -89
  48. package/scripts/postcss/onejs-tw-config.cjs +252 -252
  49. package/scripts/postcss/optional-import-plugin.cjs +26 -26
  50. package/scripts/postcss/tailwind-logging-plugin.cjs +11 -11
  51. package/scripts/postcss/unwrap-is-plugin.cjs +16 -16
  52. package/scripts/postcss/uss-transform-plugin.cjs +92 -92
  53. package/scripts/switch.cjs +290 -290
  54. package/styling/index.tsx +32 -32
  55. package/styling/utils/generateAlphabeticName.ts +20 -20
  56. package/styling/utils/generateComponentId.ts +5 -5
  57. package/styling/utils/hash.ts +46 -46
  58. package/tsconfig.json +24 -24
  59. package/typings.d.ts +5 -5
  60. package/utils/arrays.ts +10 -10
  61. package/utils/color-palettes.ts +2 -2
  62. package/utils/color-parser.ts +248 -248
  63. package/utils/float-parser.ts +30 -30
  64. package/utils/index.ts +15 -15
  65. package/utils/subscribe.ts +16 -16
  66. package/utils/system.ts +16 -16
  67. package/dist/csharp/index.d.ts +0 -3
  68. package/dist/csharp/index.js +0 -3
  69. package/dist/dom/document.d.ts +0 -30
  70. package/dist/dom/document.js +0 -89
  71. package/dist/dom/dom-style.d.ts +0 -9
  72. package/dist/dom/dom-style.js +0 -27
  73. package/dist/dom/dom.d.ts +0 -83
  74. package/dist/dom/dom.js +0 -313
  75. package/dist/dom/index.d.ts +0 -4
  76. package/dist/dom/index.js +0 -4
  77. package/dist/dom/selector.d.ts +0 -0
  78. package/dist/dom/selector.js +0 -0
  79. package/dist/index.d.ts +0 -25
  80. package/dist/index.js +0 -44
  81. package/dist/math/index.d.ts +0 -86
  82. package/dist/math/index.js +0 -361
  83. package/dist/preloads/inject.d.ts +0 -3
  84. package/dist/preloads/inject.js +0 -36
  85. package/dist/styling/index.d.ts +0 -10
  86. package/dist/styling/index.js +0 -28
  87. package/dist/styling/utils/generateAlphabeticName.d.ts +0 -1
  88. package/dist/styling/utils/generateAlphabeticName.js +0 -16
  89. package/dist/styling/utils/generateComponentId.d.ts +0 -1
  90. package/dist/styling/utils/generateComponentId.js +0 -5
  91. package/dist/styling/utils/hash.d.ts +0 -5
  92. package/dist/styling/utils/hash.js +0 -34
  93. package/dist/utils/arrays.d.ts +0 -1
  94. package/dist/utils/arrays.js +0 -10
  95. package/dist/utils/color-palettes.d.ts +0 -2
  96. package/dist/utils/color-palettes.js +0 -2
  97. package/dist/utils/color-parser.d.ts +0 -161
  98. package/dist/utils/color-parser.js +0 -241
  99. package/dist/utils/float-parser.d.ts +0 -7
  100. package/dist/utils/float-parser.js +0 -23
  101. package/dist/utils/index.d.ts +0 -12
  102. package/dist/utils/index.js +0 -15
  103. package/dist/utils/responsive.d.ts +0 -4
  104. package/dist/utils/responsive.js +0 -23
  105. package/dist/utils/subscribe.d.ts +0 -4
  106. package/dist/utils/subscribe.js +0 -10
  107. package/dist/utils/system.d.ts +0 -1
  108. package/dist/utils/system.js +0 -16
  109. package/dist/utils/toJsArray.d.ts +0 -1
  110. package/dist/utils/toJsArray.js +0 -10
@@ -1,290 +1,290 @@
1
- const fs = require('fs')
2
- const tar = require('tar')
3
- const url = require('url')
4
- const path = require('path')
5
- const fse = require('fs-extra')
6
- const xml2js = require('xml2js')
7
- const { rimraf } = require('rimraf')
8
- const ProgressBar = require('progress')
9
-
10
- const fsp = fs.promises
11
-
12
- const projectDir = path.resolve(process.cwd(), '..')
13
- const manifestPath = path.join(projectDir, 'Packages', 'manifest.json')
14
-
15
- const backends = [
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
- ]
20
-
21
- const args = process.argv.slice(2)
22
-
23
- if (args.length > 0 && args[0].toLowerCase() == "clear") {
24
- for (const backend of backends) {
25
- const filename = getFilenameFromUrl(backend.tgzUrl)
26
- const outputDir = "./tmp"
27
- const downloadedPath = path.join(outputDir, filename)
28
- if (fs.existsSync(downloadedPath)) {
29
- fs.unlinkSync(downloadedPath)
30
- console.log(`Deleted ${downloadedPath}`)
31
- }
32
- }
33
- } else if (
34
- args.length > 0 &&
35
- (["quickjs", "v8", "nodejs"].includes(args[0].toLowerCase()) ||
36
- (args[0].toLowerCase().endsWith('.tgz') || /^https?:\/\/.+\.tgz$/i.test(args[0])))
37
- ) {
38
- let backend
39
- const outputDir = "./tmp"
40
- if (["quickjs", "v8", "nodejs"].includes(args[0].toLowerCase())) {
41
- backend = backends.find(b => b.name.toLowerCase() === args[0])
42
- } else {
43
- backend = { name: "Custom", tgzUrl: args[0] }
44
- }
45
- Process(backend, outputDir)
46
- } else {
47
- console.log("Usage: npm run switch <quickjs|v8|nodejs|clear|tgz-url>\n")
48
- console.log(" quickjs: Switch to QuickJS backend")
49
- console.log(" v8: Switch to V8 backend")
50
- console.log(" nodejs: Switch to NodeJS backend")
51
- console.log(" clear: Clear all downloaded .tgz files")
52
- console.log(" <tgz-url>: Switch using a custom .tgz package URL\n")
53
- }
54
-
55
- async function Process(backend, outputDir) {
56
- try {
57
- // Download
58
- const downloadedPath = await downloadFile(backend.tgzUrl, outputDir)
59
-
60
- // Extraction
61
- const upmDir = path.join(outputDir, "upm")
62
- if (fs.existsSync(upmDir)) {
63
- await rimraf(upmDir)
64
- }
65
- await extractTgz(downloadedPath, outputDir)
66
-
67
- // Safe keep asmdef files, et al.
68
- const onejsDir = await getOneJSUnityDir()
69
- const a = path.join(onejsDir, 'Puerts/Editor/com.tencent.puerts.core.Editor.asmdef')
70
- const b = path.join(upmDir, 'Editor/com.tencent.puerts.core.Editor.asmdef')
71
- const c = path.join(onejsDir, 'Puerts/Runtime/com.tencent.puerts.core.asmdef')
72
- const d = path.join(upmDir, 'Runtime/com.tencent.puerts.core.asmdef')
73
- await fse.copy(a, b)
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)
78
-
79
- // Replace OneJS/Puerts with the new one
80
- const puertsDir = path.join(onejsDir, "Puerts")
81
- if (await deleteDirectorySafely(puertsDir)) {
82
- await fse.copy(upmDir, puertsDir)
83
- console.log(`Switched to ${backend.name} successfully.`)
84
- } else {
85
- console.error("Failed to delete old Puerts directory. Please make sure Unity Editor is not running as it may be using the files. (We cannot reliably replace native plugins while Unity Editor is using them)")
86
- }
87
- } catch (err) {
88
- console.error(`Error: ${err.message}`)
89
- }
90
- }
91
-
92
- // --- Support Functions ---
93
-
94
- // function getOneJSUnityDir() {
95
- // var packageJsonPath = path.join(process.cwd(), 'package.json')
96
- // var json = require(packageJsonPath)
97
- // return json.onejs["unity-package-path"]
98
- // }
99
-
100
- async function getOneJSUnityDir() {
101
- let oneJSPath = null
102
-
103
- // Step 1: Check manifest.json
104
- if (fs.existsSync(manifestPath)) {
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
- }
125
- }
126
- }
127
- }
128
-
129
- // Step 2: If not found, parse OneJS.Runtime.csproj
130
- if (!oneJSPath) {
131
- const csprojPath = path.join(projectDir, 'OneJS.Runtime.csproj')
132
-
133
- if (fs.existsSync(csprojPath)) {
134
- const csprojContent = fs.readFileSync(csprojPath, 'utf8')
135
- const parser = new xml2js.Parser()
136
-
137
- try {
138
- const result = await parser.parseStringPromise(csprojContent)
139
-
140
- const project = result.Project
141
- const itemGroups = project.ItemGroup
142
-
143
- if (itemGroups && itemGroups.length > 0) {
144
- for (const itemGroup of itemGroups) {
145
- if (itemGroup.Compile) {
146
- for (const compileItem of itemGroup.Compile) {
147
- const includePath = compileItem.$.Include
148
-
149
- // Normalize path separators for cross-platform compatibility
150
- const normalizedIncludePath = includePath.replace(/\\/g, '/')
151
- const searchIndex = normalizedIncludePath.indexOf('OneJS/Runtime/Engine/ScriptEngine.cs')
152
-
153
- if (searchIndex !== -1) {
154
- oneJSPath = normalizedIncludePath.substring(0, searchIndex + 'OneJS'.length)
155
- oneJSPath = path.resolve(projectDir, oneJSPath)
156
- return oneJSPath
157
- }
158
- }
159
- }
160
- }
161
- }
162
-
163
- console.error('Could not find OneJS path in csproj file.')
164
- return null
165
- } catch (err) {
166
- console.error('Error parsing csproj file:', err)
167
- return null
168
- }
169
- } else {
170
- console.error('OneJS.Runtime.csproj file does not exist.')
171
- return null
172
- }
173
- }
174
-
175
- return oneJSPath
176
- }
177
-
178
- function ensureDirectoryExistence(filePath) {
179
- const dirname = path.dirname(filePath)
180
- if (fs.existsSync(dirname)) {
181
- return true
182
- }
183
- fs.mkdirSync(dirname, { recursive: true })
184
- }
185
-
186
- function getFilenameFromUrl(fileUrl) {
187
- const parsedUrl = url.parse(fileUrl)
188
- return path.basename(parsedUrl.pathname)
189
- }
190
-
191
- async function downloadFile(fileUrl, outputDir) {
192
- const filename = getFilenameFromUrl(fileUrl)
193
- const outputLocationPath = path.join(outputDir, filename)
194
-
195
- ensureDirectoryExistence(outputLocationPath)
196
-
197
- // Check if file exists (keep existing code)
198
- if (fs.existsSync(outputLocationPath)) {
199
- console.log(`Local .tgz found: ${outputLocationPath}`)
200
- return outputLocationPath
201
- }
202
-
203
- console.log(`Downloading ${filename}`)
204
- const response = await fetch(fileUrl)
205
-
206
- if (!response.ok) {
207
- throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`)
208
- }
209
-
210
- // Get the total size for the progress bar
211
- const totalSize = parseInt(response.headers.get('content-length'), 10)
212
-
213
- // Create progress bar
214
- const progressBar = new ProgressBar('[:bar] :percent ETA: :etas', {
215
- complete: '=',
216
- incomplete: ' ',
217
- width: 40,
218
- total: totalSize
219
- })
220
-
221
- const fileStream = fs.createWriteStream(outputLocationPath)
222
- for await (const chunk of response.body) {
223
- fileStream.write(chunk)
224
- progressBar.tick(chunk.length)
225
- }
226
-
227
- fileStream.end()
228
-
229
- return new Promise((resolve, reject) => {
230
- fileStream.on('close', () => resolve(outputLocationPath))
231
- fileStream.on('error', reject)
232
- })
233
- }
234
-
235
- async function extractTgz(filePath, outputDir) {
236
- await tar.x({
237
- file: filePath,
238
- cwd: outputDir,
239
- })
240
- console.log(`Extraction completed.`)
241
- }
242
-
243
-
244
-
245
- async function checkFileInUse(file) {
246
- try {
247
- const handle = await fsp.open(file, 'r+')
248
- await handle.close()
249
- } catch (err) {
250
- if (err.code === 'EBUSY' || err.code === 'EPERM' || err.code === 'EACCES') {
251
- console.error('File is in use by another program or access is denied:', err)
252
- return false
253
- } else {
254
- console.error('Cannot access file:', err)
255
- return false
256
- }
257
- }
258
- return true
259
- }
260
-
261
- async function checkAllDeletable(currentPath) {
262
- try {
263
- const stats = await fsp.stat(currentPath)
264
-
265
- if (stats.isDirectory()) {
266
- const files = await fsp.readdir(currentPath)
267
-
268
- for (const file of files) {
269
- const deletable = await checkAllDeletable(path.join(currentPath, file))
270
- if (!deletable) {
271
- return false
272
- }
273
- }
274
- return true
275
- } else {
276
- return await checkFileInUse(currentPath)
277
- }
278
- } catch (err) {
279
- console.log(`Error accessing: ${currentPath}, ${err}`)
280
- return false
281
- }
282
- }
283
-
284
- async function deleteDirectorySafely(dirPath) {
285
- if (await checkAllDeletable(dirPath)) {
286
- await rimraf(dirPath)
287
- return true
288
- }
289
- return false
290
- }
1
+ const fs = require('fs')
2
+ const tar = require('tar')
3
+ const url = require('url')
4
+ const path = require('path')
5
+ const fse = require('fs-extra')
6
+ const { rimraf } = require('rimraf')
7
+ const ProgressBar = require('progress')
8
+
9
+ const fsp = fs.promises
10
+
11
+ const projectDir = path.resolve(process.cwd(), '..')
12
+ const manifestPath = path.join(projectDir, 'Packages', 'manifest.json')
13
+
14
+ const backends = [
15
+ { name: "QuickJS", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.2/PuerTS_Quickjs_2.2.2.tgz" },
16
+ { name: "V8", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.2/PuerTS_V8_2.2.2.tgz" },
17
+ { name: "NodeJS", tgzUrl: "https://github.com/Tencent/puerts/releases/download/Unity_v2.2.2/PuerTS_Nodejs_2.2.2.tgz" }
18
+ ]
19
+
20
+ const args = process.argv.slice(2)
21
+
22
+ if (args.length > 0 && args[0].toLowerCase() == "clear") {
23
+ for (const backend of backends) {
24
+ const filename = getFilenameFromUrl(backend.tgzUrl)
25
+ const outputDir = "./tmp"
26
+ const downloadedPath = path.join(outputDir, filename)
27
+ if (fs.existsSync(downloadedPath)) {
28
+ fs.unlinkSync(downloadedPath)
29
+ console.log(`Deleted ${downloadedPath}`)
30
+ }
31
+ }
32
+ } else if (
33
+ args.length > 0 &&
34
+ (["quickjs", "v8", "nodejs"].includes(args[0].toLowerCase()) ||
35
+ (args[0].toLowerCase().endsWith('.tgz') || /^https?:\/\/.+\.tgz$/i.test(args[0])))
36
+ ) {
37
+ let backend
38
+ const outputDir = "./tmp"
39
+ if (["quickjs", "v8", "nodejs"].includes(args[0].toLowerCase())) {
40
+ backend = backends.find(b => b.name.toLowerCase() === args[0])
41
+ } else {
42
+ backend = { name: "Custom", tgzUrl: args[0] }
43
+ }
44
+ Process(backend, outputDir)
45
+ } else {
46
+ console.log("Usage: npm run switch <quickjs|v8|nodejs|clear|tgz-url>\n")
47
+ console.log(" quickjs: Switch to QuickJS backend")
48
+ console.log(" v8: Switch to V8 backend")
49
+ console.log(" nodejs: Switch to NodeJS backend")
50
+ console.log(" clear: Clear all downloaded .tgz files")
51
+ console.log(" <tgz-url>: Switch using a custom .tgz package URL\n")
52
+ }
53
+
54
+ async function Process(backend, outputDir) {
55
+ try {
56
+ // Download
57
+ const downloadedPath = await downloadFile(backend.tgzUrl, outputDir)
58
+
59
+ // Extraction
60
+ const upmDir = path.join(outputDir, "upm")
61
+ if (fs.existsSync(upmDir)) {
62
+ await rimraf(upmDir)
63
+ }
64
+ await extractTgz(downloadedPath, outputDir)
65
+
66
+ // Safe keep asmdef files, et al.
67
+ const onejsDir = await getOneJSUnityDir()
68
+ if (!onejsDir) {
69
+ throw new Error('Could not locate the OneJS Unity package directory. See messages above for details.')
70
+ }
71
+ const a = path.join(onejsDir, 'Puerts/Editor/com.tencent.puerts.core.Editor.asmdef')
72
+ const b = path.join(upmDir, 'Editor/com.tencent.puerts.core.Editor.asmdef')
73
+ const c = path.join(onejsDir, 'Puerts/Runtime/com.tencent.puerts.core.asmdef')
74
+ const d = path.join(upmDir, 'Runtime/com.tencent.puerts.core.asmdef')
75
+ await fse.copy(a, b)
76
+ await fse.copy(c, d)
77
+ const e = path.join(onejsDir, 'Puerts/Runtime/Src/Default/JsEnv.cs')
78
+ const f = path.join(upmDir, 'Runtime/Src/Default/JsEnv.cs')
79
+ await fse.copy(e, f)
80
+
81
+ // Replace OneJS/Puerts with the new one
82
+ const puertsDir = path.join(onejsDir, "Puerts")
83
+ if (await deleteDirectorySafely(puertsDir)) {
84
+ await fse.copy(upmDir, puertsDir)
85
+ console.log(`Switched to ${backend.name} successfully.`)
86
+ } else {
87
+ console.error("Failed to delete old Puerts directory. Please make sure Unity Editor is not running as it may be using the files. (We cannot reliably replace native plugins while Unity Editor is using them)")
88
+ }
89
+ } catch (err) {
90
+ console.error(`Error: ${err.message}`)
91
+ }
92
+ }
93
+
94
+ // --- Support Functions ---
95
+
96
+ // function getOneJSUnityDir() {
97
+ // var packageJsonPath = path.join(process.cwd(), 'package.json')
98
+ // var json = require(packageJsonPath)
99
+ // return json.onejs["unity-package-path"]
100
+ // }
101
+
102
+ async function getOneJSUnityDir() {
103
+ const oneJSKeys = ["com.dragonground.onejs", "com.singtaa.onejs"]
104
+
105
+ // Step 1: Check manifest.json for local (file:) paths
106
+ if (fs.existsSync(manifestPath)) {
107
+ const manifestContent = fs.readFileSync(manifestPath, "utf8")
108
+ let manifestJson
109
+ try { manifestJson = JSON.parse(manifestContent) } catch {
110
+ console.error('Could not parse manifest.json at ' + manifestPath)
111
+ return null
112
+ }
113
+
114
+ const dependencies = manifestJson && manifestJson.dependencies
115
+
116
+ if (dependencies) {
117
+ for (const key of oneJSKeys) {
118
+ const packagePath = dependencies[key]
119
+ if (typeof packagePath === "string") {
120
+ const v = packagePath.trim()
121
+ if (v.startsWith("file:")) {
122
+ // Local path dependency, e.g., "file:PATH/TO/OneJS"
123
+ return path.resolve(projectDir, v.substring(5))
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ // Step 2: Check Library/PackageCache for Git URL or registry dependencies
130
+ const packageCacheDir = path.join(projectDir, 'Library', 'PackageCache')
131
+ if (dependencies && fs.existsSync(packageCacheDir)) {
132
+ for (const key of oneJSKeys) {
133
+ if (typeof dependencies[key] === "string") {
134
+ const found = findPackageInCache(packageCacheDir, key)
135
+ if (found) return found
136
+ }
137
+ }
138
+ }
139
+ }
140
+
141
+ // Step 3: Last resort - scan PackageCache even without manifest entry
142
+ const packageCacheDir = path.join(projectDir, 'Library', 'PackageCache')
143
+ if (fs.existsSync(packageCacheDir)) {
144
+ for (const key of oneJSKeys) {
145
+ const found = findPackageInCache(packageCacheDir, key)
146
+ if (found) return found
147
+ }
148
+ }
149
+
150
+ console.error(
151
+ 'Could not find OneJS package directory.\n' +
152
+ 'Please make sure OneJS is installed in your Unity project via one of:\n' +
153
+ ' - A local path (file:) dependency in Packages/manifest.json\n' +
154
+ ' - A Git URL dependency in Packages/manifest.json\n' +
155
+ ' - The Unity Package Manager registry\n' +
156
+ 'And that this script is run from the OneJS npm project inside the Unity project.'
157
+ )
158
+ return null
159
+ }
160
+
161
+ function findPackageInCache(packageCacheDir, packageName) {
162
+ try {
163
+ const entries = fs.readdirSync(packageCacheDir)
164
+ for (const entry of entries) {
165
+ if (entry.startsWith(packageName + '@') || entry === packageName) {
166
+ const candidatePath = path.join(packageCacheDir, entry)
167
+ if (fs.statSync(candidatePath).isDirectory()) {
168
+ return candidatePath
169
+ }
170
+ }
171
+ }
172
+ } catch (err) {
173
+ // PackageCache not readable, skip
174
+ }
175
+ return null
176
+ }
177
+
178
+ function ensureDirectoryExistence(filePath) {
179
+ const dirname = path.dirname(filePath)
180
+ if (fs.existsSync(dirname)) {
181
+ return true
182
+ }
183
+ fs.mkdirSync(dirname, { recursive: true })
184
+ }
185
+
186
+ function getFilenameFromUrl(fileUrl) {
187
+ const parsedUrl = url.parse(fileUrl)
188
+ return path.basename(parsedUrl.pathname)
189
+ }
190
+
191
+ async function downloadFile(fileUrl, outputDir) {
192
+ const filename = getFilenameFromUrl(fileUrl)
193
+ const outputLocationPath = path.join(outputDir, filename)
194
+
195
+ ensureDirectoryExistence(outputLocationPath)
196
+
197
+ // Check if file exists (keep existing code)
198
+ if (fs.existsSync(outputLocationPath)) {
199
+ console.log(`Local .tgz found: ${outputLocationPath}`)
200
+ return outputLocationPath
201
+ }
202
+
203
+ console.log(`Downloading ${filename}`)
204
+ const response = await fetch(fileUrl)
205
+
206
+ if (!response.ok) {
207
+ throw new Error(`Failed to fetch ${fileUrl}: ${response.statusText}`)
208
+ }
209
+
210
+ // Get the total size for the progress bar
211
+ const totalSize = parseInt(response.headers.get('content-length'), 10)
212
+
213
+ // Create progress bar
214
+ const progressBar = new ProgressBar('[:bar] :percent ETA: :etas', {
215
+ complete: '=',
216
+ incomplete: ' ',
217
+ width: 40,
218
+ total: totalSize
219
+ })
220
+
221
+ const fileStream = fs.createWriteStream(outputLocationPath)
222
+ for await (const chunk of response.body) {
223
+ fileStream.write(chunk)
224
+ progressBar.tick(chunk.length)
225
+ }
226
+
227
+ fileStream.end()
228
+
229
+ return new Promise((resolve, reject) => {
230
+ fileStream.on('close', () => resolve(outputLocationPath))
231
+ fileStream.on('error', reject)
232
+ })
233
+ }
234
+
235
+ async function extractTgz(filePath, outputDir) {
236
+ await tar.x({
237
+ file: filePath,
238
+ cwd: outputDir,
239
+ })
240
+ console.log(`Extraction completed.`)
241
+ }
242
+
243
+
244
+
245
+ async function checkFileInUse(file) {
246
+ try {
247
+ const handle = await fsp.open(file, 'r+')
248
+ await handle.close()
249
+ } catch (err) {
250
+ if (err.code === 'EBUSY' || err.code === 'EPERM' || err.code === 'EACCES') {
251
+ console.error('File is in use by another program or access is denied:', err)
252
+ return false
253
+ } else {
254
+ console.error('Cannot access file:', err)
255
+ return false
256
+ }
257
+ }
258
+ return true
259
+ }
260
+
261
+ async function checkAllDeletable(currentPath) {
262
+ try {
263
+ const stats = await fsp.stat(currentPath)
264
+
265
+ if (stats.isDirectory()) {
266
+ const files = await fsp.readdir(currentPath)
267
+
268
+ for (const file of files) {
269
+ const deletable = await checkAllDeletable(path.join(currentPath, file))
270
+ if (!deletable) {
271
+ return false
272
+ }
273
+ }
274
+ return true
275
+ } else {
276
+ return await checkFileInUse(currentPath)
277
+ }
278
+ } catch (err) {
279
+ console.log(`Error accessing: ${currentPath}, ${err}`)
280
+ return false
281
+ }
282
+ }
283
+
284
+ async function deleteDirectorySafely(dirPath) {
285
+ if (await checkAllDeletable(dirPath)) {
286
+ await rimraf(dirPath)
287
+ return true
288
+ }
289
+ return false
290
+ }
package/styling/index.tsx CHANGED
@@ -1,33 +1,33 @@
1
- /// <reference path="../definitions/index.d.ts" />
2
- import flatten from "css-flatten"
3
- import generateComponentId from "./utils/generateComponentId"
4
-
5
- const _pastCompIds = new Set<string>()
6
-
7
- export function hashAndAddRuntimeUSS(style: string) {
8
- let compId = generateComponentId(style)
9
- if (_pastCompIds.has(compId))
10
- return compId
11
- style = `.${compId} {${style}}`
12
- style = flatten(style)
13
- document.addRuntimeUSS(style)
14
- _pastCompIds.add(compId)
15
-
16
- return compId
17
- }
18
-
19
- /**
20
- * Similar to the Emotion api, this function takes a template string and returns
21
- * a class name that can be used to style an element.
22
- * @param strings
23
- * @param values
24
- * @returns
25
- */
26
- export const emo = function (strings: TemplateStringsArray, ...values: any[]): string {
27
- let style = values.reduce((result, expr, index) => {
28
- const value = expr
29
- return result + (value ? value : "") + strings[index + 1]
30
- }, strings[0])
31
-
32
- return hashAndAddRuntimeUSS(style)
1
+ /// <reference path="../definitions/index.d.ts" />
2
+ import flatten from "css-flatten"
3
+ import generateComponentId from "./utils/generateComponentId"
4
+
5
+ const _pastCompIds = new Set<string>()
6
+
7
+ export function hashAndAddRuntimeUSS(style: string) {
8
+ let compId = generateComponentId(style)
9
+ if (_pastCompIds.has(compId))
10
+ return compId
11
+ style = `.${compId} {${style}}`
12
+ style = flatten(style)
13
+ globalThis.___document.addRuntimeUSS(style)
14
+ _pastCompIds.add(compId)
15
+
16
+ return compId
17
+ }
18
+
19
+ /**
20
+ * Similar to the Emotion api, this function takes a template string and returns
21
+ * a class name that can be used to style an element.
22
+ * @param strings
23
+ * @param values
24
+ * @returns
25
+ */
26
+ export const emo = function (strings: TemplateStringsArray, ...values: any[]): string {
27
+ let style = values.reduce((result, expr, index) => {
28
+ const value = expr
29
+ return result + (value ? value : "") + strings[index + 1]
30
+ }, strings[0])
31
+
32
+ return hashAndAddRuntimeUSS(style)
33
33
  }