@holoscript/core 1.0.0-alpha.1 → 2.0.0

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 (127) hide show
  1. package/package.json +10 -9
  2. package/src/HoloScript2DParser.js +227 -0
  3. package/src/HoloScript2DParser.ts +5 -0
  4. package/src/HoloScriptCodeParser.js +1102 -0
  5. package/src/HoloScriptCodeParser.ts +145 -20
  6. package/src/HoloScriptDebugger.js +458 -0
  7. package/src/HoloScriptParser.js +338 -0
  8. package/src/HoloScriptPlusParser.js +371 -0
  9. package/src/HoloScriptPlusParser.ts +543 -0
  10. package/src/HoloScriptRuntime.js +1399 -0
  11. package/src/HoloScriptRuntime.test.js +351 -0
  12. package/src/HoloScriptRuntime.ts +257 -3
  13. package/src/HoloScriptTypeChecker.js +356 -0
  14. package/src/__tests__/GraphicsServices.test.js +357 -0
  15. package/src/__tests__/GraphicsServices.test.ts +427 -0
  16. package/src/__tests__/HoloScriptPlusParser.test.js +317 -0
  17. package/src/__tests__/HoloScriptPlusParser.test.ts +392 -0
  18. package/src/__tests__/integration.test.js +336 -0
  19. package/src/__tests__/performance.bench.js +218 -0
  20. package/src/__tests__/type-checker.test.js +60 -0
  21. package/src/__tests__/type-checker.test.ts +73 -0
  22. package/src/index.js +217 -0
  23. package/src/index.ts +158 -18
  24. package/src/interop/Interoperability.js +413 -0
  25. package/src/interop/Interoperability.ts +494 -0
  26. package/src/logger.js +42 -0
  27. package/src/parser/EnhancedParser.js +205 -0
  28. package/src/parser/EnhancedParser.ts +251 -0
  29. package/src/parser/HoloScriptPlusParser.js +928 -0
  30. package/src/parser/HoloScriptPlusParser.ts +1089 -0
  31. package/src/runtime/HoloScriptPlusRuntime.js +674 -0
  32. package/src/runtime/HoloScriptPlusRuntime.ts +861 -0
  33. package/src/runtime/PerformanceTelemetry.js +323 -0
  34. package/src/runtime/PerformanceTelemetry.ts +467 -0
  35. package/src/runtime/RuntimeOptimization.js +361 -0
  36. package/src/runtime/RuntimeOptimization.ts +416 -0
  37. package/src/services/HololandGraphicsPipelineService.js +506 -0
  38. package/src/services/HololandGraphicsPipelineService.ts +662 -0
  39. package/src/services/PlatformPerformanceOptimizer.js +356 -0
  40. package/src/services/PlatformPerformanceOptimizer.ts +503 -0
  41. package/src/state/ReactiveState.js +427 -0
  42. package/src/state/ReactiveState.ts +572 -0
  43. package/src/tools/DeveloperExperience.js +376 -0
  44. package/src/tools/DeveloperExperience.ts +438 -0
  45. package/src/traits/AIDriverTrait.js +322 -0
  46. package/src/traits/AIDriverTrait.test.js +329 -0
  47. package/src/traits/AIDriverTrait.test.ts +357 -0
  48. package/src/traits/AIDriverTrait.ts +474 -0
  49. package/src/traits/LightingTrait.js +313 -0
  50. package/src/traits/LightingTrait.test.js +410 -0
  51. package/src/traits/LightingTrait.test.ts +462 -0
  52. package/src/traits/LightingTrait.ts +505 -0
  53. package/src/traits/MaterialTrait.js +194 -0
  54. package/src/traits/MaterialTrait.test.js +286 -0
  55. package/src/traits/MaterialTrait.test.ts +329 -0
  56. package/src/traits/MaterialTrait.ts +324 -0
  57. package/src/traits/RenderingTrait.js +356 -0
  58. package/src/traits/RenderingTrait.test.js +363 -0
  59. package/src/traits/RenderingTrait.test.ts +427 -0
  60. package/src/traits/RenderingTrait.ts +555 -0
  61. package/src/traits/VRTraitSystem.js +740 -0
  62. package/src/traits/VRTraitSystem.ts +1040 -0
  63. package/src/traits/VoiceInputTrait.js +284 -0
  64. package/src/traits/VoiceInputTrait.test.js +226 -0
  65. package/src/traits/VoiceInputTrait.test.ts +252 -0
  66. package/src/traits/VoiceInputTrait.ts +401 -0
  67. package/src/types/AdvancedTypeSystem.js +226 -0
  68. package/src/types/AdvancedTypeSystem.ts +494 -0
  69. package/src/types/HoloScriptPlus.d.ts +853 -0
  70. package/src/types.js +6 -0
  71. package/src/types.ts +96 -1
  72. package/tsconfig.json +1 -1
  73. package/tsup.config.d.ts +2 -0
  74. package/tsup.config.js +18 -0
  75. package/LICENSE +0 -21
  76. package/dist/chunk-3X2EGU7Z.cjs +0 -52
  77. package/dist/chunk-3X2EGU7Z.cjs.map +0 -1
  78. package/dist/chunk-723TPVHD.js +0 -1074
  79. package/dist/chunk-723TPVHD.js.map +0 -1
  80. package/dist/chunk-EOKNAVDO.cjs +0 -424
  81. package/dist/chunk-EOKNAVDO.cjs.map +0 -1
  82. package/dist/chunk-HQZ3HUMY.js +0 -1087
  83. package/dist/chunk-HQZ3HUMY.js.map +0 -1
  84. package/dist/chunk-KWYIVRIH.js +0 -344
  85. package/dist/chunk-KWYIVRIH.js.map +0 -1
  86. package/dist/chunk-LKH4ZAN6.js +0 -421
  87. package/dist/chunk-LKH4ZAN6.js.map +0 -1
  88. package/dist/chunk-SATNCODL.js +0 -45
  89. package/dist/chunk-SATNCODL.js.map +0 -1
  90. package/dist/chunk-VMZN4EVR.cjs +0 -347
  91. package/dist/chunk-VMZN4EVR.cjs.map +0 -1
  92. package/dist/chunk-VV3UUUYP.cjs +0 -1089
  93. package/dist/chunk-VV3UUUYP.cjs.map +0 -1
  94. package/dist/chunk-XRYTSQHZ.cjs +0 -1076
  95. package/dist/chunk-XRYTSQHZ.cjs.map +0 -1
  96. package/dist/debugger.cjs +0 -19
  97. package/dist/debugger.cjs.map +0 -1
  98. package/dist/debugger.d.cts +0 -171
  99. package/dist/debugger.d.ts +0 -171
  100. package/dist/debugger.js +0 -6
  101. package/dist/debugger.js.map +0 -1
  102. package/dist/index.cjs +0 -755
  103. package/dist/index.cjs.map +0 -1
  104. package/dist/index.d.cts +0 -169
  105. package/dist/index.d.ts +0 -169
  106. package/dist/index.js +0 -699
  107. package/dist/index.js.map +0 -1
  108. package/dist/parser.cjs +0 -13
  109. package/dist/parser.cjs.map +0 -1
  110. package/dist/parser.d.cts +0 -154
  111. package/dist/parser.d.ts +0 -154
  112. package/dist/parser.js +0 -4
  113. package/dist/parser.js.map +0 -1
  114. package/dist/runtime.cjs +0 -13
  115. package/dist/runtime.cjs.map +0 -1
  116. package/dist/runtime.d.cts +0 -147
  117. package/dist/runtime.d.ts +0 -147
  118. package/dist/runtime.js +0 -4
  119. package/dist/runtime.js.map +0 -1
  120. package/dist/type-checker.cjs +0 -16
  121. package/dist/type-checker.cjs.map +0 -1
  122. package/dist/type-checker.d.cts +0 -105
  123. package/dist/type-checker.d.ts +0 -105
  124. package/dist/type-checker.js +0 -3
  125. package/dist/type-checker.js.map +0 -1
  126. package/dist/types-WQSk1Qs2.d.cts +0 -238
  127. package/dist/types-WQSk1Qs2.d.ts +0 -238
