@isolated-vm/experimental 0.0.8 → 0.0.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.
Files changed (192) hide show
  1. package/addon/CMakeLists.txt +1 -1
  2. package/addon/handle/local_of.cc +150 -0
  3. package/addon/handle/types.cc +8 -137
  4. package/addon/handle/value_of.cc +82 -27
  5. package/addon/resolve.js +2 -2
  6. package/addon/support/callback_info.cc +5 -5
  7. package/addon/support/callback_storage.cc +2 -2
  8. package/addon/support/free_function.cc +2 -2
  9. package/addon/support/initialize.cc +2 -2
  10. package/addon/transfer/accept.cc +84 -64
  11. package/addon/transfer/visit.cc +90 -47
  12. package/addon/value/array.cc +6 -6
  13. package/addon/value/array_buffer.cc +27 -18
  14. package/addon/value/function.cc +5 -5
  15. package/addon/value/function.h.cc +5 -5
  16. package/addon/value/object.cc +3 -3
  17. package/addon/value/primitive.cc +36 -36
  18. package/addon/value/prototype.cc +7 -7
  19. package/addon/value/record.cc +20 -20
  20. package/addon/value/value.cc +1 -1
  21. package/addon/value/vector.cc +9 -9
  22. package/backend/backend.cts +7 -0
  23. package/backend/backend.d.cts +87 -0
  24. package/backend/host.cts +41 -0
  25. package/backend/require.cts +17 -0
  26. package/dist/backend/backend.cjs +9 -0
  27. package/dist/backend/backend.cjs.map +1 -0
  28. package/dist/backend/backend.d.cts +2 -0
  29. package/dist/backend/backend.d.cts.map +1 -0
  30. package/dist/backend/host.cjs +41 -0
  31. package/dist/backend/host.cjs.map +1 -0
  32. package/dist/backend/host.d.cts +2 -0
  33. package/dist/backend/host.d.cts.map +1 -0
  34. package/dist/backend/require.cjs +19 -0
  35. package/dist/backend/require.cjs.map +1 -0
  36. package/dist/backend/require.d.cts +2 -0
  37. package/dist/backend/require.d.cts.map +1 -0
  38. package/dist/frontend/agent.d.ts +2 -1
  39. package/dist/frontend/agent.d.ts.map +1 -1
  40. package/dist/frontend/agent.js +1 -1
  41. package/dist/frontend/agent.js.map +1 -1
  42. package/dist/frontend/module.d.ts +2 -2
  43. package/dist/frontend/module.d.ts.map +1 -1
  44. package/dist/frontend/module.js +1 -1
  45. package/dist/frontend/module.js.map +1 -1
  46. package/dist/frontend/realm.d.ts +2 -2
  47. package/dist/frontend/realm.d.ts.map +1 -1
  48. package/dist/frontend/realm.js +2 -2
  49. package/dist/frontend/realm.js.map +1 -1
  50. package/dist/frontend/reference.d.ts +4 -4
  51. package/dist/frontend/reference.d.ts.map +1 -1
  52. package/dist/frontend/script.d.ts +1 -1
  53. package/dist/frontend/script.d.ts.map +1 -1
  54. package/dist/frontend/script.js +1 -1
  55. package/dist/frontend/script.js.map +1 -1
  56. package/dist/isolated-vm.d.ts +1 -1
  57. package/dist/isolated-vm.d.ts.map +1 -1
  58. package/dist/isolated-vm.js +1 -1
  59. package/dist/isolated-vm.js.map +1 -1
  60. package/dist/test/00.agent/00.prerequisites.d.ts +2 -0
  61. package/dist/test/00.agent/00.prerequisites.d.ts.map +1 -0
  62. package/dist/test/00.agent/00.prerequisites.js +25 -0
  63. package/dist/test/00.agent/00.prerequisites.js.map +1 -0
  64. package/dist/test/00.agent/10.clock.d.ts +2 -0
  65. package/dist/test/00.agent/10.clock.d.ts.map +1 -0
  66. package/dist/test/{00.datetime.js → 00.agent/10.clock.js} +8 -8
  67. package/dist/test/00.agent/10.clock.js.map +1 -0
  68. package/dist/test/00.agent/10.random.d.ts +2 -0
  69. package/dist/test/00.agent/10.random.d.ts.map +1 -0
  70. package/dist/test/{00.random.js → 00.agent/10.random.js} +4 -4
  71. package/dist/test/00.agent/10.random.js.map +1 -0
  72. package/dist/test/10.transfer/00.primitives.d.ts +2 -0
  73. package/dist/test/10.transfer/00.primitives.d.ts.map +1 -0
  74. package/dist/test/10.transfer/00.primitives.js +54 -0
  75. package/dist/test/10.transfer/00.primitives.js.map +1 -0
  76. package/dist/test/10.transfer/10.array_buffer.d.ts +2 -0
  77. package/dist/test/10.transfer/10.array_buffer.d.ts.map +1 -0
  78. package/dist/test/{20.array_buffer.js → 10.transfer/10.array_buffer.js} +90 -84
  79. package/dist/test/10.transfer/10.array_buffer.js.map +1 -0
  80. package/dist/test/10.transfer/50.interceptors.d.ts +2 -0
  81. package/dist/test/10.transfer/50.interceptors.d.ts.map +1 -0
  82. package/dist/test/10.transfer/50.interceptors.js +108 -0
  83. package/dist/test/10.transfer/50.interceptors.js.map +1 -0
  84. package/dist/test/10.transfer/90.regressions.d.ts +2 -0
  85. package/dist/test/10.transfer/90.regressions.d.ts.map +1 -0
  86. package/dist/test/10.transfer/90.regressions.js +72 -0
  87. package/dist/test/10.transfer/90.regressions.js.map +1 -0
  88. package/dist/test/20.intrinsics/00.script.d.ts +2 -0
  89. package/dist/test/20.intrinsics/00.script.d.ts.map +1 -0
  90. package/dist/test/{10.script.js → 20.intrinsics/00.script.js} +7 -7
  91. package/dist/test/20.intrinsics/00.script.js.map +1 -0
  92. package/dist/test/20.intrinsics/05.global.d.ts.map +1 -0
  93. package/dist/test/{05.global.js → 20.intrinsics/05.global.js} +5 -5
  94. package/dist/test/20.intrinsics/05.global.js.map +1 -0
  95. package/dist/test/20.intrinsics/10.reference.d.ts.map +1 -0
  96. package/dist/test/{10.reference.js → 20.intrinsics/10.reference.js} +15 -15
  97. package/dist/test/20.intrinsics/10.reference.js.map +1 -0
  98. package/dist/test/20.intrinsics/20.module.d.ts +2 -0
  99. package/dist/test/20.intrinsics/20.module.d.ts.map +1 -0
  100. package/dist/test/{10.module.js → 20.intrinsics/20.module.js} +18 -18
  101. package/dist/test/20.intrinsics/20.module.js.map +1 -0
  102. package/dist/test/50.features/50.timers.d.ts.map +1 -0
  103. package/dist/test/{50.timers.js → 50.features/50.timers.js} +8 -8
  104. package/dist/test/50.features/50.timers.js.map +1 -0
  105. package/dist/test/50.features/90.i18n.d.ts +2 -0
  106. package/dist/test/50.features/90.i18n.d.ts.map +1 -0
  107. package/dist/test/{99.i18n.js → 50.features/90.i18n.js} +6 -6
  108. package/dist/test/50.features/90.i18n.js.map +1 -0
  109. package/dist/test/90.isolation/00.dispose.d.ts +1 -1
  110. package/dist/test/90.isolation/00.dispose.d.ts.map +1 -1
  111. package/dist/test/90.isolation/00.dispose.js +23 -5
  112. package/dist/test/90.isolation/00.dispose.js.map +1 -1
  113. package/dist/test/90.isolation/10.memory.d.ts +2 -0
  114. package/dist/test/90.isolation/10.memory.d.ts.map +1 -0
  115. package/dist/test/90.isolation/10.memory.js +31 -0
  116. package/dist/test/90.isolation/10.memory.js.map +1 -0
  117. package/dist/test/fixtures.js +2 -3
  118. package/dist/test/fixtures.js.map +1 -1
  119. package/dist/test/glob.d.ts +2 -0
  120. package/dist/test/glob.d.ts.map +1 -0
  121. package/dist/test/glob.js +11 -0
  122. package/dist/test/glob.js.map +1 -0
  123. package/dist/tsconfig.tsbuildinfo +1 -1
  124. package/dist/utility/completion.d.ts +2 -1
  125. package/dist/utility/completion.d.ts.map +1 -1
  126. package/dist/utility/completion.js +4 -0
  127. package/dist/utility/completion.js.map +1 -1
  128. package/frontend/agent.ts +3 -2
  129. package/frontend/module.ts +2 -2
  130. package/frontend/realm.ts +2 -2
  131. package/frontend/reference.ts +4 -4
  132. package/frontend/script.ts +1 -1
  133. package/isolated-vm.ts +1 -1
  134. package/package.json +29 -17
  135. package/test/00.agent/00.prerequisites.ts +12 -0
  136. package/test/{00.datetime.ts → 00.agent/10.clock.ts} +7 -7
  137. package/test/{00.random.ts → 00.agent/10.random.ts} +4 -4
  138. package/test/10.transfer/00.primitives.ts +47 -0
  139. package/test/{20.array_buffer.ts → 10.transfer/10.array_buffer.ts} +49 -43
  140. package/test/10.transfer/50.interceptors.ts +63 -0
  141. package/test/10.transfer/90.regressions.ts +38 -0
  142. package/test/{10.script.ts → 20.intrinsics/00.script.ts} +6 -6
  143. package/test/{05.global.ts → 20.intrinsics/05.global.ts} +5 -5
  144. package/test/{10.reference.ts → 20.intrinsics/10.reference.ts} +18 -17
  145. package/test/{10.module.ts → 20.intrinsics/20.module.ts} +17 -17
  146. package/test/{50.timers.ts → 50.features/50.timers.ts} +8 -8
  147. package/test/{99.i18n.ts → 50.features/90.i18n.ts} +5 -5
  148. package/test/90.isolation/00.dispose.ts +12 -5
  149. package/test/90.isolation/10.memory.ts +19 -0
  150. package/test/fixtures.ts +5 -5
  151. package/test/glob.ts +11 -0
  152. package/utility/completion.ts +6 -1
  153. package/addon/handle/bound_value.cc +0 -45
  154. package/backend/backend_v8.d.ts +0 -89
  155. package/backend/backend_v8.js +0 -18
  156. package/backend/specifier.ts +0 -20
  157. package/dist/backend/specifier.d.ts +0 -3
  158. package/dist/backend/specifier.d.ts.map +0 -1
  159. package/dist/backend/specifier.js +0 -21
  160. package/dist/backend/specifier.js.map +0 -1
  161. package/dist/test/00.datetime.d.ts +0 -2
  162. package/dist/test/00.datetime.d.ts.map +0 -1
  163. package/dist/test/00.datetime.js.map +0 -1
  164. package/dist/test/00.random.d.ts +0 -2
  165. package/dist/test/00.random.d.ts.map +0 -1
  166. package/dist/test/00.random.js.map +0 -1
  167. package/dist/test/00.transfer.d.ts +0 -2
  168. package/dist/test/00.transfer.d.ts.map +0 -1
  169. package/dist/test/00.transfer.js +0 -166
  170. package/dist/test/00.transfer.js.map +0 -1
  171. package/dist/test/05.global.d.ts.map +0 -1
  172. package/dist/test/05.global.js.map +0 -1
  173. package/dist/test/10.module.d.ts +0 -2
  174. package/dist/test/10.module.d.ts.map +0 -1
  175. package/dist/test/10.module.js.map +0 -1
  176. package/dist/test/10.reference.d.ts.map +0 -1
  177. package/dist/test/10.reference.js.map +0 -1
  178. package/dist/test/10.script.d.ts +0 -2
  179. package/dist/test/10.script.d.ts.map +0 -1
  180. package/dist/test/10.script.js.map +0 -1
  181. package/dist/test/20.array_buffer.d.ts +0 -2
  182. package/dist/test/20.array_buffer.d.ts.map +0 -1
  183. package/dist/test/20.array_buffer.js.map +0 -1
  184. package/dist/test/50.timers.d.ts.map +0 -1
  185. package/dist/test/50.timers.js.map +0 -1
  186. package/dist/test/99.i18n.d.ts +0 -2
  187. package/dist/test/99.i18n.d.ts.map +0 -1
  188. package/dist/test/99.i18n.js.map +0 -1
  189. package/test/00.transfer.ts +0 -132
  190. /package/dist/test/{05.global.d.ts → 20.intrinsics/05.global.d.ts} +0 -0
  191. /package/dist/test/{10.reference.d.ts → 20.intrinsics/10.reference.d.ts} +0 -0
  192. /package/dist/test/{50.timers.d.ts → 50.features/50.timers.d.ts} +0 -0
