jslike 1.7.1 → 1.7.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.
@@ -39,6 +39,121 @@ export class Interpreter {
39
39
  }
40
40
  }
41
41
 
42
+ async evaluateAsyncRawValue(node, env) {
43
+ if (!node) return { value: undefined };
44
+
45
+ if (node.type === 'CallExpression') {
46
+ return await this.evaluateCallExpressionAsyncRawValue(node, env);
47
+ }
48
+
49
+ if (node.type === 'MemberExpression') {
50
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
51
+
52
+ if (node.optional && (obj === null || obj === undefined)) {
53
+ return { value: undefined };
54
+ }
55
+
56
+ if (obj === null || obj === undefined) {
57
+ throw new TypeError(`Cannot read property of ${obj}`);
58
+ }
59
+
60
+ const prop = node.computed
61
+ ? await this.evaluateAsync(node.property, env)
62
+ : node.property.name;
63
+
64
+ return { value: obj[prop] };
65
+ }
66
+
67
+ if (node.type === 'ChainExpression') {
68
+ return await this.evaluateAsyncRawValue(node.expression, env);
69
+ }
70
+
71
+ if (node.type === 'ConditionalExpression') {
72
+ const test = await this.evaluateAsync(node.test, env);
73
+ return await this.evaluateAsyncRawValue(test ? node.consequent : node.alternate, env);
74
+ }
75
+
76
+ if (node.type === 'LogicalExpression') {
77
+ const left = await this.evaluateAsync(node.left, env);
78
+ if (node.operator === '&&') {
79
+ return left ? await this.evaluateAsyncRawValue(node.right, env) : { value: left };
80
+ }
81
+ if (node.operator === '||') {
82
+ return left ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
83
+ }
84
+ if (node.operator === '??') {
85
+ return left !== null && left !== undefined
86
+ ? { value: left }
87
+ : await this.evaluateAsyncRawValue(node.right, env);
88
+ }
89
+ }
90
+
91
+ if (node.type === 'SequenceExpression') {
92
+ for (let i = 0; i < node.expressions.length - 1; i++) {
93
+ await this.evaluateAsync(node.expressions[i], env);
94
+ }
95
+ return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
96
+ }
97
+
98
+ if (node.type === 'NewExpression') {
99
+ return { value: this.evaluateNewExpression(node, env) };
100
+ }
101
+
102
+ if (['Literal', 'Identifier', 'ThisExpression', 'Super'].includes(node.type)) {
103
+ return { value: this.evaluate(node, env) };
104
+ }
105
+
106
+ return { value: await this.evaluateAsync(node, env) };
107
+ }
108
+
109
+ async evaluateCallExpressionAsyncRawValue(node, env) {
110
+ let thisContext = undefined;
111
+ let callee;
112
+ let objectName = null;
113
+ let methodName = null;
114
+
115
+ if (node.callee.type === 'MemberExpression') {
116
+ thisContext = (await this.evaluateAsyncRawValue(node.callee.object, env)).value;
117
+ if (node.callee.optional && (thisContext === null || thisContext === undefined)) {
118
+ return { value: undefined };
119
+ }
120
+ const prop = node.callee.computed
121
+ ? await this.evaluateAsync(node.callee.property, env)
122
+ : node.callee.property.name;
123
+ callee = thisContext[prop];
124
+
125
+ methodName = prop;
126
+ objectName = this.getExpressionName(node.callee.object);
127
+ } else {
128
+ callee = await this.evaluateAsync(node.callee, env);
129
+ }
130
+
131
+ if (node.optional && (callee === null || callee === undefined)) {
132
+ return { value: undefined };
133
+ }
134
+
135
+ const rawArgs = [];
136
+ for (const arg of node.arguments) {
137
+ rawArgs.push(await this.evaluateAsync(arg, env));
138
+ }
139
+ const args = this.flattenSpreadArgs(rawArgs);
140
+
141
+ if (typeof callee === 'function') {
142
+ const value = thisContext !== undefined
143
+ ? callee.call(thisContext, ...args)
144
+ : callee(...args);
145
+ return { value };
146
+ } else if (callee && callee.__isFunction) {
147
+ return { value: this.callUserFunction(callee, args, env, thisContext) };
148
+ }
149
+
150
+ if (objectName && methodName) {
151
+ throw createMethodNotFoundError(objectName, methodName, thisContext);
152
+ }
153
+
154
+ throw new TypeError(`${node.callee.name || 'Expression'} is not a function`);
155
+ }
156
+
42
157
  // Async evaluation for async functions - handles await expressions
