@holoscript/core 1.0.0-alpha.2 → 2.0.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/package.json +2 -2
- package/src/HoloScript2DParser.js +227 -0
- package/src/HoloScript2DParser.ts +5 -0
- package/src/HoloScriptCodeParser.js +1102 -0
- package/src/HoloScriptCodeParser.ts +145 -20
- package/src/HoloScriptDebugger.js +458 -0
- package/src/HoloScriptParser.js +338 -0
- package/src/HoloScriptPlusParser.js +371 -0
- package/src/HoloScriptPlusParser.ts +543 -0
- package/src/HoloScriptRuntime.js +1399 -0
- package/src/HoloScriptRuntime.test.js +351 -0
- package/src/HoloScriptRuntime.ts +17 -3
- package/src/HoloScriptTypeChecker.js +356 -0
- package/src/__tests__/GraphicsServices.test.js +357 -0
- package/src/__tests__/GraphicsServices.test.ts +427 -0
- package/src/__tests__/HoloScriptPlusParser.test.js +317 -0
- package/src/__tests__/HoloScriptPlusParser.test.ts +392 -0
- package/src/__tests__/integration.test.js +336 -0
- package/src/__tests__/performance.bench.js +218 -0
- package/src/__tests__/type-checker.test.js +60 -0
- package/src/__tests__/type-checker.test.ts +73 -0
- package/src/index.js +217 -0
- package/src/index.ts +158 -18
- package/src/interop/Interoperability.js +413 -0
- package/src/interop/Interoperability.ts +494 -0
- package/src/logger.js +42 -0
- package/src/parser/EnhancedParser.js +205 -0
- package/src/parser/EnhancedParser.ts +251 -0
- package/src/parser/HoloScriptPlusParser.js +928 -0
- package/src/parser/HoloScriptPlusParser.ts +1089 -0
- package/src/runtime/HoloScriptPlusRuntime.js +674 -0
- package/src/runtime/HoloScriptPlusRuntime.ts +861 -0
- package/src/runtime/PerformanceTelemetry.js +323 -0
- package/src/runtime/PerformanceTelemetry.ts +467 -0
- package/src/runtime/RuntimeOptimization.js +361 -0
- package/src/runtime/RuntimeOptimization.ts +416 -0
- package/src/services/HololandGraphicsPipelineService.js +506 -0
- package/src/services/HololandGraphicsPipelineService.ts +662 -0
- package/src/services/PlatformPerformanceOptimizer.js +356 -0
- package/src/services/PlatformPerformanceOptimizer.ts +503 -0
- package/src/state/ReactiveState.js +427 -0
- package/src/state/ReactiveState.ts +572 -0
- package/src/tools/DeveloperExperience.js +376 -0
- package/src/tools/DeveloperExperience.ts +438 -0
- package/src/traits/AIDriverTrait.js +322 -0
- package/src/traits/AIDriverTrait.test.js +329 -0
- package/src/traits/AIDriverTrait.test.ts +357 -0
- package/src/traits/AIDriverTrait.ts +474 -0
- package/src/traits/LightingTrait.js +313 -0
- package/src/traits/LightingTrait.test.js +410 -0
- package/src/traits/LightingTrait.test.ts +462 -0
- package/src/traits/LightingTrait.ts +505 -0
- package/src/traits/MaterialTrait.js +194 -0
- package/src/traits/MaterialTrait.test.js +286 -0
- package/src/traits/MaterialTrait.test.ts +329 -0
- package/src/traits/MaterialTrait.ts +324 -0
- package/src/traits/RenderingTrait.js +356 -0
- package/src/traits/RenderingTrait.test.js +363 -0
- package/src/traits/RenderingTrait.test.ts +427 -0
- package/src/traits/RenderingTrait.ts +555 -0
- package/src/traits/VRTraitSystem.js +740 -0
- package/src/traits/VRTraitSystem.ts +1040 -0
- package/src/traits/VoiceInputTrait.js +284 -0
- package/src/traits/VoiceInputTrait.test.js +226 -0
- package/src/traits/VoiceInputTrait.test.ts +252 -0
- package/src/traits/VoiceInputTrait.ts +401 -0
- package/src/types/AdvancedTypeSystem.js +226 -0
- package/src/types/AdvancedTypeSystem.ts +494 -0
- package/src/types/HoloScriptPlus.d.ts +853 -0
- package/src/types.js +6 -0
- package/src/types.ts +96 -1
- package/tsconfig.json +1 -1
- package/tsup.config.d.ts +2 -0
- package/tsup.config.js +18 -0
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @holoscript/core Interoperability
|
|
3
|
+
*
|
|
4
|
+
* TypeScript module resolution, proper import/export handling,
|
|
5
|
+
* async/await support, error boundaries
|
|
6
|
+
*/
|
|
7
|
+
import * as path from 'path';
|
|
8
|
+
import * as fs from 'fs';
|
|
9
|
+
/**
|
|
10
|
+
* Module resolver for TypeScript/JavaScript integration
|
|
11
|
+
*/
|
|
12
|
+
export class ModuleResolver {
|
|
13
|
+
constructor(basePath = process.cwd()) {
|
|
14
|
+
this.cache = new Map();
|
|
15
|
+
this.resolvedPaths = new Map();
|
|
16
|
+
this.basePath = basePath;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Resolve module path
|
|
20
|
+
*/
|
|
21
|
+
resolveModule(modulePath, fromPath) {
|
|
22
|
+
const cacheKey = `${modulePath}:${fromPath || 'root'}`;
|
|
23
|
+
if (this.resolvedPaths.has(cacheKey)) {
|
|
24
|
+
return this.resolvedPaths.get(cacheKey);
|
|
25
|
+
}
|
|
26
|
+
const resolved = this.performResolve(modulePath, fromPath);
|
|
27
|
+
this.resolvedPaths.set(cacheKey, resolved);
|
|
28
|
+
return resolved;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Perform actual module resolution
|
|
32
|
+
*/
|
|
33
|
+
performResolve(modulePath, fromPath) {
|
|
34
|
+
// Handle built-in modules
|
|
35
|
+
if (this.isBuiltinModule(modulePath)) {
|
|
36
|
+
return modulePath;
|
|
37
|
+
}
|
|
38
|
+
// Handle relative imports
|
|
39
|
+
if (modulePath.startsWith('.')) {
|
|
40
|
+
const basePath = fromPath ? path.dirname(fromPath) : this.basePath;
|
|
41
|
+
const resolved = path.resolve(basePath, modulePath);
|
|
42
|
+
return this.findModuleFile(resolved);
|
|
43
|
+
}
|
|
44
|
+
// Handle node_modules
|
|
45
|
+
if (modulePath.startsWith('@')) {
|
|
46
|
+
// Scoped package
|
|
47
|
+
return this.resolveNodeModule(modulePath);
|
|
48
|
+
}
|
|
49
|
+
// Standard package
|
|
50
|
+
return this.resolveNodeModule(modulePath);
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Check if built-in module
|
|
54
|
+
*/
|
|
55
|
+
isBuiltinModule(modulePath) {
|
|
56
|
+
const builtins = ['fs', 'path', 'crypto', 'util', 'stream', 'events'];
|
|
57
|
+
return builtins.includes(modulePath);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Resolve from node_modules
|
|
61
|
+
*/
|
|
62
|
+
resolveNodeModule(modulePath) {
|
|
63
|
+
let current = this.basePath;
|
|
64
|
+
while (current !== path.dirname(current)) {
|
|
65
|
+
const nodeModulesPath = path.join(current, 'node_modules', modulePath);
|
|
66
|
+
if (fs.existsSync(nodeModulesPath)) {
|
|
67
|
+
return nodeModulesPath;
|
|
68
|
+
}
|
|
69
|
+
// Try package.json main field
|
|
70
|
+
const packageJsonPath = path.join(nodeModulesPath, 'package.json');
|
|
71
|
+
if (fs.existsSync(packageJsonPath)) {
|
|
72
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf-8'));
|
|
73
|
+
return this.findModuleFile(path.join(nodeModulesPath, packageJson.main || 'index.js'));
|
|
74
|
+
}
|
|
75
|
+
current = path.dirname(current);
|
|
76
|
+
}
|
|
77
|
+
throw new Error(`Module not found: ${modulePath}`);
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Find module file with various extensions
|
|
81
|
+
*/
|
|
82
|
+
findModuleFile(basePath) {
|
|
83
|
+
const extensions = ['.ts', '.tsx', '.js', '.jsx', '.json'];
|
|
84
|
+
// Try exact file
|
|
85
|
+
if (fs.existsSync(basePath)) {
|
|
86
|
+
return basePath;
|
|
87
|
+
}
|
|
88
|
+
// Try with extensions
|
|
89
|
+
for (const ext of extensions) {
|
|
90
|
+
const withExt = basePath + ext;
|
|
91
|
+
if (fs.existsSync(withExt)) {
|
|
92
|
+
return withExt;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
// Try index
|
|
96
|
+
const indexPath = path.join(basePath, 'index');
|
|
97
|
+
for (const ext of extensions) {
|
|
98
|
+
const withExt = indexPath + ext;
|
|
99
|
+
if (fs.existsSync(withExt)) {
|
|
100
|
+
return withExt;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
throw new Error(`Cannot resolve file: ${basePath}`);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Load module (with caching)
|
|
107
|
+
*/
|
|
108
|
+
loadModule(modulePath, fromPath) {
|
|
109
|
+
const resolved = this.resolveModule(modulePath, fromPath);
|
|
110
|
+
const cacheKey = resolved;
|
|
111
|
+
if (this.cache.has(cacheKey)) {
|
|
112
|
+
return this.cache.get(cacheKey);
|
|
113
|
+
}
|
|
114
|
+
// For now, return module info (real implementation would execute)
|
|
115
|
+
const module = {
|
|
116
|
+
path: resolved,
|
|
117
|
+
exports: {},
|
|
118
|
+
};
|
|
119
|
+
this.cache.set(cacheKey, module);
|
|
120
|
+
return module;
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Clear cache
|
|
124
|
+
*/
|
|
125
|
+
clearCache() {
|
|
126
|
+
this.cache.clear();
|
|
127
|
+
this.resolvedPaths.clear();
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Named export/import handler
|
|
132
|
+
*/
|
|
133
|
+
export class ExportImportHandler {
|
|
134
|
+
constructor() {
|
|
135
|
+
this.exports = new Map();
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* Define named export
|
|
139
|
+
*/
|
|
140
|
+
defineExport(modulePath, name, value) {
|
|
141
|
+
if (!this.exports.has(modulePath)) {
|
|
142
|
+
this.exports.set(modulePath, new Map());
|
|
143
|
+
}
|
|
144
|
+
this.exports.get(modulePath).set(name, value);
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get named export
|
|
148
|
+
*/
|
|
149
|
+
getExport(modulePath, name) {
|
|
150
|
+
const moduleExports = this.exports.get(modulePath);
|
|
151
|
+
if (!moduleExports) {
|
|
152
|
+
throw new Error(`Module not found: ${modulePath}`);
|
|
153
|
+
}
|
|
154
|
+
if (!moduleExports.has(name)) {
|
|
155
|
+
throw new Error(`Named export '${name}' not found in ${modulePath}`);
|
|
156
|
+
}
|
|
157
|
+
return moduleExports.get(name);
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Get all exports from module
|
|
161
|
+
*/
|
|
162
|
+
getAllExports(modulePath) {
|
|
163
|
+
const moduleExports = this.exports.get(modulePath);
|
|
164
|
+
if (!moduleExports) {
|
|
165
|
+
return {};
|
|
166
|
+
}
|
|
167
|
+
const result = {};
|
|
168
|
+
for (const [name, value] of moduleExports) {
|
|
169
|
+
result[name] = value;
|
|
170
|
+
}
|
|
171
|
+
return result;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Check if export exists
|
|
175
|
+
*/
|
|
176
|
+
hasExport(modulePath, name) {
|
|
177
|
+
return this.exports.has(modulePath) && this.exports.get(modulePath).has(name);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Async function handler
|
|
182
|
+
*/
|
|
183
|
+
export class AsyncFunctionHandler {
|
|
184
|
+
/**
|
|
185
|
+
* Wrap async function for HoloScript
|
|
186
|
+
*/
|
|
187
|
+
wrapAsyncFunction(fn) {
|
|
188
|
+
return async (...args) => {
|
|
189
|
+
try {
|
|
190
|
+
return await fn(...args);
|
|
191
|
+
}
|
|
192
|
+
catch (error) {
|
|
193
|
+
throw this.normalizeError(error);
|
|
194
|
+
}
|
|
195
|
+
};
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Check if function is async
|
|
199
|
+
*/
|
|
200
|
+
isAsync(fn) {
|
|
201
|
+
if (typeof fn !== 'function') {
|
|
202
|
+
return false;
|
|
203
|
+
}
|
|
204
|
+
const fnStr = fn.toString().trim();
|
|
205
|
+
return fnStr.startsWith('async ') || fn.constructor.name === 'AsyncFunction';
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Convert callback to promise
|
|
209
|
+
*/
|
|
210
|
+
callbackToPromise(fn) {
|
|
211
|
+
return new Promise((resolve, reject) => {
|
|
212
|
+
fn((err, result) => {
|
|
213
|
+
if (err) {
|
|
214
|
+
reject(err);
|
|
215
|
+
}
|
|
216
|
+
else {
|
|
217
|
+
resolve(result);
|
|
218
|
+
}
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* Normalize error from async function
|
|
224
|
+
*/
|
|
225
|
+
normalizeError(error) {
|
|
226
|
+
if (error instanceof Error) {
|
|
227
|
+
return error;
|
|
228
|
+
}
|
|
229
|
+
if (typeof error === 'string') {
|
|
230
|
+
return new Error(error);
|
|
231
|
+
}
|
|
232
|
+
return new Error(JSON.stringify(error));
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Error boundary for isolation
|
|
237
|
+
*/
|
|
238
|
+
export class ErrorBoundary {
|
|
239
|
+
constructor(onError) {
|
|
240
|
+
this.errors = [];
|
|
241
|
+
this.onError = onError;
|
|
242
|
+
}
|
|
243
|
+
/**
|
|
244
|
+
* Wrap function with error boundary
|
|
245
|
+
*/
|
|
246
|
+
wrap(fn) {
|
|
247
|
+
return ((...args) => {
|
|
248
|
+
try {
|
|
249
|
+
const result = fn(...args);
|
|
250
|
+
// Handle async functions
|
|
251
|
+
if (result instanceof Promise) {
|
|
252
|
+
return result.catch((error) => {
|
|
253
|
+
this.handleError(error);
|
|
254
|
+
throw error;
|
|
255
|
+
});
|
|
256
|
+
}
|
|
257
|
+
return result;
|
|
258
|
+
}
|
|
259
|
+
catch (error) {
|
|
260
|
+
this.handleError(error);
|
|
261
|
+
throw error;
|
|
262
|
+
}
|
|
263
|
+
});
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Wrap async function with error boundary
|
|
267
|
+
*/
|
|
268
|
+
wrapAsync(fn) {
|
|
269
|
+
return (async (...args) => {
|
|
270
|
+
try {
|
|
271
|
+
return await fn(...args);
|
|
272
|
+
}
|
|
273
|
+
catch (error) {
|
|
274
|
+
this.handleError(error);
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Execute function in boundary
|
|
281
|
+
*/
|
|
282
|
+
execute(fn) {
|
|
283
|
+
try {
|
|
284
|
+
return fn();
|
|
285
|
+
}
|
|
286
|
+
catch (error) {
|
|
287
|
+
this.handleError(error);
|
|
288
|
+
throw error;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
/**
|
|
292
|
+
* Execute async function in boundary
|
|
293
|
+
*/
|
|
294
|
+
async executeAsync(fn) {
|
|
295
|
+
try {
|
|
296
|
+
return await fn();
|
|
297
|
+
}
|
|
298
|
+
catch (error) {
|
|
299
|
+
this.handleError(error);
|
|
300
|
+
throw error;
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
/**
|
|
304
|
+
* Handle error
|
|
305
|
+
*/
|
|
306
|
+
handleError(error) {
|
|
307
|
+
const normalized = this.normalizeError(error);
|
|
308
|
+
this.errors.push(normalized);
|
|
309
|
+
if (this.onError) {
|
|
310
|
+
this.onError(normalized);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Get errors
|
|
315
|
+
*/
|
|
316
|
+
getErrors() {
|
|
317
|
+
return [...this.errors];
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Clear errors
|
|
321
|
+
*/
|
|
322
|
+
clearErrors() {
|
|
323
|
+
this.errors = [];
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Normalize error
|
|
327
|
+
*/
|
|
328
|
+
normalizeError(error) {
|
|
329
|
+
if (error instanceof Error) {
|
|
330
|
+
return error;
|
|
331
|
+
}
|
|
332
|
+
if (typeof error === 'string') {
|
|
333
|
+
return new Error(error);
|
|
334
|
+
}
|
|
335
|
+
return new Error(JSON.stringify(error));
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
/**
|
|
339
|
+
* TypeScript type loader
|
|
340
|
+
*/
|
|
341
|
+
export class TypeScriptTypeLoader {
|
|
342
|
+
/**
|
|
343
|
+
* Load types from TypeScript declaration file
|
|
344
|
+
*/
|
|
345
|
+
loadTypes(filePath) {
|
|
346
|
+
const types = new Map();
|
|
347
|
+
// In real implementation, would parse .d.ts file
|
|
348
|
+
// For now, return empty map
|
|
349
|
+
return types;
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Convert TypeScript type to HoloScript type
|
|
353
|
+
*/
|
|
354
|
+
convertType(tsType) {
|
|
355
|
+
// Basic type mapping
|
|
356
|
+
const mapping = {
|
|
357
|
+
string: 'text',
|
|
358
|
+
number: 'numeric',
|
|
359
|
+
boolean: 'logical',
|
|
360
|
+
void: 'void',
|
|
361
|
+
any: 'dynamic',
|
|
362
|
+
unknown: 'dynamic',
|
|
363
|
+
null: 'null',
|
|
364
|
+
undefined: 'void',
|
|
365
|
+
};
|
|
366
|
+
if (typeof tsType === 'string') {
|
|
367
|
+
return mapping[tsType] || tsType;
|
|
368
|
+
}
|
|
369
|
+
if (Array.isArray(tsType)) {
|
|
370
|
+
return {
|
|
371
|
+
kind: 'array',
|
|
372
|
+
elementType: this.convertType(tsType[0]),
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
if (typeof tsType === 'object') {
|
|
376
|
+
return {
|
|
377
|
+
kind: 'object',
|
|
378
|
+
properties: Object.entries(tsType).reduce((acc, [key, val]) => {
|
|
379
|
+
acc[key] = this.convertType(val);
|
|
380
|
+
return acc;
|
|
381
|
+
}, {}),
|
|
382
|
+
};
|
|
383
|
+
}
|
|
384
|
+
return tsType;
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Unified interop context
|
|
389
|
+
*/
|
|
390
|
+
export class InteropContext {
|
|
391
|
+
constructor(basePath) {
|
|
392
|
+
this.moduleResolver = new ModuleResolver(basePath);
|
|
393
|
+
this.exportImportHandler = new ExportImportHandler();
|
|
394
|
+
this.asyncHandler = new AsyncFunctionHandler();
|
|
395
|
+
this.errorBoundary = new ErrorBoundary();
|
|
396
|
+
this.typeLoader = new TypeScriptTypeLoader();
|
|
397
|
+
}
|
|
398
|
+
getModuleResolver() {
|
|
399
|
+
return this.moduleResolver;
|
|
400
|
+
}
|
|
401
|
+
getExportImportHandler() {
|
|
402
|
+
return this.exportImportHandler;
|
|
403
|
+
}
|
|
404
|
+
getAsyncHandler() {
|
|
405
|
+
return this.asyncHandler;
|
|
406
|
+
}
|
|
407
|
+
getErrorBoundary() {
|
|
408
|
+
return this.errorBoundary;
|
|
409
|
+
}
|
|
410
|
+
getTypeLoader() {
|
|
411
|
+
return this.typeLoader;
|
|
412
|
+
}
|
|
413
|
+
}
|