@@ -1,10 +1,10 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { unsafeEvalAsString } from "./fixtures.js";
3
+ import { Agent } from "@isolated-vm/experimental";
4
+ import { unsafeEvalAsString } from "@isolated-vm/experimental/test/fixtures";
5
5
 
6
- const makeAgentRandom = async (randomSeed?: number) => {
7
- await using agent = await ivm.Agent.create({ randomSeed });
6
+ const makeAgentRandom = async (randomSeed?: number) => {
7
+ await using agent = await Agent.create({ randomSeed });
8
8
  return await unsafeEvalAsString(agent, () => Math.random());
9
9
  };
10
10
 
@@ -0,0 +1,47 @@
1
+ import * as assert from "node:assert/strict";
2
+ import { test } from "node:test";
3
+ import { Agent, Realm } from "@isolated-vm/experimental";
4
+ import { unsafeEvalAsStringInRealm } from "@isolated-vm/experimental/test/fixtures";
5
+
6
+ async function check(agent: Agent, realm: Realm | null, fn: () => unknown) {
7
+ const result = await unsafeEvalAsStringInRealm(agent, realm, fn);
8
+ assert.deepStrictEqual(result, fn());
9
+ }
10
+
11
+ await test("primitives", async () => {
12
+ await using agent = await Agent.create();
13
+ const realm = await agent.createRealm();
14
+
15
+ // null, undefined, bool
16
+ await check(agent, realm, () => null);
17
+ await check(agent, realm, () => undefined);
18
+ await check(agent, realm, () => true);
19
+ await check(agent, realm, () => false);
20
+
21
+ // boolean
22
+ await check(agent, realm, () => true);
23
+ await check(agent, realm, () => false);
24
+
25
+ // string
26
+ await check(agent, realm, () => "hello world");
27
+ await check(agent, realm, () => "\u{10ffff}");
28
+
29
+ // number
30
+ await check(agent, realm, () => 0);
31
+ await check(agent, realm, () => Number.MAX_SAFE_INTEGER);
32
+ await check(agent, realm, () => Number.MAX_SAFE_INTEGER + 1);
33
+ await check(agent, realm, () => Number.MIN_SAFE_INTEGER);
34
+ await check(agent, realm, () => Number.MIN_SAFE_INTEGER - 1);
35
+ await check(agent, realm, () => Math.PI);
36
+
37
+ // bigint
38
+ await check(agent, realm, () => 0n);
39
+ await check(agent, realm, () => 9_223_372_036_854_775_807n); // int64 max
40
+ await check(agent, realm, () => 9_223_372_036_854_775_808n); // int64 max + 1
41
+ await check(agent, realm, () => -9_223_372_036_854_775_808n); // int64 min
42
+ await check(agent, realm, () => -9_223_372_036_854_775_809n); // int64 min - 1
43
+ await check(agent, realm, () => 18_446_744_073_709_551_615n); // uint64 max
44
+ await check(agent, realm, () => 18_446_744_073_709_551_616n); // uint64 max + 1
45
+ await check(agent, realm, () => 502_360_950_888_298_027_355_518_043_327_124_471_675_959_709_617_316_205_938_938_264_006_428_765_255_489n); // 256 bit number
46
+ await check(agent, realm, () => -502_360_950_888_298_027_355_518_043_327_124_471_675_959_709_617_316_205_938_938_264_006_428_765_255_490n); // 256 bit negative
47
+ });
@@ -1,7 +1,7 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { describe, test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { injectAssert, unsafeEvalAsString, unsafeEvalAsStringInRealm } from "./fixtures.js";
3
+ import { Agent, expect } from "@isolated-vm/experimental";
4
+ import { injectAssert, unsafeEvalAsString, unsafeEvalAsStringInRealm } from "@isolated-vm/experimental/test/fixtures";
5
5
 
6
6
  const hostSupportsSharedArraySupport =
7
7
  // @ts-expect-error
@@ -9,7 +9,7 @@ const hostSupportsSharedArraySupport =
9
9
 
10
10
  await describe("array buffer", async () => {
11
11
  await describe("transfer out", async () => {
12
- await using agent = await ivm.Agent.create();
12
+ await using agent = await Agent.create();
13
13
  const ab = await unsafeEvalAsString(agent, () => {
14
14
  const uint8 = new Uint8Array([ 1, 2, 3 ]);
15
15
  return uint8.buffer;
@@ -20,7 +20,7 @@ await describe("array buffer", async () => {
20
20
 
21
21
  if (hostSupportsSharedArraySupport) {
22
22
  await test("transfer out same reference", async () => {
23
- await using agent = await ivm.Agent.create();
23
+ await using agent = await Agent.create();
24
24
  const ab = await unsafeEvalAsString(agent, () => {
25
25
  // nb: also tests zero-length buffer
26
26
  const ab = new ArrayBuffer(0);
@@ -30,38 +30,43 @@ await describe("array buffer", async () => {
30
30
  });
31
31
  }
32
32
 
33
- await test("transfer in", async () => {
34
- await using agent = await ivm.Agent.create();
35
- const realm = await agent.createRealm();
36
- await injectAssert(agent, realm);
37
- const global = await realm.acquireGlobalObject();
38
- await global.set("ab", new Uint8Array([ 1, 2, 3 ]).buffer);
39
- await unsafeEvalAsStringInRealm(agent, realm, () => {
40
- // @ts-expect-error
41
- const uint8 = new Uint8Array(ab);
42
- assert.deepStrictEqual([ ...uint8 ], [ 1, 2, 3 ]);
33
+ // These tests work individually in Deno but something about the test runner is choking when run
34
+ // in the suite.
35
+ if (process.versions.deno === undefined) {
36
+ await test("transfer in", async () => {
37
+ await using agent = await Agent.create();
38
+ const realm = expect(await agent.createRealm());
39
+ await injectAssert(agent, realm);
40
+ const global = await realm.acquireGlobalObject();
41
+ await global.set("ab", new Uint8Array([ 1, 2, 3 ]).buffer);
42
+ await unsafeEvalAsStringInRealm(agent, realm, () => {
43
+ // @ts-expect-error
44
+ const uint8 = new Uint8Array(ab);
45
+ assert.deepStrictEqual([ ...uint8 ], [ 1, 2, 3 ]);
46
+ });
47
+ await agent.disposeAsync();
43
48
  });
44
- });
45
49
 
46
- await test("transfer in same reference", async () => {
47
- await using agent = await ivm.Agent.create();
48
- const realm = await agent.createRealm();
49
- await injectAssert(agent, realm);
50
- const global = await realm.acquireGlobalObject();
51
- const ab = new ArrayBuffer(0);
52
- await global.set("abs", [ ab, ab ]);
53
- await unsafeEvalAsStringInRealm(agent, realm, () => {
50
+ await test("transfer in same reference", async () => {
51
+ await using agent = await Agent.create();
52
+ const realm = expect(await agent.createRealm());
53
+ await injectAssert(agent, realm);
54
+ const global = await realm.acquireGlobalObject();
55
+ const ab = new ArrayBuffer(0);
56
+ await global.set("abs", [ ab, ab ]);
57
+ await unsafeEvalAsStringInRealm(agent, realm, () => {
54
58
  // @ts-expect-error
55
59
  // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access
56
- assert.strictEqual(abs[0], abs[1]);
60
+ assert.strictEqual(abs[0], abs[1]);
61
+ });
57
62
  });
58
- });
63
+ }
59
64
  });
60
65
 
61
66
  await describe("shared array buffer", async () => {
62
67
  if (hostSupportsSharedArraySupport) {
63
68
  await describe("transfer out", async () => {
64
- await using agent = await ivm.Agent.create();
69
+ await using agent = await Agent.create();
65
70
  const realm = await agent.createRealm();
66
71
  const sab = await unsafeEvalAsStringInRealm(agent, realm, () => {
67
72
  const sab = new SharedArrayBuffer(3);
@@ -85,7 +90,7 @@ await describe("shared array buffer", async () => {
85
90
  });
86
91
 
87
92
  await test("transfer out same reference", async () => {
88
- await using agent = await ivm.Agent.create();
93
+ await using agent = await Agent.create();
89
94
  const ab = await unsafeEvalAsString(agent, () => {
90
95
  // nb: also tests zero-length buffer
91
96
  const sab = new SharedArrayBuffer(0);
@@ -95,8 +100,8 @@ await describe("shared array buffer", async () => {
95
100
  });
96
101
 
97
102
  await test("transfer in", async () => {
98
- await using agent = await ivm.Agent.create();
99
- const realm = await agent.createRealm();
103
+ await using agent = await Agent.create();
104
+ const realm = expect(await agent.createRealm());
100
105
  await injectAssert(agent, realm);
101
106
  const global = await realm.acquireGlobalObject();
102
107
  const sab = new SharedArrayBuffer(3);
@@ -113,8 +118,8 @@ await describe("shared array buffer", async () => {
113
118
  }
114
119
 
115
120
  await test("transfer in same reference", async () => {
116
- await using agent = await ivm.Agent.create();
117
- const realm = await agent.createRealm();
121
+ await using agent = await Agent.create();
122
+ const realm = expect(await agent.createRealm());
118
123
  await injectAssert(agent, realm);
119
124
  const global = await realm.acquireGlobalObject();
120
125
  const ab = new ArrayBuffer(0);
@@ -130,20 +135,21 @@ await describe("shared array buffer", async () => {
130
135
  });
131
136
  });
132
137
 
133
- await describe("typed array", async () => {
134
- await test("transfer out", async () => {
135
- await using agent = await ivm.Agent.create();
136
- const [ uint8, uint8_copy ] = await unsafeEvalAsString(agent, () => {
137
- const uint8 = new Uint8Array([ 1, 2, 3 ]);
138
- return [ uint8, new Uint8Array(uint8.buffer) ];
139
- });
140
- assert.deepStrictEqual(uint8, new Uint8Array([ 1, 2, 3 ]));
141
- assert.strictEqual(uint8.buffer, uint8_copy.buffer);
138
+ // TODO: deno fails when this is in the `describe` (??)
139
+ await test("transfer out", async () => {
140
+ await using agent = await Agent.create();
141
+ const [ uint8, uint8_copy ] = await unsafeEvalAsString(agent, () => {
142
+ const uint8 = new Uint8Array([ 1, 2, 3 ]);
143
+ return [ uint8, new Uint8Array(uint8.buffer) ];
142
144
  });
145
+ assert.deepStrictEqual(uint8, new Uint8Array([ 1, 2, 3 ]));
146
+ assert.strictEqual(uint8.buffer, uint8_copy.buffer);
147
+ });
143
148
 
149
+ await describe("typed array", async () => {
144
150
  await test("transfer in", async () => {
145
- await using agent = await ivm.Agent.create();
146
- const realm = await agent.createRealm();
151
+ await using agent = await Agent.create();
152
+ const realm = expect(await agent.createRealm());
147
153
  await injectAssert(agent, realm);
148
154
  const global = await realm.acquireGlobalObject();
149
155
  const uint8 = new Uint8Array([ 1, 2, 3 ]);
@@ -158,7 +164,7 @@ await describe("typed array", async () => {
158
164
 
159
165
  if (hostSupportsSharedArraySupport) {
160
166
  await test("shared transfer out", async () => {
161
- await using agent = await ivm.Agent.create();
167
+ await using agent = await Agent.create();
162
168
  const [ shared_uint8, shared_uint8_copy ] = await unsafeEvalAsString(agent, () => {
163
169
  const sab = new SharedArrayBuffer(3);
164
170
  const uint8 = new Uint8Array(sab);
@@ -0,0 +1,63 @@
1
+ import * as assert from "node:assert/strict";
2
+ import { describe, test } from "node:test";
3
+ import { Agent } from "@isolated-vm/experimental";
4
+ import { unsafeEvalAsStringInRealm } from "@isolated-vm/experimental/test/fixtures";
5
+
6
+ const supportsExpectedFailure =
7
+ // @ts-expect-error
8
+ process.isBun === undefined && process.versions.deno === undefined;
9
+
10
+ if (supportsExpectedFailure) {
11
+ // None of these work!
12
+ await test("named proxy", { expectFailure: "interceptor invoked" }, async () => {
13
+ await using agent = await Agent.create();
14
+ const realm = await agent.createRealm();
15
+ const result = await unsafeEvalAsStringInRealm(agent, realm, () => {
16
+ const proxy = new Proxy({ name: "value" }, {
17
+ get() { throw new Error("interceptor invoked"); },
18
+ });
19
+ return proxy;
20
+ });
21
+ assert.deepStrictEqual(result, { name: undefined });
22
+ });
23
+
24
+ await test("indexed proxy", { expectFailure: "interceptor invoked" }, async () => {
25
+ await using agent = await Agent.create();
26
+ const realm = await agent.createRealm();
27
+ const result = await unsafeEvalAsStringInRealm(agent, realm, () => {
28
+ const proxy = new Proxy([ 0, 1 ], {
29
+ get() { throw new Error("interceptor invoked"); },
30
+ });
31
+ return proxy;
32
+ });
33
+ assert.deepStrictEqual(result, [ undefined, undefined ]);
34
+ });
35
+
36
+ await describe("named getter", { expectFailure: "interceptor invoked" }, async () => {
37
+ await using agent = await Agent.create();
38
+ const realm = await agent.createRealm();
39
+ const result = await unsafeEvalAsStringInRealm(agent, realm, () => {
40
+ const object = { name: "value" };
41
+ Object.defineProperty(object, "name", {
42
+ enumerable: true,
43
+ get() { throw new Error("interceptor invoked"); },
44
+ });
45
+ return object;
46
+ });
47
+ assert.deepStrictEqual(result, { name: undefined });
48
+ });
49
+
50
+ await describe("indexed getter", { expectFailure: "interceptor invoked" }, async () => {
51
+ await using agent = await Agent.create();
52
+ const realm = await agent.createRealm();
53
+ const result = await unsafeEvalAsStringInRealm(agent, realm, () => {
54
+ const array = [ 0, 1 ];
55
+ Object.defineProperty(array, 0, {
56
+ enumerable: true,
57
+ get() { throw new Error("interceptor invoked"); },
58
+ });
59
+ return array;
60
+ });
61
+ assert.deepStrictEqual(result, [ undefined, 1 ]);
62
+ });
63
+ }
@@ -0,0 +1,38 @@
1
+ import { test } from "node:test";
2
+ import { Agent, expect } from "@isolated-vm/experimental";
3
+ import "@isolated-vm/experimental/test/fixtures";
4
+
5
+ const hostSupportsSharedArraySupport =
6
+ // @ts-expect-error
7
+ process.isBun === undefined && process.versions.deno === undefined;
8
+
9
+ // TODO: deno fails when this is in the `describe` (??)
10
+ await test("numeric references", async () => {
11
+ await using agent = await Agent.create();
12
+ const realm = expect(await agent.createRealm());
13
+ const global = await realm.acquireGlobalObject();
14
+ // doubles are stored as references in `value_t`, because they are bigger than 32-bit. there was
15
+ // a failure with more than one of them in the same transfer operation.
16
+ expect(await global.set("xx", { zero: 0.1, one: 0.2 }));
17
+ });
18
+
19
+ await test("numeric indices", async () => {
20
+ await using agent = await Agent.create();
21
+ const realm = expect(await agent.createRealm());
22
+ const global = await realm.acquireGlobalObject();
23
+ // numeric array indices broke as part of a double to int32_t change.
24
+ expect(await global.set("xx", [ false, true ]));
25
+ });
26
+
27
+ if (hostSupportsSharedArraySupport) {
28
+ await test("seen index type", async () => {
29
+ await using agent = await Agent.create();
30
+ const realm = expect(await agent.createRealm());
31
+ const global = await realm.acquireGlobalObject();
32
+ const payload = {
33
+ number: 0,
34
+ buffer: [ new Uint8Array(new SharedArrayBuffer(0)) ],
35
+ };
36
+ expect(await global.set("xx", [ payload ]));
37
+ });
38
+ }
@@ -1,10 +1,10 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { expectComplete, expectThrow, unsafeEvalAsStringInRealm, unsafeIIFEAsString } from "./fixtures.js";
3
+ import { Agent } from "@isolated-vm/experimental";
4
+ import { expectComplete, expectThrow, unsafeEvalAsStringInRealm, unsafeIIFEAsString } from "@isolated-vm/experimental/test/fixtures";
5
5
 
6
6
  await test("script source origin", async () => {
7
- await using agent = await ivm.Agent.create();
7
+ await using agent = await Agent.create();
8
8
  const script = expectComplete(await agent.compileScript(
9
9
  unsafeIIFEAsString(() => {
10
10
  try {
@@ -28,7 +28,7 @@ await test("script source origin", async () => {
28
28
  });
29
29
 
30
30
  await test("script which throws", async () => {
31
- await using agent = await ivm.Agent.create();
31
+ await using agent = await Agent.create();
32
32
  const realm = await agent.createRealm();
33
33
  const script = expectComplete(await agent.compileScript("throw new Error('wow');", { origin: { name: "test:script" } }));
34
34
  const error = expectThrow(await script.run(realm)) as Error;
@@ -37,7 +37,7 @@ await test("script which throws", async () => {
37
37
  });
38
38
 
39
39
  await test("script with syntax error", async () => {
40
- await using agent = await ivm.Agent.create();
40
+ await using agent = await Agent.create();
41
41
  const error = expectThrow(await agent.compileScript("}"));
42
42
  // @ts-expect-error
43
43
  const message: unknown = error.message;
@@ -46,7 +46,7 @@ await test("script with syntax error", async () => {
46
46
  });
47
47
 
48
48
  await test("script which returns a circular object", async () => {
49
- await using agent = await ivm.Agent.create();
49
+ await using agent = await Agent.create();
50
50
  const realm = await agent.createRealm();
51
51
  const result = await unsafeEvalAsStringInRealm(agent, realm, () => {
52
52
  const date = new Date();
@@ -1,17 +1,17 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { unsafeEvalAsStringInRealm } from "./fixtures.js";
3
+ import { Agent, expect } from "@isolated-vm/experimental";
4
+ import { unsafeEvalAsStringInRealm } from "@isolated-vm/experimental/test/fixtures";
5
5
 
6
6
  await test("realm global reference", async () => {
7
- await using agent = await ivm.Agent.create();
8
- const realm = await agent.createRealm();
7
+ await using agent = await Agent.create();
8
+ const realm = expect(await agent.createRealm());
9
9
  await unsafeEvalAsStringInRealm(agent, realm, () => {
10
10
  // @ts-expect-error
11
11
  globalThis.test = 123;
12
12
  });
13
13
  const global = await realm.acquireGlobalObject();
14
- const property = await global.get("test");
14
+ const property = expect(await global.get("test"));
15
15
  const value = await property.copy();
16
16
  assert.equal(value, 123);
17
17
  });
@@ -1,24 +1,25 @@
1
+ import type { Reference } from "@isolated-vm/experimental";
1
2
  import * as assert from "node:assert/strict";
2
3
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { expectComplete, unsafeEvalAsStringInRealm } from "./fixtures.js";
4
+ import { Agent, expect } from "@isolated-vm/experimental";
5
+ import { expectComplete, unsafeEvalAsStringInRealm } from "@isolated-vm/experimental/test/fixtures";
5
6
 
6
7
  await test("function reference invoke", async () => {
7
- await using agent = await ivm.Agent.create();
8
- const realm = await agent.createRealm();
8
+ await using agent = await Agent.create();
9
+ const realm = expect(await agent.createRealm());
9
10
  await unsafeEvalAsStringInRealm(agent, realm, () => {
10
11
  // @ts-expect-error
11
12
  globalThis.fn = () => "wow";
12
13
  });
13
14
  const global = await realm.acquireGlobalObject();
14
- const property = (await global.get("fn")) as ivm.Reference<() => unknown>;
15
+ const property = (await global.get("fn")) as Reference<() => unknown>;
15
16
  const value = expectComplete(await property.invoke([]));
16
17
  assert.equal(value, "wow");
17
18
  });
18
19
 
19
20
  await test("invoke function cross-param reference", async () => {
20
- await using agent = await ivm.Agent.create();
21
- const realm = await agent.createRealm();
21
+ await using agent = await Agent.create();
22
+ const realm = expect(await agent.createRealm());
22
23
  await unsafeEvalAsStringInRealm(agent, realm, () => {
23
24
  // @ts-expect-error
24
25
  globalThis.fn = (...values: unknown[]) => values;
@@ -32,14 +33,14 @@ await test("invoke function cross-param reference", async () => {
32
33
  });
33
34
 
34
35
  await test("invoke function reference with circular object", async () => {
35
- await using agent = await ivm.Agent.create();
36
- const realm = await agent.createRealm();
36
+ await using agent = await Agent.create();
37
+ const realm = expect(await agent.createRealm());
37
38
  await unsafeEvalAsStringInRealm(agent, realm, () => {
38
39
  // @ts-expect-error
39
40
  globalThis.fn = (value: unknown) => value;
40
41
  });
41
42
  const global = await realm.acquireGlobalObject();
42
- const fn = (await global.get("fn")) as ivm.Reference<(value: unknown) => unknown>;
43
+ const fn = (await global.get("fn")) as Reference<(value: unknown) => unknown>;
43
44
  const date = new Date();
44
45
  const object: Record<string, any> = {
45
46
  record: {},
@@ -55,8 +56,8 @@ await test("invoke function reference with circular object", async () => {
55
56
  });
56
57
 
57
58
  await test("get & set should not invoke proxies", async () => {
58
- await using agent = await ivm.Agent.create();
59
- const realm = await agent.createRealm();
59
+ await using agent = await Agent.create();
60
+ const realm = expect(await agent.createRealm());
60
61
  await unsafeEvalAsStringInRealm(agent, realm, () => {
61
62
  // @ts-expect-error
62
63
  globalThis.prox = new Proxy({}, {
@@ -67,16 +68,16 @@ await test("get & set should not invoke proxies", async () => {
67
68
  });
68
69
  });
69
70
  const global = await realm.acquireGlobalObject();
70
- const prox = await global.get("prox");
71
+ const prox = expect(await global.get("prox"));
71
72
  await prox.get("name");
72
- assert.equal(await (await global.get("failed")).copy(), undefined);
73
- await prox.set("name", undefined);
74
- assert.equal(await (await global.get("failed")).copy(), undefined);
73
+ assert.equal(await expect(await global.get("failed")).copy(), undefined);
74
+ expect(await prox.set("name", undefined));
75
+ assert.equal(await expect(await global.get("failed")).copy(), undefined);
75
76
 
76
77
  // sanity check
77
78
  await unsafeEvalAsStringInRealm(agent, realm, () => {
78
79
  // @ts-expect-error
79
80
  globalThis.failed = true;
80
81
  });
81
- assert.equal(await (await global.get("failed")).copy(), true);
82
+ assert.equal(await expect(await global.get("failed")).copy(), true);
82
83
  });
@@ -1,11 +1,11 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { makeNullLinker } from "../utility/linker.js";
5
- import { expectComplete, expectThrow } from "./fixtures.js";
3
+ import { Agent, expect } from "@isolated-vm/experimental";
4
+ import { expectComplete, expectThrow } from "@isolated-vm/experimental/test/fixtures";
5
+ import { makeNullLinker } from "@isolated-vm/experimental/utility/linker";
6
6
 
7
7
  await test("module linker", async () => {
8
- await using agent = await ivm.Agent.create();
8
+ await using agent = await Agent.create();
9
9
  const realm = await agent.createRealm();
10
10
  const left = expectComplete(await agent.compileModule('import { right } from "right"; globalThis.right = right;'));
11
11
  const right = expectComplete(await agent.compileModule('export function right() { return "hello"; }'));
@@ -20,18 +20,18 @@ await test("module linker", async () => {
20
20
  });
21
21
 
22
22
  await test("nested compilation in module linker", async () => {
23
- await using agent = await ivm.Agent.create();
23
+ await using agent = await Agent.create();
24
24
  const realm = await agent.createRealm();
25
25
  const left = expectComplete(await agent.compileModule('import "right";'));
26
26
  await left.link(realm, async () => expectComplete(await agent.compileModule("export {};")));
27
27
  });
28
28
 
29
29
  await test("synthetic module capability", async () => {
30
- await using agent = await ivm.Agent.create();
30
+ await using agent = await Agent.create();
31
31
  const capabilityName = "isolated-vm:///capability";
32
32
  let didInvoke = false;
33
- const realm = await agent.createRealm();
34
- const capability = await realm.createCapability(
33
+ const realm = expect(await agent.createRealm());
34
+ const capability = expect(await realm.createCapability(
35
35
  () => ({
36
36
  default: (value1: unknown, value2: unknown) => {
37
37
  didInvoke = true;
@@ -39,7 +39,7 @@ await test("synthetic module capability", async () => {
39
39
  assert.equal(value2, "world");
40
40
  },
41
41
  }),
42
- { origin: capabilityName });
42
+ { origin: capabilityName }));
43
43
  const left = expectComplete(await agent.compileModule(`
44
44
  import capability from ${JSON.stringify(capabilityName)};
45
45
  capability("hello", "world");
@@ -53,10 +53,10 @@ await test("synthetic module capability", async () => {
53
53
  });
54
54
 
55
55
  await test("synthetic module with circular reference", async () => {
56
- await using agent = await ivm.Agent.create();
56
+ await using agent = await Agent.create();
57
57
  const capabilityName = "isolated-vm:///capability";
58
- const realm = await agent.createRealm();
59
- const capability = await realm.createCapability(
58
+ const realm = expect(await agent.createRealm());
59
+ const capability = expect(await realm.createCapability(
60
60
  () => ({
61
61
  default: (value1: unknown) => {
62
62
  // @ts-expect-error
@@ -65,7 +65,7 @@ await test("synthetic module with circular reference", async () => {
65
65
  assert.strictEqual(value1.object, value1);
66
66
  },
67
67
  }),
68
- { origin: capabilityName });
68
+ { origin: capabilityName }));
69
69
  const left = expectComplete(await agent.compileModule(`
70
70
  import capability from ${JSON.stringify(capabilityName)};
71
71
  const date = new Date();
@@ -87,7 +87,7 @@ await test("synthetic module with circular reference", async () => {
87
87
  // TODO: This terminates the process. It should probably raise an async error, because there is no
88
88
  // promise.
89
89
  // await test("throw from synthetic module", async () => {
90
- // await using agent = await ivm.Agent.create();
90
+ // await using agent = await Agent.create();
91
91
  // const capabilityName = "isolated-vm:///capability";
92
92
  // const realm = await agent.createRealm();
93
93
  // const capability = await realm.createCapability(
@@ -109,7 +109,7 @@ await test("synthetic module with circular reference", async () => {
109
109
  // });
110
110
 
111
111
  await test("throw from linker", async () => {
112
- await using agent = await ivm.Agent.create();
112
+ await using agent = await Agent.create();
113
113
  const realm = await agent.createRealm();
114
114
  const left = expectComplete(await agent.compileModule('import "right";'));
115
115
  await assert.rejects(left.link(realm, () => {
@@ -118,7 +118,7 @@ await test("throw from linker", async () => {
118
118
  });
119
119
 
120
120
  await test("throw from evaluation", async () => {
121
- await using agent = await ivm.Agent.create();
121
+ await using agent = await Agent.create();
122
122
  const realm = await agent.createRealm();
123
123
  const module = expectComplete(await agent.compileModule('throw new Error("wow");', { origin: { name: "test:module" } }));
124
124
  await module.link(realm, makeNullLinker());
@@ -128,7 +128,7 @@ await test("throw from evaluation", async () => {
128
128
  });
129
129
 
130
130
  await test("missing imports", async () => {
131
- await using agent = await ivm.Agent.create();
131
+ await using agent = await Agent.create();
132
132
  const realm = await agent.createRealm();
133
133
  const left = expectComplete(await agent.compileModule('import { nothing } from "right";'));
134
134
  await assert.rejects(left.link(realm, async () =>
@@ -1,16 +1,16 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
3
+ import { Agent, expect } from "@isolated-vm/experimental";
4
+ import { expectComplete } from "@isolated-vm/experimental/test/fixtures";
4
5
  import { makeCompositeLinker, makeDirectResolver, makeFileSystemCompilationLoader, makeLinker, makeLocalResolver, makeStaticLoader } from "@isolated-vm/experimental/utility/linker";
5
- import { expectComplete } from "./fixtures.js";
6
6
 
7
7
  await test("setTimeout capability", async () => {
8
- await using agent = await ivm.Agent.create();
9
- const realm = await agent.createRealm();
8
+ await using agent = await Agent.create();
9
+ const realm = expect(await agent.createRealm());
10
10
  const runTimers = expectComplete(await agent.compileScript("runTimers()"));
11
11
  const resolvers = Promise.withResolvers();
12
12
  const capabilities = makeStaticLoader({
13
- "isolated-vm:capability/timers": await realm.createCapability(
13
+ "isolated-vm:capability/timers": expect(await realm.createCapability(
14
14
  () => ({
15
15
  default: (/*timeout*/) => {
16
16
  void async function() {
@@ -18,12 +18,12 @@ await test("setTimeout capability", async () => {
18
18
  }();
19
19
  },
20
20
  }),
21
- { origin: "isolated-vm:capability/timers" }),
22
- "notify-test": await realm.createCapability(
21
+ { origin: "isolated-vm:capability/timers" })),
22
+ "notify-test": expect(await realm.createCapability(
23
23
  () => ({
24
24
  default: (message: unknown) => { resolvers.resolve(message); },
25
25
  }),
26
- { origin: "notify-test" }),
26
+ { origin: "notify-test" })),
27
27
  });
28
28
 
29
29
  const runtime = makeFileSystemCompilationLoader(agent);
@@ -1,16 +1,16 @@
1
1
  import * as assert from "node:assert/strict";
2
2
  import { test } from "node:test";
3
- import * as ivm from "@isolated-vm/experimental";
4
- import { unsafeEvalAsString } from "./fixtures.js";
3
+ import { Agent } from "@isolated-vm/experimental";
4
+ import { unsafeEvalAsString } from "@isolated-vm/experimental/test/fixtures";
5
5
 
6
6
  await test("localCompare", async () => {
7
- await using agent = await ivm.Agent.create();
7
+ await using agent = await Agent.create();
8
8
  const result = await unsafeEvalAsString(agent, () => "a".localeCompare("b"));
9
9
  assert.equal(result, -1);
10
10
  });
11
11
 
12
12
  await test("i18n locales", async () => {
13
- await using agent = await ivm.Agent.create();
13
+ await using agent = await Agent.create();
14
14
  const supported = await unsafeEvalAsString(agent, () =>
15
15
  Intl.NumberFormat.supportedLocalesOf([ "ar-EG", "fa-IR", "zh-Hans", "hi-IN", "th-TH", "km-KH" ]));
16
16
  // no "km-KH"
@@ -18,7 +18,7 @@ await test("i18n locales", async () => {
18
18
  });
19
19
 
20
20
  await test("i18n format", async () => {
21
- await using agent = await ivm.Agent.create();
21
+ await using agent = await Agent.create();
22
22
  const german = await unsafeEvalAsString(agent, () => new Intl.NumberFormat("de-DE").format(1234567.89));
23
23
  assert.equal(german, "1.234.567,89");
24
24
  });