jslike 1.8.8 → 1.8.10

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.
@@ -2,6 +2,20 @@ import { Environment, ReturnValue, BreakSignal, ContinueSignal, ThrowSignal } fr
2
2
  import { parse as acornParse, tsParse, tsxParse } from '../parser.js';
3
3
  import { createMethodNotFoundError } from '../errors/enhanced-error.js';
4
4
 
5
+ const ASYNC_EXPRESSION_COMPLETION = Symbol('jslike.asyncExpressionCompletion');
6
+
7
+ function createAsyncExpressionCompletion(value) {
8
+ return { [ASYNC_EXPRESSION_COMPLETION]: true, value };
9
+ }
10
+
11
+ function isAsyncExpressionCompletion(value) {
12
+ return value && value[ASYNC_EXPRESSION_COMPLETION] === true;
13
+ }
14
+
15
+ function unwrapAsyncExpressionCompletion(value) {
16
+ return isAsyncExpressionCompletion(value) ? value.value : value;
17
+ }
18
+
5
19
  function isTypeScriptPath(sourcePath) {
6
20
  return typeof sourcePath === 'string' && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
7
21
  }
@@ -398,6 +412,45 @@ export class Interpreter {
398
412
  return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
399
413
  }
400
414
 
415
+ if (node.type === 'AssignmentExpression') {
416
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
417
+
418
+ if (node.left.type === 'Identifier') {
419
+ const name = node.left.name;
420
+ if (node.operator === '=') {
421
+ if (env.has(name)) {
422
+ env.set(name, value);
423
+ } else {
424
+ env.define(name, value);
425
+ }
426
+ return { value };
427
+ }
428
+
429
+ const current = env.get(name);
430
+ const newValue = this.applyCompoundAssignment(node.operator, current, value);
431
+ env.set(name, newValue);
432
+ return { value: newValue };
433
+ }
434
+
435
+ if (node.left.type === 'MemberExpression') {
436
+ const obj = await this.evaluateAsync(node.left.object, env);
437
+ const prop = node.left.computed
438
+ ? await this.evaluateAsync(node.left.property, env)
439
+ : node.left.property.name;
440
+
441
+ if (node.operator === '=') {
442
+ obj[prop] = value;
443
+ return { value };
444
+ }
445
+
446
+ const newValue = this.applyCompoundAssignment(node.operator, obj[prop], value);
447
+ obj[prop] = newValue;
448
+ return { value: newValue };
449
+ }
450
+
451
+ throw new Error('Invalid assignment target');
452
+ }
453
+
401
454
  if (node.type === 'NewExpression') {
402
455
  return { value: this.evaluateNewExpression(node, env) };
403
456
  }
@@ -437,7 +490,7 @@ export class Interpreter {
437
490
 
438
491
  const rawArgs = [];
439
492
  for (const arg of node.arguments) {
440
- rawArgs.push(await this.evaluateAsync(arg, env));
493
+ rawArgs.push((await this.evaluateAsyncRawValue(arg, env)).value);
441
494
  }
442
495
  const args = this.flattenSpreadArgs(rawArgs);
443
496
 
@@ -513,7 +566,7 @@ export class Interpreter {
513
566
 
514
567
  // For expression statements, evaluate the expression async
515
568
  if (node.type === 'ExpressionStatement') {
516
- return await this.evaluateAsync(node.expression, env);
569
+ return createAsyncExpressionCompletion((await this.evaluateAsyncRawValue(node.expression, env)).value);
517
570
  }
518
571
 
519
572
  // For variable declarations with await in init
@@ -548,7 +601,7 @@ export class Interpreter {
548
601
  return result;
549
602
  }
550
603
  }
551
- return result;
604
+ return unwrapAsyncExpressionCompletion(result);
552
605
  } finally {
553
606
  this.runtimeIdentifierReferences = previousReferences;
554
607
  }
@@ -1026,7 +1079,7 @@ export class Interpreter {
1026
1079
  throw new TypeError('Spread syntax requires an iterable');
1027
1080
  }
1028
1081
  } else {
1029
- result.push(await this.evaluateAsync(elem, env));
1082
+ result.push((await this.evaluateAsyncRawValue(elem, env)).value);
1030
1083
  }
1031
1084
  }
1032
1085
  return result;