@@ -0,0 +1,226 @@
1
+ /**
2
+ * @holoscript/core Advanced Type System
3
+ *
4
+ * Union types, generics, type inference, exhaustiveness checking
5
+ */
6
+ /**
7
+ * Type inference engine
8
+ */
9
+ export class TypeInferenceEngine {
10
+ constructor() {
11
+ this.typeEnvironment = new Map();
12
+ this.genericTypeVars = new Map();
13
+ }
14
+ /**
15
+ * Infer type from value
16
+ */
17
+ inferType(value) {
18
+ if (typeof value === 'number') {
19
+ return { kind: 'primitive', name: 'number' };
20
+ }
21
+ if (typeof value === 'string') {
22
+ return { kind: 'primitive', name: 'string' };
23
+ }
24
+ if (typeof value === 'boolean') {
25
+ return { kind: 'primitive', name: 'boolean' };
26
+ }
27
+ if (Array.isArray(value)) {
28
+ const elementType = value.length > 0 ? this.inferType(value[0]) : { kind: 'primitive', name: 'void' };
29
+ return { kind: 'array', elementType };
30
+ }
31
+ return { kind: 'primitive', name: 'void' };
32
+ }
33
+ /**
34
+ * Check type compatibility
35
+ */
36
+ isAssignableTo(from, to) {
37
+ // Same type
38
+ if (JSON.stringify(from) === JSON.stringify(to))
39
+ return true;
40
+ // Union type includes from
41
+ if (to.kind === 'union') {
42
+ return to.members.some((m) => this.isAssignableTo(from, m));
43
+ }
44
+ // Intersection type all match
45
+ if (from.kind === 'intersection') {
46
+ return from.members.every((m) => this.isAssignableTo(m, to));
47
+ }
48
+ // Array covariance
49
+ if (from.kind === 'array' && to.kind === 'array') {
50
+ return this.isAssignableTo(from.elementType, to.elementType);
51
+ }
52
+ return false;
53
+ }
54
+ /**
55
+ * Unify types (for generics)
56
+ */
57
+ unify(t1, t2) {
58
+ const substitutions = new Map();
59
+ // If t1 is a type variable
60
+ if (t1.kind === 'custom' && this.isTypeVariable(t1.name)) {
61
+ substitutions.set(t1.name, t2);
62
+ return substitutions;
63
+ }
64
+ // Structural unification
65
+ if (t1.kind === 'array' && t2.kind === 'array') {
66
+ return this.unify(t1.elementType, t2.elementType);
67
+ }
68
+ if (t1.kind === 'generic' && t2.kind === 'generic') {
69
+ if (t1.name === t2.name && t1.typeArgs.length === t2.typeArgs.length) {
70
+ for (let i = 0; i < t1.typeArgs.length; i++) {
71
+ const unified = this.unify(t1.typeArgs[i], t2.typeArgs[i]);
72
+ for (const [k, v] of unified) {
73
+ substitutions.set(k, v);
74
+ }
75
+ }
76
+ }
77
+ }
78
+ return substitutions;
79
+ }
80
+ isTypeVariable(name) {
81
+ return /^[A-Z]$/.test(name); // Single uppercase letter is type var
82
+ }
83
+ /**
84
+ * Resolve generic type with type arguments
85
+ */
86
+ resolveGeneric(generic, concreteTypes) {
87
+ const substitutions = new Map();
88
+ for (let i = 0; i < generic.typeArgs.length; i++) {
89
+ if (generic.typeArgs[i].kind === 'custom') {
90
+ substitutions.set(generic.typeArgs[i].name, concreteTypes[i]);
91
+ }
92
+ }
93
+ return this.substitute(generic, substitutions);
94
+ }
95
+ substitute(type, subs) {
96
+ if (type.kind === 'custom' && subs.has(type.name)) {
97
+ return subs.get(type.name);
98
+ }
99
+ if (type.kind === 'array') {
100
+ return {
101
+ kind: 'array',
102
+ elementType: this.substitute(type.elementType, subs),
103
+ };
104
+ }
105
+ if (type.kind === 'union') {
106
+ return {
107
+ kind: 'union',
108
+ members: type.members.map((m) => this.substitute(m, subs)),
109
+ };
110
+ }
111
+ return type;
112
+ }
113
+ }
114
+ /**
115
+ * Exhaustiveness checker for match statements
116
+ */
117
+ export class ExhaustivenessChecker {
118
+ /**
119
+ * Check if all union members are covered in match statement
120
+ */
121
+ checkMatch(unionType, casePatterns) {
122
+ const patterns = new Set(casePatterns.map((p) => p.toLowerCase()));
123
+ const uncovered = [];
124
+ for (const member of unionType.members) {
125
+ const caseName = this.getCaseName(member);
126
+ if (!patterns.has(caseName.toLowerCase()) && caseName !== '_') {
127
+ uncovered.push(caseName);
128
+ }
129
+ }
130
+ return {
131
+ isExhaustive: uncovered.length === 0 || patterns.has('_'),
132
+ uncoveredCases: uncovered,
133
+ };
134
+ }
135
+ getCaseName(type) {
136
+ if (type.kind === 'literal') {
137
+ return String(type.value);
138
+ }
139
+ if (type.kind === 'custom') {
140
+ return type.name;
141
+ }
142
+ return type.kind;
143
+ }
144
+ }
145
+ /**
146
+ * Type checker for HoloScript+
147
+ */
148
+ export class AdvancedTypeChecker {
149
+ constructor() {
150
+ this.types = new Map();
151
+ this.inference = new TypeInferenceEngine();
152
+ this.exhaustiveness = new ExhaustivenessChecker();
153
+ // Register built-in types
154
+ this.registerBuiltins();
155
+ }
156
+ registerBuiltins() {
157
+ this.types.set('Vector3', {
158
+ kind: 'custom',
159
+ name: 'Vector3',
160
+ properties: new Map([
161
+ ['x', { kind: 'primitive', name: 'number' }],
162
+ ['y', { kind: 'primitive', name: 'number' }],
163
+ ['z', { kind: 'primitive', name: 'number' }],
164
+ ]),
165
+ methods: new Map(),
166
+ });
167
+ this.types.set('Transform', {
168
+ kind: 'custom',
169
+ name: 'Transform',
170
+ properties: new Map([
171
+ ['position', this.types.get('Vector3')],
172
+ ['rotation', this.types.get('Vector3')],
173
+ ['scale', this.types.get('Vector3')],
174
+ ]),
175
+ methods: new Map(),
176
+ });
177
+ }
178
+ /**
179
+ * Register a new type
180
+ */
181
+ registerType(name, type) {
182
+ this.types.set(name, type);
183
+ }
184
+ /**
185
+ * Get registered type
186
+ */
187
+ getType(name) {
188
+ return this.types.get(name);
189
+ }
190
+ /**
191
+ * Check union exhaustiveness
192
+ */
193
+ checkUnionExhaustiveness(unionType, cases) {
194
+ return this.exhaustiveness.checkMatch(unionType, cases);
195
+ }
196
+ /**
197
+ * Check type assignment
198
+ */
199
+ checkAssignment(from, to) {
200
+ if (this.inference.isAssignableTo(from, to)) {
201
+ return { valid: true };
202
+ }
203
+ return {
204
+ valid: false,
205
+ error: `Type '${this.formatType(from)}' is not assignable to '${this.formatType(to)}'`,
206
+ };
207
+ }
208
+ formatType(type) {
209
+ switch (type.kind) {
210
+ case 'primitive':
211
+ return type.name;
212
+ case 'array':
213
+ return `${this.formatType(type.elementType)}[]`;
214
+ case 'union':
215
+ return type.members.map((m) => this.formatType(m)).join(' | ');
216
+ case 'intersection':
217
+ return type.members.map((m) => this.formatType(m)).join(' & ');
218
+ case 'custom':
219
+ return type.name;
220
+ case 'literal':
221
+ return JSON.stringify(type.value);
222
+ default:
223
+ return 'unknown';
224
+ }
225
+ }
226
+ }
@@ -0,0 +1,494 @@
1
+ /**
2
+ * @holoscript/core Advanced Type System
3
+ *
4
+ * Union types, generics, type inference, exhaustiveness checking
5
+ */
6
+
7
+ export type HoloScriptType =
8
+ | PrimitiveType
9
+ | ArrayType
10
+ | UnionType
11
+ | IntersectionType
12
+ | GenericType
13
+ | LiteralType
14
+ | CustomType;
15
+
16
+ /**
17
+ * Primitive types
18
+ */
19
+ export type PrimitiveTypeName = 'number' | 'string' | 'boolean' | 'void';
20
+
21
+ export interface PrimitiveType {
22
+ kind: 'primitive';
23
+ name: PrimitiveTypeName;
24
+ }
25
+
26
+ /**
27
+ * Array type: T[]
28
+ */
29
+ export interface ArrayType {
30
+ kind: 'array';
31
+ elementType: HoloScriptType;
32
+ }
33
+
34
+ /**
35
+ * Union type: A | B | C
36
+ */
37
+ export interface UnionType {
38
+ kind: 'union';
39
+ members: HoloScriptType[];
40
+ }
41
+
42
+ /**
43
+ * Intersection type: A & B
44
+ */
45
+ export interface IntersectionType {
46
+ kind: 'intersection';
47
+ members: HoloScriptType[];
48
+ }
49
+
50
+ /**
51
+ * Generic type: Container<T>
52
+ */
53
+ export interface GenericType {
54
+ kind: 'generic';
55
+ name: string;
56
+ typeArgs: HoloScriptType[];
57
+ }
58
+
59
+ /**
60
+ * Literal type: "idle" | "moving"
61
+ */
62
+ export interface LiteralType {
63
+ kind: 'literal';
64
+ value: string | number | boolean;
65
+ }
66
+
67
+ /**
68
+ * Custom type: User-defined types
69
+ */
70
+ export interface CustomType {
71
+ kind: 'custom';
72
+ name: string;
73
+ properties: Map<string, HoloScriptType>;
74
+ methods: Map<string, FunctionType>;
75
+ }
76
+
77
+ /**
78
+ * Function type
79
+ */
80
+ export interface FunctionType {
81
+ kind: 'function';
82
+ parameters: { name: string; type: HoloScriptType }[];
83
+ returnType: HoloScriptType;
84
+ }
85
+
86
+ /**
87
+ * Type inference engine
88
+ */
89
+ export class TypeInferenceEngine {
90
+ // Reserved for future type environment tracking
91
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
92
+ // private typeEnvironment: Map<string, HoloScriptType> = new Map();
93
+ // private genericTypeVars: Map<string, HoloScriptType> = new Map();
94
+
95
+ /**
96
+ * Infer type from value
97
+ */
98
+ inferType(value: any): HoloScriptType {
99
+ if (typeof value === 'number') {
100
+ return { kind: 'primitive', name: 'number' };
101
+ }
102
+ if (typeof value === 'string') {
103
+ return { kind: 'primitive', name: 'string' };
104
+ }
105
+ if (typeof value === 'boolean') {
106
+ return { kind: 'primitive', name: 'boolean' };
107
+ }
108
+ if (Array.isArray(value)) {
109
+ const elementType: HoloScriptType = value.length > 0 ? this.inferType(value[0]) : { kind: 'primitive', name: 'void' };
110
+ return { kind: 'array', elementType } as ArrayType;
111
+ }
112
+ return { kind: 'primitive', name: 'void' };
113
+ }
114
+
115
+ /**
116
+ * Check type compatibility
117
+ */
118
+ isAssignableTo(from: HoloScriptType, to: HoloScriptType): boolean {
119
+ // Same type
120
+ if (JSON.stringify(from) === JSON.stringify(to)) return true;
121
+
122
+ // Union type includes from
123
+ if (to.kind === 'union') {
124
+ return to.members.some((m) => this.isAssignableTo(from, m));
125
+ }
126
+
127
+ // Intersection type all match
128
+ if (from.kind === 'intersection') {
129
+ return from.members.every((m) => this.isAssignableTo(m, to));
130
+ }
131
+
132
+ // Array covariance
133
+ if (from.kind === 'array' && to.kind === 'array') {
134
+ return this.isAssignableTo(from.elementType, to.elementType);
135
+ }
136
+
137
+ return false;
138
+ }
139
+
140
+ /**
141
+ * Unify types (for generics)
142
+ */
143
+ unify(t1: HoloScriptType, t2: HoloScriptType): Map<string, HoloScriptType> {
144
+ const substitutions = new Map<string, HoloScriptType>();
145
+
146
+ // If t1 is a type variable
147
+ if (t1.kind === 'custom' && this.isTypeVariable(t1.name)) {
148
+ substitutions.set(t1.name, t2);
149
+ return substitutions;
150
+ }
151
+
152
+ // Structural unification
153
+ if (t1.kind === 'array' && t2.kind === 'array') {
154
+ return this.unify(t1.elementType, t2.elementType);
155
+ }
156
+
157
+ if (t1.kind === 'generic' && t2.kind === 'generic') {
158
+ if (t1.name === t2.name && t1.typeArgs.length === t2.typeArgs.length) {
159
+ for (let i = 0; i < t1.typeArgs.length; i++) {
160
+ const unified = this.unify(t1.typeArgs[i], t2.typeArgs[i]);
161
+ for (const [k, v] of unified) {
162
+ substitutions.set(k, v);
163
+ }
164
+ }
165
+ }
166
+ }
167
+
168
+ return substitutions;
169
+ }
170
+
171
+ private isTypeVariable(name: string): boolean {
172
+ return /^[A-Z]$/.test(name); // Single uppercase letter is type var
173
+ }
174
+
175
+ /**
176
+ * Resolve generic type with type arguments
177
+ */
178
+ resolveGeneric(generic: GenericType, concreteTypes: HoloScriptType[]): HoloScriptType {
179
+ const substitutions = new Map<string, HoloScriptType>();
180
+
181
+ for (let i = 0; i < generic.typeArgs.length; i++) {
182
+ if (generic.typeArgs[i].kind === 'custom') {
183
+ substitutions.set((generic.typeArgs[i] as CustomType).name, concreteTypes[i]);
184
+ }
185
+ }
186
+
187
+ return this.substitute(generic, substitutions);
188
+ }
189
+
190
+ private substitute(type: HoloScriptType, subs: Map<string, HoloScriptType>): HoloScriptType {
191
+ if (type.kind === 'custom' && subs.has((type as CustomType).name)) {
192
+ return subs.get((type as CustomType).name)!;
193
+ }
194
+
195
+ if (type.kind === 'array') {
196
+ return {
197
+ kind: 'array',
198
+ elementType: this.substitute((type as ArrayType).elementType, subs),
199
+ };
200
+ }
201
+
202
+ if (type.kind === 'union') {
203
+ return {
204
+ kind: 'union',
205
+ members: (type as UnionType).members.map((m) => this.substitute(m, subs)),
206
+ };
207
+ }
208
+
209
+ return type;
210
+ }
211
+ }
212
+
213
+ /**
214
+ * Exhaustiveness checker for match statements
215
+ */
216
+ export class ExhaustivenessChecker {
217
+ /**
218
+ * Check if all union members are covered in match statement
219
+ */
220
+ checkMatch(unionType: UnionType, casePatterns: string[]): {
221
+ isExhaustive: boolean;
222
+ uncoveredCases: string[];
223
+ } {
224
+ const patterns = new Set(casePatterns.map((p) => p.toLowerCase()));
225
+
226
+ const uncovered: string[] = [];
227
+ for (const member of unionType.members) {
228
+ const caseName = this.getCaseName(member);
229
+ if (!patterns.has(caseName.toLowerCase()) && caseName !== '_') {
230
+ uncovered.push(caseName);
231
+ }
232
+ }
233
+
234
+ return {
235
+ isExhaustive: uncovered.length === 0 || patterns.has('_'),
236
+ uncoveredCases: uncovered,
237
+ };
238
+ }
239
+
240
+ private getCaseName(type: HoloScriptType): string {
241
+ if (type.kind === 'literal') {
242
+ return String((type as LiteralType).value);
243
+ }
244
+ if (type.kind === 'custom') {
245
+ return (type as CustomType).name;
246
+ }
247
+ return type.kind;
248
+ }
249
+ }
250
+
251
+ /**
252
+ * Type checker for HoloScript+
253
+ */
254
+ export class AdvancedTypeChecker {
255
+ private inference: TypeInferenceEngine;
256
+ private exhaustiveness: ExhaustivenessChecker;
257
+ private types: Map<string, HoloScriptType> = new Map();
258
+
259
+ constructor() {
260
+ this.inference = new TypeInferenceEngine();
261
+ this.exhaustiveness = new ExhaustivenessChecker();
262
+
263
+ // Register built-in types
264
+ this.registerBuiltins();
265
+ }
266
+
267
+ private registerBuiltins(): void {
268
+ this.types.set('Vector3', {
269
+ kind: 'custom',
270
+ name: 'Vector3',
271
+ properties: new Map([
272
+ ['x', { kind: 'primitive', name: 'number' }],
273
+ ['y', { kind: 'primitive', name: 'number' }],
274
+ ['z', { kind: 'primitive', name: 'number' }],
275
+ ]),
276
+ methods: new Map(),
277
+ });
278
+
279
+ this.types.set('Transform', {
280
+ kind: 'custom',
281
+ name: 'Transform',
282
+ properties: new Map([
283
+ ['position', this.types.get('Vector3')!],
284
+ ['rotation', this.types.get('Vector3')!],
285
+ ['scale', this.types.get('Vector3')!],
286
+ ]),
287
+ methods: new Map(),
288
+ });
289
+ }
290
+
291
+ /**
292
+ * Register a new type
293
+ */
294
+ registerType(name: string, type: HoloScriptType): void {
295
+ this.types.set(name, type);
296
+ }
297
+
298
+ /**
299
+ * Get registered type
300
+ */
301
+ getType(name: string): HoloScriptType | undefined {
302
+ return this.types.get(name);
303
+ }
304
+
305
+ /**
306
+ * Check union exhaustiveness
307
+ */
308
+ checkUnionExhaustiveness(
309
+ unionType: UnionType,
310
+ cases: string[]
311
+ ): { isExhaustive: boolean; uncoveredCases: string[] } {
312
+ return this.exhaustiveness.checkMatch(unionType, cases);
313
+ }
314
+
315
+ /**
316
+ * Check type assignment
317
+ */
318
+ checkAssignment(from: HoloScriptType, to: HoloScriptType): { valid: boolean; error?: string } {
319
+ if (this.inference.isAssignableTo(from, to)) {
320
+ return { valid: true };
321
+ }
322
+
323
+ return {
324
+ valid: false,
325
+ error: `Type '${this.formatType(from)}' is not assignable to '${this.formatType(to)}'`,
326
+ };
327
+ }
328
+
329
+ private formatType(type: HoloScriptType): string {
330
+ switch (type.kind) {
331
+ case 'primitive':
332
+ return (type as PrimitiveType).name;
333
+ case 'array':
334
+ return `${this.formatType((type as ArrayType).elementType)}[]`;
335
+ case 'union':
336
+ return (type as UnionType).members.map((m) => this.formatType(m)).join(' | ');
337
+ case 'intersection':
338
+ return (type as IntersectionType).members.map((m) => this.formatType(m)).join(' & ');
339
+ case 'custom':
340
+ return (type as CustomType).name;
341
+ case 'literal':
342
+ return JSON.stringify((type as LiteralType).value);
343
+ default:
344
+ return 'unknown';
345
+ }
346
+ }
347
+ }
348
+
349
+ /**
350
+ * HoloScript+ AST Types
351
+ */
352
+ export interface HSPlusNode {
353
+ type: 'directive' | 'trait' | 'lifecycle' | 'state' | 'for' | 'if' | 'import' | 'component' | 'element' | 'fragment' | 'Program';
354
+ [key: string]: any;
355
+ }
356
+
357
+ export interface HSPlusAST extends HSPlusNode {
358
+ type: 'Program';
359
+ body: HSPlusNode[];
360
+ version: string;
361
+ root: HSPlusNode;
362
+ imports: Array<{ path: string; alias: string }>;
363
+ hasState: boolean;
364
+ hasVRTraits: boolean;
365
+ hasControlFlow: boolean;
366
+ }
367
+
368
+ export interface HSPlusDirective extends HSPlusNode {
369
+ type: 'directive' | 'trait' | 'lifecycle' | 'state' | 'for' | 'if' | 'import' | 'fragment';
370
+ name: string;
371
+ args: string[];
372
+ enableTypeScriptImports?: boolean;
373
+ enableVRTraits?: boolean;
374
+ }
375
+
376
+ export interface HSPlusCompileResult {
377
+ success: boolean;
378
+ code?: string;
379
+ sourceMap?: any;
380
+ errors: Array<{ message: string; line: number; column: number }>;
381
+ ast?: any;
382
+ compiledExpressions?: any;
383
+ requiredCompanions?: string[];
384
+ features?: any;
385
+ warnings?: any[];
386
+ [key: string]: any;
387
+ }
388
+
389
+ export interface HSPlusParserOptions {
390
+ sourceMap?: boolean;
391
+ strict?: boolean;
392
+ enableTypeScriptImports?: boolean;
393
+ enableVRTraits?: boolean;
394
+ }
395
+
396
+ export type VRTraitName =
397
+ | 'grabbable'
398
+ | 'throwable'
399
+ | 'pointable'
400
+ | 'scalable'
401
+ | 'draggable'
402
+ | 'rotatable'
403
+ | 'clickable'
404
+ | 'hoverable'
405
+ | 'pressable'
406
+ | 'stackable'
407
+ | 'snappable'
408
+ | 'breakable';
409
+
410
+ export interface StateDeclaration {
411
+ name: string;
412
+ type: HoloScriptType;
413
+ initialValue?: any;
414
+ [key: string]: any;
415
+ }
416
+
417
+ export interface LifecycleHook {
418
+ name: 'mounted' | 'updated' | 'destroyed';
419
+ handler: string;
420
+ }
421
+
422
+ export interface VRLifecycleHook {
423
+ name: 'grabbed' | 'released' | 'pointed' | 'unpointed' | 'thrown';
424
+ handler: string;
425
+ }
426
+
427
+ export interface ControllerHook {
428
+ name: 'trigger' | 'grip' | 'thumbstick' | 'button_a' | 'button_b';
429
+ handler: string;
430
+ }
431
+
432
+ /**
433
+ * Vector3 type for 3D coordinates
434
+ */
435
+ export interface Vector3 {
436
+ x: number;
437
+ y: number;
438
+ z: number;
439
+ }
440
+
441
+ /**
442
+ * Color type for RGBA colors
443
+ */
444
+ export interface Color {
445
+ r: number;
446
+ g: number;
447
+ b: number;
448
+ a?: number;
449
+ }
450
+
451
+ /**
452
+ * VR Hand representation
453
+ */
454
+ export interface VRHand {
455
+ position: Vector3;
456
+ rotation: Vector3;
457
+ pinch: number;
458
+ grip: number;
459
+ pointing: boolean;
460
+ }
461
+
462
+ /**
463
+ * HoloScript+ Runtime built-in functions
464
+ */
465
+ export interface HSPlusBuiltins {
466
+ log: (...args: any[]) => void;
467
+ warn: (...args: any[]) => void;
468
+ error: (...args: any[]) => void;
469
+ setTimeout: (fn: () => void, ms: number) => number;
470
+ clearTimeout: (id: number) => void;
471
+ setInterval: (fn: () => void, ms: number) => number;
472
+ clearInterval: (id: number) => void;
473
+ fetch: (url: string, options?: any) => Promise<any>;
474
+ emit: (event: string, data?: any) => void;
475
+ on: (event: string, handler: (data: any) => void) => void;
476
+ off: (event: string, handler?: (data: any) => void) => void;
477
+ [key: string]: any;
478
+ }
479
+
480
+ /**
481
+ * HoloScript+ Runtime interface
482
+ */
483
+ export interface HSPlusRuntime {
484
+ state: Record<string, any>;
485
+ props: Record<string, any>;
486
+ refs: Record<string, any>;
487
+ builtins: HSPlusBuiltins;
488
+ execute: (ast: HSPlusAST) => any;
489
+ evaluate: (expression: string) => any;
490
+ callMethod: (name: string, args: any[]) => any;
491
+ setState: (key: string, value: any) => void;
492
+ getState: (key: string) => any;
493
+ destroy: () => void;
494
+ }