43
158
  async evaluateAsync(node, env) {
44
159
  if (!node) return undefined;
@@ -77,7 +192,7 @@ export class Interpreter {
77
192
  if (node.type === 'VariableDeclaration') {
78
193
  for (const declarator of node.declarations) {
79
194
  const value = declarator.init
80
- ? await this.evaluateAsync(declarator.init, env)
195
+ ? (await this.evaluateAsyncRawValue(declarator.init, env)).value
81
196
  : undefined;
82
197
 
83
198
  const isConst = node.kind === 'const';
@@ -134,51 +249,8 @@ export class Interpreter {
134
249
 
135
250
  // For call expressions (might be calling async functions)
136
251
  if (node.type === 'CallExpression') {
137
- let thisContext = undefined;
138
- let callee;
139
- let objectName = null;
140
- let methodName = null;
141
-
142
- if (node.callee.type === 'MemberExpression') {
143
- thisContext = await this.evaluateAsync(node.callee.object, env);
144
- const prop = node.callee.computed
145
- ? await this.evaluateAsync(node.callee.property, env)
146
- : node.callee.property.name;
147
- callee = thisContext[prop];
148
-
149
- // Capture names for enhanced error messages
150
- methodName = prop;
151
- objectName = this.getExpressionName(node.callee.object);
152
- } else {
153
- callee = await this.evaluateAsync(node.callee, env);
154
- }
155
-
156
- // Handle optional call - if optional and callee is null/undefined, return undefined
157
- if (node.optional && (callee === null || callee === undefined)) {
158
- return undefined;
159
- }
160
-
161
- const rawArgs = [];
162
- for (const arg of node.arguments) {
163
- rawArgs.push(await this.evaluateAsync(arg, env));
164
- }
165
- const args = this.flattenSpreadArgs(rawArgs);
166
-
167
- if (typeof callee === 'function') {
168
- if (thisContext !== undefined) {
169
- return await callee.call(thisContext, ...args);
170
- }
171
- return await callee(...args);
172
- } else if (callee && callee.__isFunction) {
173
- return await this.callUserFunction(callee, args, env, thisContext);
174
- }
175
-
176
- // Throw enhanced error for member expression calls
177
- if (objectName && methodName) {
178
- throw createMethodNotFoundError(objectName, methodName, thisContext);
179
- }
180
-
181
- throw new TypeError(`${node.callee.name || 'Expression'} is not a function`);
252
+ const result = (await this.evaluateCallExpressionAsyncRawValue(node, env)).value;
253
+ return await result;
182
254
  }
183
255
 
184
256
  // For chain expressions (optional chaining)
@@ -188,7 +260,7 @@ export class Interpreter {
188
260
 
189
261
  // For member expressions in async context
190
262
  if (node.type === 'MemberExpression') {
191
- const obj = await this.evaluateAsync(node.object, env);
263
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
192
264
 
193
265
  // Handle optional chaining
194
266
  if (node.optional && (obj === null || obj === undefined)) {
@@ -510,7 +582,7 @@ export class Interpreter {
510
582
 
511
583
  // For AssignmentExpression with async value
512
584
  if (node.type === 'AssignmentExpression') {
513
- const value = await this.evaluateAsync(node.right, env);
585
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
514
586
 
515
587
  if (node.left.type === 'Identifier') {
516
588
  const name = node.left.name;
@@ -1230,6 +1302,9 @@ export class Interpreter {
1230
1302
  if (node.callee.type === 'MemberExpression') {
1231
1303
  // For method calls like obj.method(), set this to obj
1232
1304
  thisContext = this.evaluate(node.callee.object, env);
1305
+ if (node.callee.optional && (thisContext === null || thisContext === undefined)) {
1306
+ return undefined;
1307
+ }
1233
1308
  const prop = node.callee.computed
1234
1309
  ? this.evaluate(node.callee.property, env)
1235
1310
  : node.callee.property.name;
package/dist/index.cjs CHANGED
@@ -6507,6 +6507,91 @@ var Interpreter = class _Interpreter {
6507
6507
  return null;
6508
6508
  }
6509
6509
  }
6510
+ async evaluateAsyncRawValue(node, env) {
6511
+ if (!node) return { value: void 0 };
6512
+ if (node.type === "CallExpression") {
6513
+ return await this.evaluateCallExpressionAsyncRawValue(node, env);
6514
+ }
6515
+ if (node.type === "MemberExpression") {
6516
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
6517
+ if (node.optional && (obj === null || obj === void 0)) {
6518
+ return { value: void 0 };
6519
+ }
6520
+ if (obj === null || obj === void 0) {
6521
+ throw new TypeError(`Cannot read property of ${obj}`);
6522
+ }
6523
+ const prop = node.computed ? await this.evaluateAsync(node.property, env) : node.property.name;
6524
+ return { value: obj[prop] };
6525
+ }
6526
+ if (node.type === "ChainExpression") {
6527
+ return await this.evaluateAsyncRawValue(node.expression, env);
6528
+ }
6529
+ if (node.type === "ConditionalExpression") {
6530
+ const test = await this.evaluateAsync(node.test, env);
6531
+ return await this.evaluateAsyncRawValue(test ? node.consequent : node.alternate, env);
6532
+ }
6533
+ if (node.type === "LogicalExpression") {
6534
+ const left = await this.evaluateAsync(node.left, env);
6535
+ if (node.operator === "&&") {
6536
+ return left ? await this.evaluateAsyncRawValue(node.right, env) : { value: left };
6537
+ }
6538
+ if (node.operator === "||") {
6539
+ return left ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
6540
+ }
6541
+ if (node.operator === "??") {
6542
+ return left !== null && left !== void 0 ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
6543
+ }
6544
+ }
6545
+ if (node.type === "SequenceExpression") {
6546
+ for (let i = 0; i < node.expressions.length - 1; i++) {
6547
+ await this.evaluateAsync(node.expressions[i], env);
6548
+ }
6549
+ return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
6550
+ }
6551
+ if (node.type === "NewExpression") {
6552
+ return { value: this.evaluateNewExpression(node, env) };
6553
+ }
6554
+ if (["Literal", "Identifier", "ThisExpression", "Super"].includes(node.type)) {
6555
+ return { value: this.evaluate(node, env) };
6556
+ }
6557
+ return { value: await this.evaluateAsync(node, env) };
6558
+ }
6559
+ async evaluateCallExpressionAsyncRawValue(node, env) {
6560
+ let thisContext = void 0;
6561
+ let callee;
6562
+ let objectName = null;
6563
+ let methodName = null;
6564
+ if (node.callee.type === "MemberExpression") {
6565
+ thisContext = (await this.evaluateAsyncRawValue(node.callee.object, env)).value;
6566
+ if (node.callee.optional && (thisContext === null || thisContext === void 0)) {
6567
+ return { value: void 0 };
6568
+ }
6569
+ const prop = node.callee.computed ? await this.evaluateAsync(node.callee.property, env) : node.callee.property.name;
6570
+ callee = thisContext[prop];
6571
+ methodName = prop;
6572
+ objectName = this.getExpressionName(node.callee.object);
6573
+ } else {
6574
+ callee = await this.evaluateAsync(node.callee, env);
6575
+ }
6576
+ if (node.optional && (callee === null || callee === void 0)) {
6577
+ return { value: void 0 };
6578
+ }
6579
+ const rawArgs = [];
6580
+ for (const arg of node.arguments) {
6581
+ rawArgs.push(await this.evaluateAsync(arg, env));
6582
+ }
6583
+ const args = this.flattenSpreadArgs(rawArgs);
6584
+ if (typeof callee === "function") {
6585
+ const value = thisContext !== void 0 ? callee.call(thisContext, ...args) : callee(...args);
6586
+ return { value };
6587
+ } else if (callee && callee.__isFunction) {
6588
+ return { value: this.callUserFunction(callee, args, env, thisContext) };
6589
+ }
6590
+ if (objectName && methodName) {
6591
+ throw createMethodNotFoundError(objectName, methodName, thisContext);
6592
+ }
6593
+ throw new TypeError(`${node.callee.name || "Expression"} is not a function`);
6594
+ }
6510
6595
  // Async evaluation for async functions - handles await expressions
6511
6596
  async evaluateAsync(node, env) {
6512
6597
  if (!node) return void 0;
@@ -6532,7 +6617,7 @@ var Interpreter = class _Interpreter {
6532
6617
  }
6533
6618
  if (node.type === "VariableDeclaration") {
6534
6619
  for (const declarator of node.declarations) {
6535
- const value = declarator.init ? await this.evaluateAsync(declarator.init, env) : void 0;
6620
+ const value = declarator.init ? (await this.evaluateAsyncRawValue(declarator.init, env)).value : void 0;
6536
6621
  const isConst = node.kind === "const";
6537
6622
  if (declarator.id.type === "Identifier") {
6538
6623
  env.define(declarator.id.name, value, isConst);
@@ -6573,45 +6658,14 @@ var Interpreter = class _Interpreter {
6573
6658
  return this.evaluateBinaryExpressionValues(node.operator, left, right);
6574
6659
  }
6575
6660
  if (node.type === "CallExpression") {
6576
- let thisContext = void 0;
6577
- let callee;
6578
- let objectName = null;
6579
- let methodName = null;
6580
- if (node.callee.type === "MemberExpression") {
6581
- thisContext = await this.evaluateAsync(node.callee.object, env);
6582
- const prop = node.callee.computed ? await this.evaluateAsync(node.callee.property, env) : node.callee.property.name;
6583
- callee = thisContext[prop];
6584
- methodName = prop;
6585
- objectName = this.getExpressionName(node.callee.object);
6586
- } else {
6587
- callee = await this.evaluateAsync(node.callee, env);
6588
- }
6589
- if (node.optional && (callee === null || callee === void 0)) {
6590
- return void 0;
6591
- }
6592
- const rawArgs = [];
6593
- for (const arg of node.arguments) {
6594
- rawArgs.push(await this.evaluateAsync(arg, env));
6595
- }
6596
- const args = this.flattenSpreadArgs(rawArgs);
6597
- if (typeof callee === "function") {
6598
- if (thisContext !== void 0) {
6599
- return await callee.call(thisContext, ...args);
6600
- }
6601
- return await callee(...args);
6602
- } else if (callee && callee.__isFunction) {
6603
- return await this.callUserFunction(callee, args, env, thisContext);
6604
- }
6605
- if (objectName && methodName) {
6606
- throw createMethodNotFoundError(objectName, methodName, thisContext);
6607
- }
6608
- throw new TypeError(`${node.callee.name || "Expression"} is not a function`);
6661
+ const result = (await this.evaluateCallExpressionAsyncRawValue(node, env)).value;
6662
+ return await result;
6609
6663
  }
6610
6664
  if (node.type === "ChainExpression") {
6611
6665
  return await this.evaluateAsync(node.expression, env);
6612
6666
  }
6613
6667
  if (node.type === "MemberExpression") {
6614
- const obj = await this.evaluateAsync(node.object, env);
6668
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
6615
6669
  if (node.optional && (obj === null || obj === void 0)) {
6616
6670
  return void 0;
6617
6671
  }
@@ -6869,7 +6923,7 @@ var Interpreter = class _Interpreter {
6869
6923
  return test ? await this.evaluateAsync(node.consequent, env) : await this.evaluateAsync(node.alternate, env);
6870
6924
  }
6871
6925
  if (node.type === "AssignmentExpression") {
6872
- const value = await this.evaluateAsync(node.right, env);
6926
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
6873
6927
  if (node.left.type === "Identifier") {
6874
6928
  const name = node.left.name;
6875
6929
  if (node.operator === "=") {
@@ -7447,6 +7501,9 @@ var Interpreter = class _Interpreter {
7447
7501
  let methodName = null;
7448
7502
  if (node.callee.type === "MemberExpression") {
7449
7503
  thisContext = this.evaluate(node.callee.object, env);
7504
+ if (node.callee.optional && (thisContext === null || thisContext === void 0)) {
7505
+ return void 0;
7506
+ }
7450
7507
  const prop = node.callee.computed ? this.evaluate(node.callee.property, env) : node.callee.property.name;
7451
7508
  callee = thisContext[prop];
7452
7509
  methodName = prop;
package/dist/index.d.cts CHANGED
@@ -7204,6 +7204,121 @@ class Interpreter {
7204
7204
  }
7205
7205
  }
7206
7206
 
7207
+ async evaluateAsyncRawValue(node, env) {
7208
+ if (!node) return { value: undefined };
7209
+
7210
+ if (node.type === 'CallExpression') {
7211
+ return await this.evaluateCallExpressionAsyncRawValue(node, env);
7212
+ }
7213
+
7214
+ if (node.type === 'MemberExpression') {
7215
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
7216
+
7217
+ if (node.optional && (obj === null || obj === undefined)) {
7218
+ return { value: undefined };
7219
+ }
7220
+
7221
+ if (obj === null || obj === undefined) {
7222
+ throw new TypeError(`Cannot read property of ${obj}`);
7223
+ }
7224
+
7225
+ const prop = node.computed
7226
+ ? await this.evaluateAsync(node.property, env)
7227
+ : node.property.name;
7228
+
7229
+ return { value: obj[prop] };
7230
+ }
7231
+
7232
+ if (node.type === 'ChainExpression') {
7233
+ return await this.evaluateAsyncRawValue(node.expression, env);
7234
+ }
7235
+
7236
+ if (node.type === 'ConditionalExpression') {
7237
+ const test = await this.evaluateAsync(node.test, env);
7238
+ return await this.evaluateAsyncRawValue(test ? node.consequent : node.alternate, env);
7239
+ }
7240
+
7241
+ if (node.type === 'LogicalExpression') {
7242
+ const left = await this.evaluateAsync(node.left, env);
7243
+ if (node.operator === '&&') {
7244
+ return left ? await this.evaluateAsyncRawValue(node.right, env) : { value: left };
7245
+ }
7246
+ if (node.operator === '||') {
7247
+ return left ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
7248
+ }
7249
+ if (node.operator === '??') {
7250
+ return left !== null && left !== undefined
7251
+ ? { value: left }
7252
+ : await this.evaluateAsyncRawValue(node.right, env);
7253
+ }
7254
+ }
7255
+
7256
+ if (node.type === 'SequenceExpression') {
7257
+ for (let i = 0; i < node.expressions.length - 1; i++) {
7258
+ await this.evaluateAsync(node.expressions[i], env);
7259
+ }
7260
+ return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
7261
+ }
7262
+
7263
+ if (node.type === 'NewExpression') {
7264
+ return { value: this.evaluateNewExpression(node, env) };
7265
+ }
7266
+
7267
+ if (['Literal', 'Identifier', 'ThisExpression', 'Super'].includes(node.type)) {
7268
+ return { value: this.evaluate(node, env) };
7269
+ }
7270
+
7271
+ return { value: await this.evaluateAsync(node, env) };
7272
+ }
7273
+
7274
+ async evaluateCallExpressionAsyncRawValue(node, env) {
7275
+ let thisContext = undefined;
7276
+ let callee;
7277
+ let objectName = null;
7278
+ let methodName = null;
7279
+
7280
+ if (node.callee.type === 'MemberExpression') {
7281
+ thisContext = (await this.evaluateAsyncRawValue(node.callee.object, env)).value;
7282
+ if (node.callee.optional && (thisContext === null || thisContext === undefined)) {
7283
+ return { value: undefined };
7284
+ }
7285
+ const prop = node.callee.computed
7286
+ ? await this.evaluateAsync(node.callee.property, env)
7287
+ : node.callee.property.name;
7288
+ callee = thisContext[prop];
7289
+
7290
+ methodName = prop;
7291
+ objectName = this.getExpressionName(node.callee.object);
7292
+ } else {
7293
+ callee = await this.evaluateAsync(node.callee, env);
7294
+ }
7295
+
7296
+ if (node.optional && (callee === null || callee === undefined)) {
7297
+ return { value: undefined };
7298
+ }
7299
+
7300
+ const rawArgs = [];
7301
+ for (const arg of node.arguments) {
7302
+ rawArgs.push(await this.evaluateAsync(arg, env));
7303
+ }
7304
+ const args = this.flattenSpreadArgs(rawArgs);
7305
+
7306
+ if (typeof callee === 'function') {
7307
+ const value = thisContext !== undefined
7308
+ ? callee.call(thisContext, ...args)
7309
+ : callee(...args);
7310
+ return { value };
7311
+ } else if (callee && callee.__isFunction) {
7312
+ return { value: this.callUserFunction(callee, args, env, thisContext) };
7313
+ }
7314
+
7315
+ if (objectName && methodName) {
7316
+ throw createMethodNotFoundError(objectName, methodName, thisContext);
7317
+ }
7318
+
7319
+ throw new TypeError(`${node.callee.name || 'Expression'} is not a function`);
7320
+ }
7321
+
7207
7322
  // Async evaluation for async functions - handles await expressions
7208
7323
  async evaluateAsync(node, env) {
7209
7324
  if (!node) return undefined;
@@ -7242,7 +7357,7 @@ class Interpreter {
7242
7357
  if (node.type === 'VariableDeclaration') {
7243
7358
  for (const declarator of node.declarations) {
7244
7359
  const value = declarator.init
7245
- ? await this.evaluateAsync(declarator.init, env)
7360
+ ? (await this.evaluateAsyncRawValue(declarator.init, env)).value
7246
7361
  : undefined;
7247
7362
 
7248
7363
  const isConst = node.kind === 'const';
@@ -7299,51 +7414,8 @@ class Interpreter {
7299
7414
 
7300
7415
  // For call expressions (might be calling async functions)
7301
7416
  if (node.type === 'CallExpression') {
7302
- let thisContext = undefined;
7303
- let callee;
7304
- let objectName = null;
7305
- let methodName = null;
7306
-
7307
- if (node.callee.type === 'MemberExpression') {
7308
- thisContext = await this.evaluateAsync(node.callee.object, env);
7309
- const prop = node.callee.computed
7310
- ? await this.evaluateAsync(node.callee.property, env)
7311
- : node.callee.property.name;
7312
- callee = thisContext[prop];
7313
-
7314
- // Capture names for enhanced error messages
7315
- methodName = prop;
7316
- objectName = this.getExpressionName(node.callee.object);
7317
- } else {
7318
- callee = await this.evaluateAsync(node.callee, env);
7319
- }
7320
-
7321
- // Handle optional call - if optional and callee is null/undefined, return undefined
7322
- if (node.optional && (callee === null || callee === undefined)) {
7323
- return undefined;
7324
- }
7325
-
7326
- const rawArgs = [];
7327
- for (const arg of node.arguments) {
7328
- rawArgs.push(await this.evaluateAsync(arg, env));
7329
- }
7330
- const args = this.flattenSpreadArgs(rawArgs);
7331
-
7332
- if (typeof callee === 'function') {
7333
- if (thisContext !== undefined) {
7334
- return await callee.call(thisContext, ...args);
7335
- }
7336
- return await callee(...args);
7337
- } else if (callee && callee.__isFunction) {
7338
- return await this.callUserFunction(callee, args, env, thisContext);
7339
- }
7340
-
7341
- // Throw enhanced error for member expression calls
7342
- if (objectName && methodName) {
7343
- throw createMethodNotFoundError(objectName, methodName, thisContext);
7344
- }
7345
-
7346
- throw new TypeError(`${node.callee.name || 'Expression'} is not a function`);
7417
+ const result = (await this.evaluateCallExpressionAsyncRawValue(node, env)).value;
7418
+ return await result;
7347
7419
  }
7348
7420
 
7349
7421
  // For chain expressions (optional chaining)
@@ -7353,7 +7425,7 @@ class Interpreter {
7353
7425
 
7354
7426
  // For member expressions in async context
7355
7427
  if (node.type === 'MemberExpression') {
7356
- const obj = await this.evaluateAsync(node.object, env);
7428
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
7357
7429
 
7358
7430
  // Handle optional chaining
7359
7431
  if (node.optional && (obj === null || obj === undefined)) {
@@ -7675,7 +7747,7 @@ class Interpreter {
7675
7747
 
7676
7748
  // For AssignmentExpression with async value
7677
7749
  if (node.type === 'AssignmentExpression') {
7678
- const value = await this.evaluateAsync(node.right, env);
7750
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
7679
7751
 
7680
7752
  if (node.left.type === 'Identifier') {
7681
7753
  const name = node.left.name;
@@ -8395,6 +8467,9 @@ class Interpreter {
8395
8467
  if (node.callee.type === 'MemberExpression') {
8396
8468
  // For method calls like obj.method(), set this to obj
8397
8469
  thisContext = this.evaluate(node.callee.object, env);
8470
+ if (node.callee.optional && (thisContext === null || thisContext === undefined)) {
8471
+ return undefined;
8472
+ }
8398
8473
  const prop = node.callee.computed
8399
8474
  ? this.evaluate(node.callee.property, env)
8400
8475
  : node.callee.property.name;
package/dist/index.d.ts CHANGED
@@ -7204,6 +7204,121 @@ class Interpreter {
7204
7204
  }
7205
7205
  }
7206
7206
 
7207
+ async evaluateAsyncRawValue(node, env) {
7208
+ if (!node) return { value: undefined };
7209
+
7210
+ if (node.type === 'CallExpression') {
7211
+ return await this.evaluateCallExpressionAsyncRawValue(node, env);
7212
+ }
7213
+
7214
+ if (node.type === 'MemberExpression') {
7215
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
7216
+
7217
+ if (node.optional && (obj === null || obj === undefined)) {
7218
+ return { value: undefined };
7219
+ }
7220
+
7221
+ if (obj === null || obj === undefined) {
7222
+ throw new TypeError(`Cannot read property of ${obj}`);
7223
+ }
7224
+
7225
+ const prop = node.computed
7226
+ ? await this.evaluateAsync(node.property, env)
7227
+ : node.property.name;
7228
+
7229
+ return { value: obj[prop] };
7230
+ }
7231
+
7232
+ if (node.type === 'ChainExpression') {
7233
+ return await this.evaluateAsyncRawValue(node.expression, env);
7234
+ }
7235
+
7236
+ if (node.type === 'ConditionalExpression') {
7237
+ const test = await this.evaluateAsync(node.test, env);
7238
+ return await this.evaluateAsyncRawValue(test ? node.consequent : node.alternate, env);
7239
+ }
7240
+
7241
+ if (node.type === 'LogicalExpression') {
7242
+ const left = await this.evaluateAsync(node.left, env);
7243
+ if (node.operator === '&&') {
7244
+ return left ? await this.evaluateAsyncRawValue(node.right, env) : { value: left };
7245
+ }
7246
+ if (node.operator === '||') {
7247
+ return left ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
7248
+ }
7249
+ if (node.operator === '??') {
7250
+ return left !== null && left !== undefined
7251
+ ? { value: left }
7252
+ : await this.evaluateAsyncRawValue(node.right, env);
7253
+ }
7254
+ }
7255
+
7256
+ if (node.type === 'SequenceExpression') {
7257
+ for (let i = 0; i < node.expressions.length - 1; i++) {
7258
+ await this.evaluateAsync(node.expressions[i], env);
7259
+ }
7260
+ return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
7261
+ }
7262
+
7263
+ if (node.type === 'NewExpression') {
7264
+ return { value: this.evaluateNewExpression(node, env) };
7265
+ }
7266
+
7267
+ if (['Literal', 'Identifier', 'ThisExpression', 'Super'].includes(node.type)) {
7268
+ return { value: this.evaluate(node, env) };
7269
+ }
7270
+
7271
+ return { value: await this.evaluateAsync(node, env) };
7272
+ }
7273
+
7274
+ async evaluateCallExpressionAsyncRawValue(node, env) {
7275
+ let thisContext = undefined;
7276
+ let callee;
7277
+ let objectName = null;
7278
+ let methodName = null;
7279
+
7280
+ if (node.callee.type === 'MemberExpression') {
7281
+ thisContext = (await this.evaluateAsyncRawValue(node.callee.object, env)).value;
7282
+ if (node.callee.optional && (thisContext === null || thisContext === undefined)) {
7283
+ return { value: undefined };
7284
+ }
7285
+ const prop = node.callee.computed
7286
+ ? await this.evaluateAsync(node.callee.property, env)
7287
+ : node.callee.property.name;
7288
+ callee = thisContext[prop];
7289
+
7290
+ methodName = prop;
7291
+ objectName = this.getExpressionName(node.callee.object);
7292
+ } else {
7293
+ callee = await this.evaluateAsync(node.callee, env);
7294
+ }
7295
+
7296
+ if (node.optional && (callee === null || callee === undefined)) {
7297
+ return { value: undefined };
7298
+ }
7299
+
7300
+ const rawArgs = [];
7301
+ for (const arg of node.arguments) {
7302
+ rawArgs.push(await this.evaluateAsync(arg, env));
7303
+ }
7304
+ const args = this.flattenSpreadArgs(rawArgs);
7305
+
7306
+ if (typeof callee === 'function') {
7307
+ const value = thisContext !== undefined
7308
+ ? callee.call(thisContext, ...args)
7309
+ : callee(...args);
7310
+ return { value };
7311
+ } else if (callee && callee.__isFunction) {
7312
+ return { value: this.callUserFunction(callee, args, env, thisContext) };
7313
+ }
7314
+
7315
+ if (objectName && methodName) {
7316
+ throw createMethodNotFoundError(objectName, methodName, thisContext);
7317
+ }
7318
+
7319
+ throw new TypeError(`${node.callee.name || 'Expression'} is not a function`);
7320
+ }
7321
+
7207
7322
  // Async evaluation for async functions - handles await expressions
7208
7323
  async evaluateAsync(node, env) {
7209
7324
  if (!node) return undefined;
@@ -7242,7 +7357,7 @@ class Interpreter {
7242
7357
  if (node.type === 'VariableDeclaration') {
7243
7358
  for (const declarator of node.declarations) {
7244
7359
  const value = declarator.init
7245
- ? await this.evaluateAsync(declarator.init, env)
7360
+ ? (await this.evaluateAsyncRawValue(declarator.init, env)).value
7246
7361
  : undefined;
7247
7362
 
7248
7363
  const isConst = node.kind === 'const';
@@ -7299,51 +7414,8 @@ class Interpreter {
7299
7414
 
7300
7415
  // For call expressions (might be calling async functions)
7301
7416
  if (node.type === 'CallExpression') {
7302
- let thisContext = undefined;
7303
- let callee;
7304
- let objectName = null;
7305
- let methodName = null;
7306
-
7307
- if (node.callee.type === 'MemberExpression') {
7308
- thisContext = await this.evaluateAsync(node.callee.object, env);
7309
- const prop = node.callee.computed
7310
- ? await this.evaluateAsync(node.callee.property, env)
7311
- : node.callee.property.name;
7312
- callee = thisContext[prop];
7313
-
7314
- // Capture names for enhanced error messages
7315
- methodName = prop;
7316
- objectName = this.getExpressionName(node.callee.object);
7317
- } else {
7318
- callee = await this.evaluateAsync(node.callee, env);
7319
- }
7320
-
7321
- // Handle optional call - if optional and callee is null/undefined, return undefined
7322
- if (node.optional && (callee === null || callee === undefined)) {
7323
- return undefined;
7324
- }
7325
-
7326
- const rawArgs = [];
7327
- for (const arg of node.arguments) {
7328
- rawArgs.push(await this.evaluateAsync(arg, env));
7329
- }
7330
- const args = this.flattenSpreadArgs(rawArgs);
7331
-
7332
- if (typeof callee === 'function') {
7333
- if (thisContext !== undefined) {
7334
- return await callee.call(thisContext, ...args);
7335
- }
7336
- return await callee(...args);
7337
- } else if (callee && callee.__isFunction) {
7338
- return await this.callUserFunction(callee, args, env, thisContext);
7339
- }
7340
-
7341
- // Throw enhanced error for member expression calls
7342
- if (objectName && methodName) {
7343
- throw createMethodNotFoundError(objectName, methodName, thisContext);
7344
- }
7345
-
7346
- throw new TypeError(`${node.callee.name || 'Expression'} is not a function`);
7417
+ const result = (await this.evaluateCallExpressionAsyncRawValue(node, env)).value;
7418
+ return await result;
7347
7419
  }
7348
7420
 
7349
7421
  // For chain expressions (optional chaining)
@@ -7353,7 +7425,7 @@ class Interpreter {
7353
7425
 
7354
7426
  // For member expressions in async context
7355
7427
  if (node.type === 'MemberExpression') {
7356
- const obj = await this.evaluateAsync(node.object, env);
7428
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
7357
7429
 
7358
7430
  // Handle optional chaining
7359
7431
  if (node.optional && (obj === null || obj === undefined)) {
@@ -7675,7 +7747,7 @@ class Interpreter {
7675
7747
 
7676
7748
  // For AssignmentExpression with async value
7677
7749
  if (node.type === 'AssignmentExpression') {
7678
- const value = await this.evaluateAsync(node.right, env);
7750
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
7679
7751
 
7680
7752
  if (node.left.type === 'Identifier') {
7681
7753
  const name = node.left.name;
@@ -8395,6 +8467,9 @@ class Interpreter {
8395
8467
  if (node.callee.type === 'MemberExpression') {
8396
8468
  // For method calls like obj.method(), set this to obj
8397
8469
  thisContext = this.evaluate(node.callee.object, env);
8470
+ if (node.callee.optional && (thisContext === null || thisContext === undefined)) {
8471
+ return undefined;
8472
+ }
8398
8473
  const prop = node.callee.computed
8399
8474
  ? this.evaluate(node.callee.property, env)
8400
8475
  : node.callee.property.name;
package/dist/index.js CHANGED
@@ -6473,6 +6473,91 @@ var Interpreter = class _Interpreter {
6473
6473
  return null;
6474
6474
  }
6475
6475
  }
6476
+ async evaluateAsyncRawValue(node, env) {
6477
+ if (!node) return { value: void 0 };
6478
+ if (node.type === "CallExpression") {
6479
+ return await this.evaluateCallExpressionAsyncRawValue(node, env);
6480
+ }
6481
+ if (node.type === "MemberExpression") {
6482
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
6483
+ if (node.optional && (obj === null || obj === void 0)) {
6484
+ return { value: void 0 };
6485
+ }
6486
+ if (obj === null || obj === void 0) {
6487
+ throw new TypeError(`Cannot read property of ${obj}`);
6488
+ }
6489
+ const prop = node.computed ? await this.evaluateAsync(node.property, env) : node.property.name;
6490
+ return { value: obj[prop] };
6491
+ }
6492
+ if (node.type === "ChainExpression") {
6493
+ return await this.evaluateAsyncRawValue(node.expression, env);
6494
+ }
6495
+ if (node.type === "ConditionalExpression") {
6496
+ const test = await this.evaluateAsync(node.test, env);
6497
+ return await this.evaluateAsyncRawValue(test ? node.consequent : node.alternate, env);
6498
+ }
6499
+ if (node.type === "LogicalExpression") {
6500
+ const left = await this.evaluateAsync(node.left, env);
6501
+ if (node.operator === "&&") {
6502
+ return left ? await this.evaluateAsyncRawValue(node.right, env) : { value: left };
6503
+ }
6504
+ if (node.operator === "||") {
6505
+ return left ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
6506
+ }
6507
+ if (node.operator === "??") {
6508
+ return left !== null && left !== void 0 ? { value: left } : await this.evaluateAsyncRawValue(node.right, env);
6509
+ }
6510
+ }
6511
+ if (node.type === "SequenceExpression") {
6512
+ for (let i = 0; i < node.expressions.length - 1; i++) {
6513
+ await this.evaluateAsync(node.expressions[i], env);
6514
+ }
6515
+ return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
6516
+ }
6517
+ if (node.type === "NewExpression") {
6518
+ return { value: this.evaluateNewExpression(node, env) };
6519
+ }
6520
+ if (["Literal", "Identifier", "ThisExpression", "Super"].includes(node.type)) {
6521
+ return { value: this.evaluate(node, env) };
6522
+ }
6523
+ return { value: await this.evaluateAsync(node, env) };
6524
+ }
6525
+ async evaluateCallExpressionAsyncRawValue(node, env) {
6526
+ let thisContext = void 0;
6527
+ let callee;
6528
+ let objectName = null;
6529
+ let methodName = null;
6530
+ if (node.callee.type === "MemberExpression") {
6531
+ thisContext = (await this.evaluateAsyncRawValue(node.callee.object, env)).value;
6532
+ if (node.callee.optional && (thisContext === null || thisContext === void 0)) {
6533
+ return { value: void 0 };
6534
+ }
6535
+ const prop = node.callee.computed ? await this.evaluateAsync(node.callee.property, env) : node.callee.property.name;
6536
+ callee = thisContext[prop];
6537
+ methodName = prop;
6538
+ objectName = this.getExpressionName(node.callee.object);
6539
+ } else {
6540
+ callee = await this.evaluateAsync(node.callee, env);
6541
+ }
6542
+ if (node.optional && (callee === null || callee === void 0)) {
6543
+ return { value: void 0 };
6544
+ }
6545
+ const rawArgs = [];
6546
+ for (const arg of node.arguments) {
6547
+ rawArgs.push(await this.evaluateAsync(arg, env));
6548
+ }
6549
+ const args = this.flattenSpreadArgs(rawArgs);
6550
+ if (typeof callee === "function") {
6551
+ const value = thisContext !== void 0 ? callee.call(thisContext, ...args) : callee(...args);
6552
+ return { value };
6553
+ } else if (callee && callee.__isFunction) {
6554
+ return { value: this.callUserFunction(callee, args, env, thisContext) };
6555
+ }
6556
+ if (objectName && methodName) {
6557
+ throw createMethodNotFoundError(objectName, methodName, thisContext);
6558
+ }
6559
+ throw new TypeError(`${node.callee.name || "Expression"} is not a function`);
6560
+ }
6476
6561
  // Async evaluation for async functions - handles await expressions
6477
6562
  async evaluateAsync(node, env) {
6478
6563
  if (!node) return void 0;
@@ -6498,7 +6583,7 @@ var Interpreter = class _Interpreter {
6498
6583
  }
6499
6584
  if (node.type === "VariableDeclaration") {
6500
6585
  for (const declarator of node.declarations) {
6501
- const value = declarator.init ? await this.evaluateAsync(declarator.init, env) : void 0;
6586
+ const value = declarator.init ? (await this.evaluateAsyncRawValue(declarator.init, env)).value : void 0;
6502
6587
  const isConst = node.kind === "const";
6503
6588
  if (declarator.id.type === "Identifier") {
6504
6589
  env.define(declarator.id.name, value, isConst);
@@ -6539,45 +6624,14 @@ var Interpreter = class _Interpreter {
6539
6624
  return this.evaluateBinaryExpressionValues(node.operator, left, right);
6540
6625
  }
6541
6626
  if (node.type === "CallExpression") {
6542
- let thisContext = void 0;
6543
- let callee;
6544
- let objectName = null;
6545
- let methodName = null;
6546
- if (node.callee.type === "MemberExpression") {
6547
- thisContext = await this.evaluateAsync(node.callee.object, env);
6548
- const prop = node.callee.computed ? await this.evaluateAsync(node.callee.property, env) : node.callee.property.name;
6549
- callee = thisContext[prop];
6550
- methodName = prop;
6551
- objectName = this.getExpressionName(node.callee.object);
6552
- } else {
6553
- callee = await this.evaluateAsync(node.callee, env);
6554
- }
6555
- if (node.optional && (callee === null || callee === void 0)) {
6556
- return void 0;
6557
- }
6558
- const rawArgs = [];
6559
- for (const arg of node.arguments) {
6560
- rawArgs.push(await this.evaluateAsync(arg, env));
6561
- }
6562
- const args = this.flattenSpreadArgs(rawArgs);
6563
- if (typeof callee === "function") {
6564
- if (thisContext !== void 0) {
6565
- return await callee.call(thisContext, ...args);
6566
- }
6567
- return await callee(...args);
6568
- } else if (callee && callee.__isFunction) {
6569
- return await this.callUserFunction(callee, args, env, thisContext);
6570
- }
6571
- if (objectName && methodName) {
6572
- throw createMethodNotFoundError(objectName, methodName, thisContext);
6573
- }
6574
- throw new TypeError(`${node.callee.name || "Expression"} is not a function`);
6627
+ const result = (await this.evaluateCallExpressionAsyncRawValue(node, env)).value;
6628
+ return await result;
6575
6629
  }
6576
6630
  if (node.type === "ChainExpression") {
6577
6631
  return await this.evaluateAsync(node.expression, env);
6578
6632
  }
6579
6633
  if (node.type === "MemberExpression") {
6580
- const obj = await this.evaluateAsync(node.object, env);
6634
+ const obj = (await this.evaluateAsyncRawValue(node.object, env)).value;
6581
6635
  if (node.optional && (obj === null || obj === void 0)) {
6582
6636
  return void 0;
6583
6637
  }
@@ -6835,7 +6889,7 @@ var Interpreter = class _Interpreter {
6835
6889
  return test ? await this.evaluateAsync(node.consequent, env) : await this.evaluateAsync(node.alternate, env);
6836
6890
  }
6837
6891
  if (node.type === "AssignmentExpression") {
6838
- const value = await this.evaluateAsync(node.right, env);
6892
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
6839
6893
  if (node.left.type === "Identifier") {
6840
6894
  const name = node.left.name;
6841
6895
  if (node.operator === "=") {
@@ -7413,6 +7467,9 @@ var Interpreter = class _Interpreter {
7413
7467
  let methodName = null;
7414
7468
  if (node.callee.type === "MemberExpression") {
7415
7469
  thisContext = this.evaluate(node.callee.object, env);
7470
+ if (node.callee.optional && (thisContext === null || thisContext === void 0)) {
7471
+ return void 0;
7472
+ }
7416
7473
  const prop = node.callee.computed ? this.evaluate(node.callee.property, env) : node.callee.property.name;
7417
7474
  callee = thisContext[prop];
7418
7475
  methodName = prop;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jslike",
3
- "version": "1.7.1",
3
+ "version": "1.7.3",
4
4
  "description": "Production-ready JavaScript interpreter with full ES6+ support using Acorn parser",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.js",