@@ -1045,7 +1098,7 @@ export class Interpreter {
1045
1098
  const key = prop.key.type === 'Identifier' && !prop.computed
1046
1099
  ? prop.key.name
1047
1100
  : await this.evaluateAsync(prop.key, env);
1048
- const value = prop.value ? await this.evaluateAsync(prop.value, env) : env.get(key);
1101
+ const value = prop.value ? (await this.evaluateAsyncRawValue(prop.value, env)).value : env.get(key);
1049
1102
  if (prop.method && prop.value.type === 'FunctionExpression') {
1050
1103
  obj[key] = (...args) => {
1051
1104
  const funcValue = this.evaluate(prop.value, env);
@@ -2401,7 +2454,7 @@ export class Interpreter {
2401
2454
  throw new Error(`Module '${modulePath}' has no export '${importedName}'`);
2402
2455
  }
2403
2456
 
2404
- env.define(localName, moduleExports[importedName]);
2457
+ env.defineLive(localName, () => moduleExports[importedName]);
2405
2458
  } else if (specifier.type === 'ImportDefaultSpecifier') {
2406
2459
  // Default import: import foo from "module"
2407
2460
  const localName = specifier.local.name;
@@ -2410,7 +2463,7 @@ export class Interpreter {
2410
2463
  throw new Error(`Module '${modulePath}' has no default export`);
2411
2464
  }
2412
2465
 
2413
- env.define(localName, moduleExports.default);
2466
+ env.defineLive(localName, () => moduleExports.default);
2414
2467
  } else if (specifier.type === 'ImportNamespaceSpecifier') {
2415
2468
  // Namespace import: import * as foo from "module"
2416
2469
  const localName = specifier.local.name;
@@ -4,17 +4,19 @@ export class Environment {
4
4
  constructor(parent = null) {
5
5
  this.parent = parent;
6
6
  this.vars = new Map();
7
+ this.liveBindings = new Map();
7
8
  this.consts = new Set(); // Track const variables
8
9
  }
9
10
 
10
11
  define(name, value, isConst = false) {
11
- if (this.vars.has(name)) {
12
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
12
13
  // Allow redeclaration for non-const (REPL-style behavior)
13
14
  // But cannot redeclare a const
14
15
  if (this.consts.has(name)) {
15
16
  throw new Error(`Cannot redeclare const '${name}'`);
16
17
  }
17
18
  // Update existing variable
19
+ this.liveBindings.delete(name);
18
20
  this.vars.set(name, value);
19
21
  if (isConst) {
20
22
  this.consts.add(name);
@@ -28,7 +30,24 @@ export class Environment {
28
30
  return value;
29
31
  }
30
32
 
33
+ defineLive(name, getter, isConst = true) {
34
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
35
+ if (this.consts.has(name)) {
36
+ throw new Error(`Cannot redeclare const '${name}'`);
37
+ }
38
+ this.vars.delete(name);
39
+ }
40
+ this.liveBindings.set(name, getter);
41
+ if (isConst) {
42
+ this.consts.add(name);
43
+ }
44
+ return getter();
45
+ }
46
+
31
47
  get(name) {
48
+ if (this.liveBindings.has(name)) {
49
+ return this.liveBindings.get(name)();
50
+ }
32
51
  if (this.vars.has(name)) {
33
52
  return this.vars.get(name);
34
53
  }
@@ -39,11 +58,12 @@ export class Environment {
39
58
  }
40
59
 
41
60
  set(name, value) {
42
- if (this.vars.has(name)) {
61
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
43
62
  // Check if trying to reassign a const variable
44
63
  if (this.consts.has(name)) {
45
64
  throw new TypeError(`Cannot reassign const variable '${name}'`);
46
65
  }
66
+ this.liveBindings.delete(name);
47
67
  this.vars.set(name, value);
48
68
  return value;
49
69
  }
@@ -54,7 +74,7 @@ export class Environment {
54
74
  }
55
75
 
56
76
  has(name) {
57
- return this.vars.has(name) || (this.parent ? this.parent.has(name) : false);
77
+ return this.vars.has(name) || this.liveBindings.has(name) || (this.parent ? this.parent.has(name) : false);
58
78
  }
59
79
 
60
80
  // For let/const block scoping
package/dist/index.cjs CHANGED
@@ -11320,13 +11320,15 @@ var Environment = class _Environment {
11320
11320
  constructor(parent = null) {
11321
11321
  this.parent = parent;
11322
11322
  this.vars = /* @__PURE__ */ new Map();
11323
+ this.liveBindings = /* @__PURE__ */ new Map();
11323
11324
  this.consts = /* @__PURE__ */ new Set();
11324
11325
  }
11325
11326
  define(name, value, isConst = false) {
11326
- if (this.vars.has(name)) {
11327
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11327
11328
  if (this.consts.has(name)) {
11328
11329
  throw new Error(`Cannot redeclare const '${name}'`);
11329
11330
  }
11331
+ this.liveBindings.delete(name);
11330
11332
  this.vars.set(name, value);
11331
11333
  if (isConst) {
11332
11334
  this.consts.add(name);
@@ -11339,7 +11341,23 @@ var Environment = class _Environment {
11339
11341
  }
11340
11342
  return value;
11341
11343
  }
11344
+ defineLive(name, getter, isConst = true) {
11345
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11346
+ if (this.consts.has(name)) {
11347
+ throw new Error(`Cannot redeclare const '${name}'`);
11348
+ }
11349
+ this.vars.delete(name);
11350
+ }
11351
+ this.liveBindings.set(name, getter);
11352
+ if (isConst) {
11353
+ this.consts.add(name);
11354
+ }
11355
+ return getter();
11356
+ }
11342
11357
  get(name) {
11358
+ if (this.liveBindings.has(name)) {
11359
+ return this.liveBindings.get(name)();
11360
+ }
11343
11361
  if (this.vars.has(name)) {
11344
11362
  return this.vars.get(name);
11345
11363
  }
@@ -11349,10 +11367,11 @@ var Environment = class _Environment {
11349
11367
  throw new ReferenceError(`Variable "${name}" is not defined`);
11350
11368
  }
11351
11369
  set(name, value) {
11352
- if (this.vars.has(name)) {
11370
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11353
11371
  if (this.consts.has(name)) {
11354
11372
  throw new TypeError(`Cannot reassign const variable '${name}'`);
11355
11373
  }
11374
+ this.liveBindings.delete(name);
11356
11375
  this.vars.set(name, value);
11357
11376
  return value;
11358
11377
  }
@@ -11362,7 +11381,7 @@ var Environment = class _Environment {
11362
11381
  throw new ReferenceError(`Variable "${name}" is not defined`);
11363
11382
  }
11364
11383
  has(name) {
11365
- return this.vars.has(name) || (this.parent ? this.parent.has(name) : false);
11384
+ return this.vars.has(name) || this.liveBindings.has(name) || (this.parent ? this.parent.has(name) : false);
11366
11385
  }
11367
11386
  // For let/const block scoping
11368
11387
  extend() {
@@ -11503,6 +11522,16 @@ function createMethodNotFoundError(objectName, methodName, objectValue) {
11503
11522
  }
11504
11523
 
11505
11524
  // src/interpreter/interpreter.js
11525
+ var ASYNC_EXPRESSION_COMPLETION = Symbol("jslike.asyncExpressionCompletion");
11526
+ function createAsyncExpressionCompletion(value) {
11527
+ return { [ASYNC_EXPRESSION_COMPLETION]: true, value };
11528
+ }
11529
+ function isAsyncExpressionCompletion(value) {
11530
+ return value && value[ASYNC_EXPRESSION_COMPLETION] === true;
11531
+ }
11532
+ function unwrapAsyncExpressionCompletion(value) {
11533
+ return isAsyncExpressionCompletion(value) ? value.value : value;
11534
+ }
11506
11535
  function isTypeScriptPath(sourcePath) {
11507
11536
  return typeof sourcePath === "string" && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
11508
11537
  }
@@ -11843,6 +11872,36 @@ var Interpreter = class _Interpreter {
11843
11872
  }
11844
11873
  return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
11845
11874
  }
11875
+ if (node.type === "AssignmentExpression") {
11876
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
11877
+ if (node.left.type === "Identifier") {
11878
+ const name = node.left.name;
11879
+ if (node.operator === "=") {
11880
+ if (env.has(name)) {
11881
+ env.set(name, value);
11882
+ } else {
11883
+ env.define(name, value);
11884
+ }
11885
+ return { value };
11886
+ }
11887
+ const current2 = env.get(name);
11888
+ const newValue = this.applyCompoundAssignment(node.operator, current2, value);
11889
+ env.set(name, newValue);
11890
+ return { value: newValue };
11891
+ }
11892
+ if (node.left.type === "MemberExpression") {
11893
+ const obj = await this.evaluateAsync(node.left.object, env);
11894
+ const prop = node.left.computed ? await this.evaluateAsync(node.left.property, env) : node.left.property.name;
11895
+ if (node.operator === "=") {
11896
+ obj[prop] = value;
11897
+ return { value };
11898
+ }
11899
+ const newValue = this.applyCompoundAssignment(node.operator, obj[prop], value);
11900
+ obj[prop] = newValue;
11901
+ return { value: newValue };
11902
+ }
11903
+ throw new Error("Invalid assignment target");
11904
+ }
11846
11905
  if (node.type === "NewExpression") {
11847
11906
  return { value: this.evaluateNewExpression(node, env) };
11848
11907
  }
@@ -11873,7 +11932,7 @@ var Interpreter = class _Interpreter {
11873
11932
  }
11874
11933
  const rawArgs = [];
11875
11934
  for (const arg of node.arguments) {
11876
- rawArgs.push(await this.evaluateAsync(arg, env));
11935
+ rawArgs.push((await this.evaluateAsyncRawValue(arg, env)).value);
11877
11936
  }
11878
11937
  const args = this.flattenSpreadArgs(rawArgs);
11879
11938
  if (typeof callee === "function") {
@@ -11927,7 +11986,7 @@ var Interpreter = class _Interpreter {
11927
11986
  return result;
11928
11987
  }
11929
11988
  if (node.type === "ExpressionStatement") {
11930
- return await this.evaluateAsync(node.expression, env);
11989
+ return createAsyncExpressionCompletion((await this.evaluateAsyncRawValue(node.expression, env)).value);
11931
11990
  }
11932
11991
  if (node.type === "VariableDeclaration") {
11933
11992
  for (const declarator of node.declarations) {
@@ -11954,7 +12013,7 @@ var Interpreter = class _Interpreter {
11954
12013
  return result;
11955
12014
  }
11956
12015
  }
11957
- return result;
12016
+ return unwrapAsyncExpressionCompletion(result);
11958
12017
  } finally {
11959
12018
  this.runtimeIdentifierReferences = previousReferences;
11960
12019
  }
@@ -12341,7 +12400,7 @@ var Interpreter = class _Interpreter {
12341
12400
  throw new TypeError("Spread syntax requires an iterable");
12342
12401
  }
12343
12402
  } else {
12344
- result.push(await this.evaluateAsync(elem, env));
12403
+ result.push((await this.evaluateAsyncRawValue(elem, env)).value);
12345
12404
  }
12346
12405
  }
12347
12406
  return result;
@@ -12356,7 +12415,7 @@ var Interpreter = class _Interpreter {
12356
12415
  }
12357
12416
  } else {
12358
12417
  const key = prop.key.type === "Identifier" && !prop.computed ? prop.key.name : await this.evaluateAsync(prop.key, env);
12359
- const value = prop.value ? await this.evaluateAsync(prop.value, env) : env.get(key);
12418
+ const value = prop.value ? (await this.evaluateAsyncRawValue(prop.value, env)).value : env.get(key);
12360
12419
  if (prop.method && prop.value.type === "FunctionExpression") {
12361
12420
  obj[key] = (...args) => {
12362
12421
  const funcValue = this.evaluate(prop.value, env);
@@ -13390,13 +13449,13 @@ var Interpreter = class _Interpreter {
13390
13449
  if (!(importedName in moduleExports)) {
13391
13450
  throw new Error(`Module '${modulePath}' has no export '${importedName}'`);
13392
13451
  }
13393
- env.define(localName, moduleExports[importedName]);
13452
+ env.defineLive(localName, () => moduleExports[importedName]);
13394
13453
  } else if (specifier.type === "ImportDefaultSpecifier") {
13395
13454
  const localName = specifier.local.name;
13396
13455
  if (!("default" in moduleExports)) {
13397
13456
  throw new Error(`Module '${modulePath}' has no default export`);
13398
13457
  }
13399
- env.define(localName, moduleExports.default);
13458
+ env.defineLive(localName, () => moduleExports.default);
13400
13459
  } else if (specifier.type === "ImportNamespaceSpecifier") {
13401
13460
  const localName = specifier.local.name;
13402
13461
  env.define(localName, moduleExports);
package/dist/index.d.cts CHANGED
@@ -11964,17 +11964,19 @@ class Environment {
11964
11964
  constructor(parent = null) {
11965
11965
  this.parent = parent;
11966
11966
  this.vars = new Map();
11967
+ this.liveBindings = new Map();
11967
11968
  this.consts = new Set(); // Track const variables
11968
11969
  }
11969
11970
 
11970
11971
  define(name, value, isConst = false) {
11971
- if (this.vars.has(name)) {
11972
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11972
11973
  // Allow redeclaration for non-const (REPL-style behavior)
11973
11974
  // But cannot redeclare a const
11974
11975
  if (this.consts.has(name)) {
11975
11976
  throw new Error(`Cannot redeclare const '${name}'`);
11976
11977
  }
11977
11978
  // Update existing variable
11979
+ this.liveBindings.delete(name);
11978
11980
  this.vars.set(name, value);
11979
11981
  if (isConst) {
11980
11982
  this.consts.add(name);
@@ -11988,7 +11990,24 @@ class Environment {
11988
11990
  return value;
11989
11991
  }
11990
11992
 
11993
+ defineLive(name, getter, isConst = true) {
11994
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11995
+ if (this.consts.has(name)) {
11996
+ throw new Error(`Cannot redeclare const '${name}'`);
11997
+ }
11998
+ this.vars.delete(name);
11999
+ }
12000
+ this.liveBindings.set(name, getter);
12001
+ if (isConst) {
12002
+ this.consts.add(name);
12003
+ }
12004
+ return getter();
12005
+ }
12006
+
11991
12007
  get(name) {
12008
+ if (this.liveBindings.has(name)) {
12009
+ return this.liveBindings.get(name)();
12010
+ }
11992
12011
  if (this.vars.has(name)) {
11993
12012
  return this.vars.get(name);
11994
12013
  }
@@ -11999,11 +12018,12 @@ class Environment {
11999
12018
  }
12000
12019
 
12001
12020
  set(name, value) {
12002
- if (this.vars.has(name)) {
12021
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
12003
12022
  // Check if trying to reassign a const variable
12004
12023
  if (this.consts.has(name)) {
12005
12024
  throw new TypeError(`Cannot reassign const variable '${name}'`);
12006
12025
  }
12026
+ this.liveBindings.delete(name);
12007
12027
  this.vars.set(name, value);
12008
12028
  return value;
12009
12029
  }
@@ -12014,7 +12034,7 @@ class Environment {
12014
12034
  }
12015
12035
 
12016
12036
  has(name) {
12017
- return this.vars.has(name) || (this.parent ? this.parent.has(name) : false);
12037
+ return this.vars.has(name) || this.liveBindings.has(name) || (this.parent ? this.parent.has(name) : false);
12018
12038
  }
12019
12039
 
12020
12040
  // For let/const block scoping
@@ -12195,6 +12215,20 @@ function createMethodNotFoundError(objectName, methodName, objectValue) {
12195
12215
  });
12196
12216
  }
12197
12217
 
12218
+ const ASYNC_EXPRESSION_COMPLETION = Symbol('jslike.asyncExpressionCompletion');
12219
+
12220
+ function createAsyncExpressionCompletion(value) {
12221
+ return { [ASYNC_EXPRESSION_COMPLETION]: true, value };
12222
+ }
12223
+
12224
+ function isAsyncExpressionCompletion(value) {
12225
+ return value && value[ASYNC_EXPRESSION_COMPLETION] === true;
12226
+ }
12227
+
12228
+ function unwrapAsyncExpressionCompletion(value) {
12229
+ return isAsyncExpressionCompletion(value) ? value.value : value;
12230
+ }
12231
+
12198
12232
  function isTypeScriptPath$1(sourcePath) {
12199
12233
  return typeof sourcePath === 'string' && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
12200
12234
  }
@@ -12591,6 +12625,45 @@ class Interpreter {
12591
12625
  return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
12592
12626
  }
12593
12627
 
12628
+ if (node.type === 'AssignmentExpression') {
12629
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
12630
+
12631
+ if (node.left.type === 'Identifier') {
12632
+ const name = node.left.name;
12633
+ if (node.operator === '=') {
12634
+ if (env.has(name)) {
12635
+ env.set(name, value);
12636
+ } else {
12637
+ env.define(name, value);
12638
+ }
12639
+ return { value };
12640
+ }
12641
+
12642
+ const current = env.get(name);
12643
+ const newValue = this.applyCompoundAssignment(node.operator, current, value);
12644
+ env.set(name, newValue);
12645
+ return { value: newValue };
12646
+ }
12647
+
12648
+ if (node.left.type === 'MemberExpression') {
12649
+ const obj = await this.evaluateAsync(node.left.object, env);
12650
+ const prop = node.left.computed
12651
+ ? await this.evaluateAsync(node.left.property, env)
12652
+ : node.left.property.name;
12653
+
12654
+ if (node.operator === '=') {
12655
+ obj[prop] = value;
12656
+ return { value };
12657
+ }
12658
+
12659
+ const newValue = this.applyCompoundAssignment(node.operator, obj[prop], value);
12660
+ obj[prop] = newValue;
12661
+ return { value: newValue };
12662
+ }
12663
+
12664
+ throw new Error('Invalid assignment target');
12665
+ }
12666
+
12594
12667
  if (node.type === 'NewExpression') {
12595
12668
  return { value: this.evaluateNewExpression(node, env) };
12596
12669
  }
@@ -12630,7 +12703,7 @@ class Interpreter {
12630
12703
 
12631
12704
  const rawArgs = [];
12632
12705
  for (const arg of node.arguments) {
12633
- rawArgs.push(await this.evaluateAsync(arg, env));
12706
+ rawArgs.push((await this.evaluateAsyncRawValue(arg, env)).value);
12634
12707
  }
12635
12708
  const args = this.flattenSpreadArgs(rawArgs);
12636
12709
 
@@ -12706,7 +12779,7 @@ class Interpreter {
12706
12779
 
12707
12780
  // For expression statements, evaluate the expression async
12708
12781
  if (node.type === 'ExpressionStatement') {
12709
- return await this.evaluateAsync(node.expression, env);
12782
+ return createAsyncExpressionCompletion((await this.evaluateAsyncRawValue(node.expression, env)).value);
12710
12783
  }
12711
12784
 
12712
12785
  // For variable declarations with await in init
@@ -12741,7 +12814,7 @@ class Interpreter {
12741
12814
  return result;
12742
12815
  }
12743
12816
  }
12744
- return result;
12817
+ return unwrapAsyncExpressionCompletion(result);
12745
12818
  } finally {
12746
12819
  this.runtimeIdentifierReferences = previousReferences;
12747
12820
  }
@@ -13219,7 +13292,7 @@ class Interpreter {
13219
13292
  throw new TypeError('Spread syntax requires an iterable');
13220
13293
  }
13221
13294
  } else {
13222
- result.push(await this.evaluateAsync(elem, env));
13295
+ result.push((await this.evaluateAsyncRawValue(elem, env)).value);
13223
13296
  }
13224
13297
  }
13225
13298
  return result;
@@ -13238,7 +13311,7 @@ class Interpreter {
13238
13311
  const key = prop.key.type === 'Identifier' && !prop.computed
13239
13312
  ? prop.key.name
13240
13313
  : await this.evaluateAsync(prop.key, env);
13241
- const value = prop.value ? await this.evaluateAsync(prop.value, env) : env.get(key);
13314
+ const value = prop.value ? (await this.evaluateAsyncRawValue(prop.value, env)).value : env.get(key);
13242
13315
  if (prop.method && prop.value.type === 'FunctionExpression') {
13243
13316
  obj[key] = (...args) => {
13244
13317
  const funcValue = this.evaluate(prop.value, env);
@@ -14594,7 +14667,7 @@ class Interpreter {
14594
14667
  throw new Error(`Module '${modulePath}' has no export '${importedName}'`);
14595
14668
  }
14596
14669
 
14597
- env.define(localName, moduleExports[importedName]);
14670
+ env.defineLive(localName, () => moduleExports[importedName]);
14598
14671
  } else if (specifier.type === 'ImportDefaultSpecifier') {
14599
14672
  // Default import: import foo from "module"
14600
14673
  const localName = specifier.local.name;
@@ -14603,7 +14676,7 @@ class Interpreter {
14603
14676
  throw new Error(`Module '${modulePath}' has no default export`);
14604
14677
  }
14605
14678
 
14606
- env.define(localName, moduleExports.default);
14679
+ env.defineLive(localName, () => moduleExports.default);
14607
14680
  } else if (specifier.type === 'ImportNamespaceSpecifier') {
14608
14681
  // Namespace import: import * as foo from "module"
14609
14682
  const localName = specifier.local.name;
package/dist/index.d.ts CHANGED
@@ -11964,17 +11964,19 @@ class Environment {
11964
11964
  constructor(parent = null) {
11965
11965
  this.parent = parent;
11966
11966
  this.vars = new Map();
11967
+ this.liveBindings = new Map();
11967
11968
  this.consts = new Set(); // Track const variables
11968
11969
  }
11969
11970
 
11970
11971
  define(name, value, isConst = false) {
11971
- if (this.vars.has(name)) {
11972
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11972
11973
  // Allow redeclaration for non-const (REPL-style behavior)
11973
11974
  // But cannot redeclare a const
11974
11975
  if (this.consts.has(name)) {
11975
11976
  throw new Error(`Cannot redeclare const '${name}'`);
11976
11977
  }
11977
11978
  // Update existing variable
11979
+ this.liveBindings.delete(name);
11978
11980
  this.vars.set(name, value);
11979
11981
  if (isConst) {
11980
11982
  this.consts.add(name);
@@ -11988,7 +11990,24 @@ class Environment {
11988
11990
  return value;
11989
11991
  }
11990
11992
 
11993
+ defineLive(name, getter, isConst = true) {
11994
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11995
+ if (this.consts.has(name)) {
11996
+ throw new Error(`Cannot redeclare const '${name}'`);
11997
+ }
11998
+ this.vars.delete(name);
11999
+ }
12000
+ this.liveBindings.set(name, getter);
12001
+ if (isConst) {
12002
+ this.consts.add(name);
12003
+ }
12004
+ return getter();
12005
+ }
12006
+
11991
12007
  get(name) {
12008
+ if (this.liveBindings.has(name)) {
12009
+ return this.liveBindings.get(name)();
12010
+ }
11992
12011
  if (this.vars.has(name)) {
11993
12012
  return this.vars.get(name);
11994
12013
  }
@@ -11999,11 +12018,12 @@ class Environment {
11999
12018
  }
12000
12019
 
12001
12020
  set(name, value) {
12002
- if (this.vars.has(name)) {
12021
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
12003
12022
  // Check if trying to reassign a const variable
12004
12023
  if (this.consts.has(name)) {
12005
12024
  throw new TypeError(`Cannot reassign const variable '${name}'`);
12006
12025
  }
12026
+ this.liveBindings.delete(name);
12007
12027
  this.vars.set(name, value);
12008
12028
  return value;
12009
12029
  }
@@ -12014,7 +12034,7 @@ class Environment {
12014
12034
  }
12015
12035
 
12016
12036
  has(name) {
12017
- return this.vars.has(name) || (this.parent ? this.parent.has(name) : false);
12037
+ return this.vars.has(name) || this.liveBindings.has(name) || (this.parent ? this.parent.has(name) : false);
12018
12038
  }
12019
12039
 
12020
12040
  // For let/const block scoping
@@ -12195,6 +12215,20 @@ function createMethodNotFoundError(objectName, methodName, objectValue) {
12195
12215
  });
12196
12216
  }
12197
12217
 
12218
+ const ASYNC_EXPRESSION_COMPLETION = Symbol('jslike.asyncExpressionCompletion');
12219
+
12220
+ function createAsyncExpressionCompletion(value) {
12221
+ return { [ASYNC_EXPRESSION_COMPLETION]: true, value };
12222
+ }
12223
+
12224
+ function isAsyncExpressionCompletion(value) {
12225
+ return value && value[ASYNC_EXPRESSION_COMPLETION] === true;
12226
+ }
12227
+
12228
+ function unwrapAsyncExpressionCompletion(value) {
12229
+ return isAsyncExpressionCompletion(value) ? value.value : value;
12230
+ }
12231
+
12198
12232
  function isTypeScriptPath$1(sourcePath) {
12199
12233
  return typeof sourcePath === 'string' && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
12200
12234
  }
@@ -12591,6 +12625,45 @@ class Interpreter {
12591
12625
  return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
12592
12626
  }
12593
12627
 
12628
+ if (node.type === 'AssignmentExpression') {
12629
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
12630
+
12631
+ if (node.left.type === 'Identifier') {
12632
+ const name = node.left.name;
12633
+ if (node.operator === '=') {
12634
+ if (env.has(name)) {
12635
+ env.set(name, value);
12636
+ } else {
12637
+ env.define(name, value);
12638
+ }
12639
+ return { value };
12640
+ }
12641
+
12642
+ const current = env.get(name);
12643
+ const newValue = this.applyCompoundAssignment(node.operator, current, value);
12644
+ env.set(name, newValue);
12645
+ return { value: newValue };
12646
+ }
12647
+
12648
+ if (node.left.type === 'MemberExpression') {
12649
+ const obj = await this.evaluateAsync(node.left.object, env);
12650
+ const prop = node.left.computed
12651
+ ? await this.evaluateAsync(node.left.property, env)
12652
+ : node.left.property.name;
12653
+
12654
+ if (node.operator === '=') {
12655
+ obj[prop] = value;
12656
+ return { value };
12657
+ }
12658
+
12659
+ const newValue = this.applyCompoundAssignment(node.operator, obj[prop], value);
12660
+ obj[prop] = newValue;
12661
+ return { value: newValue };
12662
+ }
12663
+
12664
+ throw new Error('Invalid assignment target');
12665
+ }
12666
+
12594
12667
  if (node.type === 'NewExpression') {
12595
12668
  return { value: this.evaluateNewExpression(node, env) };
12596
12669
  }
@@ -12630,7 +12703,7 @@ class Interpreter {
12630
12703
 
12631
12704
  const rawArgs = [];
12632
12705
  for (const arg of node.arguments) {
12633
- rawArgs.push(await this.evaluateAsync(arg, env));
12706
+ rawArgs.push((await this.evaluateAsyncRawValue(arg, env)).value);
12634
12707
  }
12635
12708
  const args = this.flattenSpreadArgs(rawArgs);
12636
12709
 
@@ -12706,7 +12779,7 @@ class Interpreter {
12706
12779
 
12707
12780
  // For expression statements, evaluate the expression async
12708
12781
  if (node.type === 'ExpressionStatement') {
12709
- return await this.evaluateAsync(node.expression, env);
12782
+ return createAsyncExpressionCompletion((await this.evaluateAsyncRawValue(node.expression, env)).value);
12710
12783
  }
12711
12784
 
12712
12785
  // For variable declarations with await in init
@@ -12741,7 +12814,7 @@ class Interpreter {
12741
12814
  return result;
12742
12815
  }
12743
12816
  }
12744
- return result;
12817
+ return unwrapAsyncExpressionCompletion(result);
12745
12818
  } finally {
12746
12819
  this.runtimeIdentifierReferences = previousReferences;
12747
12820
  }
@@ -13219,7 +13292,7 @@ class Interpreter {
13219
13292
  throw new TypeError('Spread syntax requires an iterable');
13220
13293
  }
13221
13294
  } else {
13222
- result.push(await this.evaluateAsync(elem, env));
13295
+ result.push((await this.evaluateAsyncRawValue(elem, env)).value);
13223
13296
  }
13224
13297
  }
13225
13298
  return result;
@@ -13238,7 +13311,7 @@ class Interpreter {
13238
13311
  const key = prop.key.type === 'Identifier' && !prop.computed
13239
13312
  ? prop.key.name
13240
13313
  : await this.evaluateAsync(prop.key, env);
13241
- const value = prop.value ? await this.evaluateAsync(prop.value, env) : env.get(key);
13314
+ const value = prop.value ? (await this.evaluateAsyncRawValue(prop.value, env)).value : env.get(key);
13242
13315
  if (prop.method && prop.value.type === 'FunctionExpression') {
13243
13316
  obj[key] = (...args) => {
13244
13317
  const funcValue = this.evaluate(prop.value, env);
@@ -14594,7 +14667,7 @@ class Interpreter {
14594
14667
  throw new Error(`Module '${modulePath}' has no export '${importedName}'`);
14595
14668
  }
14596
14669
 
14597
- env.define(localName, moduleExports[importedName]);
14670
+ env.defineLive(localName, () => moduleExports[importedName]);
14598
14671
  } else if (specifier.type === 'ImportDefaultSpecifier') {
14599
14672
  // Default import: import foo from "module"
14600
14673
  const localName = specifier.local.name;
@@ -14603,7 +14676,7 @@ class Interpreter {
14603
14676
  throw new Error(`Module '${modulePath}' has no default export`);
14604
14677
  }
14605
14678
 
14606
- env.define(localName, moduleExports.default);
14679
+ env.defineLive(localName, () => moduleExports.default);
14607
14680
  } else if (specifier.type === 'ImportNamespaceSpecifier') {
14608
14681
  // Namespace import: import * as foo from "module"
14609
14682
  const localName = specifier.local.name;
package/dist/index.js CHANGED
@@ -11286,13 +11286,15 @@ var Environment = class _Environment {
11286
11286
  constructor(parent = null) {
11287
11287
  this.parent = parent;
11288
11288
  this.vars = /* @__PURE__ */ new Map();
11289
+ this.liveBindings = /* @__PURE__ */ new Map();
11289
11290
  this.consts = /* @__PURE__ */ new Set();
11290
11291
  }
11291
11292
  define(name, value, isConst = false) {
11292
- if (this.vars.has(name)) {
11293
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11293
11294
  if (this.consts.has(name)) {
11294
11295
  throw new Error(`Cannot redeclare const '${name}'`);
11295
11296
  }
11297
+ this.liveBindings.delete(name);
11296
11298
  this.vars.set(name, value);
11297
11299
  if (isConst) {
11298
11300
  this.consts.add(name);
@@ -11305,7 +11307,23 @@ var Environment = class _Environment {
11305
11307
  }
11306
11308
  return value;
11307
11309
  }
11310
+ defineLive(name, getter, isConst = true) {
11311
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11312
+ if (this.consts.has(name)) {
11313
+ throw new Error(`Cannot redeclare const '${name}'`);
11314
+ }
11315
+ this.vars.delete(name);
11316
+ }
11317
+ this.liveBindings.set(name, getter);
11318
+ if (isConst) {
11319
+ this.consts.add(name);
11320
+ }
11321
+ return getter();
11322
+ }
11308
11323
  get(name) {
11324
+ if (this.liveBindings.has(name)) {
11325
+ return this.liveBindings.get(name)();
11326
+ }
11309
11327
  if (this.vars.has(name)) {
11310
11328
  return this.vars.get(name);
11311
11329
  }
@@ -11315,10 +11333,11 @@ var Environment = class _Environment {
11315
11333
  throw new ReferenceError(`Variable "${name}" is not defined`);
11316
11334
  }
11317
11335
  set(name, value) {
11318
- if (this.vars.has(name)) {
11336
+ if (this.vars.has(name) || this.liveBindings.has(name)) {
11319
11337
  if (this.consts.has(name)) {
11320
11338
  throw new TypeError(`Cannot reassign const variable '${name}'`);
11321
11339
  }
11340
+ this.liveBindings.delete(name);
11322
11341
  this.vars.set(name, value);
11323
11342
  return value;
11324
11343
  }
@@ -11328,7 +11347,7 @@ var Environment = class _Environment {
11328
11347
  throw new ReferenceError(`Variable "${name}" is not defined`);
11329
11348
  }
11330
11349
  has(name) {
11331
- return this.vars.has(name) || (this.parent ? this.parent.has(name) : false);
11350
+ return this.vars.has(name) || this.liveBindings.has(name) || (this.parent ? this.parent.has(name) : false);
11332
11351
  }
11333
11352
  // For let/const block scoping
11334
11353
  extend() {
@@ -11469,6 +11488,16 @@ function createMethodNotFoundError(objectName, methodName, objectValue) {
11469
11488
  }
11470
11489
 
11471
11490
  // src/interpreter/interpreter.js
11491
+ var ASYNC_EXPRESSION_COMPLETION = Symbol("jslike.asyncExpressionCompletion");
11492
+ function createAsyncExpressionCompletion(value) {
11493
+ return { [ASYNC_EXPRESSION_COMPLETION]: true, value };
11494
+ }
11495
+ function isAsyncExpressionCompletion(value) {
11496
+ return value && value[ASYNC_EXPRESSION_COMPLETION] === true;
11497
+ }
11498
+ function unwrapAsyncExpressionCompletion(value) {
11499
+ return isAsyncExpressionCompletion(value) ? value.value : value;
11500
+ }
11472
11501
  function isTypeScriptPath(sourcePath) {
11473
11502
  return typeof sourcePath === "string" && /\.(ts|tsx|mts|cts)$/i.test(sourcePath);
11474
11503
  }
@@ -11809,6 +11838,36 @@ var Interpreter = class _Interpreter {
11809
11838
  }
11810
11839
  return await this.evaluateAsyncRawValue(node.expressions[node.expressions.length - 1], env);
11811
11840
  }
11841
+ if (node.type === "AssignmentExpression") {
11842
+ const value = (await this.evaluateAsyncRawValue(node.right, env)).value;
11843
+ if (node.left.type === "Identifier") {
11844
+ const name = node.left.name;
11845
+ if (node.operator === "=") {
11846
+ if (env.has(name)) {
11847
+ env.set(name, value);
11848
+ } else {
11849
+ env.define(name, value);
11850
+ }
11851
+ return { value };
11852
+ }
11853
+ const current2 = env.get(name);
11854
+ const newValue = this.applyCompoundAssignment(node.operator, current2, value);
11855
+ env.set(name, newValue);
11856
+ return { value: newValue };
11857
+ }
11858
+ if (node.left.type === "MemberExpression") {
11859
+ const obj = await this.evaluateAsync(node.left.object, env);
11860
+ const prop = node.left.computed ? await this.evaluateAsync(node.left.property, env) : node.left.property.name;
11861
+ if (node.operator === "=") {
11862
+ obj[prop] = value;
11863
+ return { value };
11864
+ }
11865
+ const newValue = this.applyCompoundAssignment(node.operator, obj[prop], value);
11866
+ obj[prop] = newValue;
11867
+ return { value: newValue };
11868
+ }
11869
+ throw new Error("Invalid assignment target");
11870
+ }
11812
11871
  if (node.type === "NewExpression") {
11813
11872
  return { value: this.evaluateNewExpression(node, env) };
11814
11873
  }
@@ -11839,7 +11898,7 @@ var Interpreter = class _Interpreter {
11839
11898
  }
11840
11899
  const rawArgs = [];
11841
11900
  for (const arg of node.arguments) {
11842
- rawArgs.push(await this.evaluateAsync(arg, env));
11901
+ rawArgs.push((await this.evaluateAsyncRawValue(arg, env)).value);
11843
11902
  }
11844
11903
  const args = this.flattenSpreadArgs(rawArgs);
11845
11904
  if (typeof callee === "function") {
@@ -11893,7 +11952,7 @@ var Interpreter = class _Interpreter {
11893
11952
  return result;
11894
11953
  }
11895
11954
  if (node.type === "ExpressionStatement") {
11896
- return await this.evaluateAsync(node.expression, env);
11955
+ return createAsyncExpressionCompletion((await this.evaluateAsyncRawValue(node.expression, env)).value);
11897
11956
  }
11898
11957
  if (node.type === "VariableDeclaration") {
11899
11958
  for (const declarator of node.declarations) {
@@ -11920,7 +11979,7 @@ var Interpreter = class _Interpreter {
11920
11979
  return result;
11921
11980
  }
11922
11981
  }
11923
- return result;
11982
+ return unwrapAsyncExpressionCompletion(result);
11924
11983
  } finally {
11925
11984
  this.runtimeIdentifierReferences = previousReferences;
11926
11985
  }
@@ -12307,7 +12366,7 @@ var Interpreter = class _Interpreter {
12307
12366
  throw new TypeError("Spread syntax requires an iterable");
12308
12367
  }
12309
12368
  } else {
12310
- result.push(await this.evaluateAsync(elem, env));
12369
+ result.push((await this.evaluateAsyncRawValue(elem, env)).value);
12311
12370
  }
12312
12371
  }
12313
12372
  return result;
@@ -12322,7 +12381,7 @@ var Interpreter = class _Interpreter {
12322
12381
  }
12323
12382
  } else {
12324
12383
  const key = prop.key.type === "Identifier" && !prop.computed ? prop.key.name : await this.evaluateAsync(prop.key, env);
12325
- const value = prop.value ? await this.evaluateAsync(prop.value, env) : env.get(key);
12384
+ const value = prop.value ? (await this.evaluateAsyncRawValue(prop.value, env)).value : env.get(key);
12326
12385
  if (prop.method && prop.value.type === "FunctionExpression") {
12327
12386
  obj[key] = (...args) => {
12328
12387
  const funcValue = this.evaluate(prop.value, env);
@@ -13356,13 +13415,13 @@ var Interpreter = class _Interpreter {
13356
13415
  if (!(importedName in moduleExports)) {
13357
13416
  throw new Error(`Module '${modulePath}' has no export '${importedName}'`);
13358
13417
  }
13359
- env.define(localName, moduleExports[importedName]);
13418
+ env.defineLive(localName, () => moduleExports[importedName]);
13360
13419
  } else if (specifier.type === "ImportDefaultSpecifier") {
13361
13420
  const localName = specifier.local.name;
13362
13421
  if (!("default" in moduleExports)) {
13363
13422
  throw new Error(`Module '${modulePath}' has no default export`);
13364
13423
  }
13365
- env.define(localName, moduleExports.default);
13424
+ env.defineLive(localName, () => moduleExports.default);
13366
13425
  } else if (specifier.type === "ImportNamespaceSpecifier") {
13367
13426
  const localName = specifier.local.name;
13368
13427
  env.define(localName, moduleExports);
@@ -11306,6 +11306,9 @@ function tsxParse(input, options) {
11306
11306
  return TSXParser.parse(input, options);
11307
11307
  }
11308
11308
 
11309
+ // src/interpreter/interpreter.js
11310
+ var ASYNC_EXPRESSION_COMPLETION = Symbol("jslike.asyncExpressionCompletion");
11311
+
11309
11312
  // src/index.js
11310
11313
  function containsModuleSyntax(code) {
11311
11314
  if (/(^|[;{\n])\s*(import|export)\s+/m.test(code)) {
@@ -11281,6 +11281,9 @@ function tsxParse(input, options) {
11281
11281
  return TSXParser.parse(input, options);
11282
11282
  }
11283
11283
 
11284
+ // src/interpreter/interpreter.js
11285
+ var ASYNC_EXPRESSION_COMPLETION = Symbol("jslike.asyncExpressionCompletion");
11286
+
11284
11287
  // src/index.js
11285
11288
  function containsModuleSyntax(code) {
11286
11289
  if (/(^|[;{\n])\s*(import|export)\s+/m.test(code)) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "jslike",
3
- "version": "1.8.8",
3
+ "version": "1.8.10",
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",