@secure-exec/core 0.2.1 → 0.3.0-rc.2

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 (248) hide show
  1. package/README.md +5 -5
  2. package/dist/binary.d.ts +4 -0
  3. package/dist/binary.js +25 -0
  4. package/dist/bytes.d.ts +2 -0
  5. package/dist/bytes.js +6 -0
  6. package/dist/callbacks.d.ts +41 -0
  7. package/dist/callbacks.js +94 -0
  8. package/dist/cargo.d.ts +2 -0
  9. package/dist/cargo.js +142 -0
  10. package/dist/correlation.d.ts +10 -0
  11. package/dist/correlation.js +49 -0
  12. package/dist/descriptors.d.ts +34 -0
  13. package/dist/descriptors.js +37 -0
  14. package/dist/event-buffer.d.ts +90 -0
  15. package/dist/event-buffer.js +313 -0
  16. package/dist/ext.d.ts +7 -0
  17. package/dist/ext.js +13 -0
  18. package/dist/filesystem.d.ts +41 -0
  19. package/dist/filesystem.js +70 -0
  20. package/dist/frame-payload-codec.d.ts +8 -0
  21. package/dist/frame-payload-codec.js +14 -0
  22. package/dist/frame-rpc.d.ts +38 -0
  23. package/dist/frame-rpc.js +73 -0
  24. package/dist/frame-stream.d.ts +27 -0
  25. package/dist/frame-stream.js +99 -0
  26. package/dist/framing.d.ts +7 -0
  27. package/dist/framing.js +22 -0
  28. package/dist/generated/AcpLimitsConfig.d.ts +4 -0
  29. package/dist/generated/AcpLimitsConfig.js +2 -0
  30. package/dist/generated/CreateVmConfig.d.ts +19 -0
  31. package/dist/generated/FsPermissionRule.d.ts +6 -0
  32. package/dist/generated/FsPermissionRuleSet.d.ts +6 -0
  33. package/dist/generated/FsPermissionRuleSet.js +1 -0
  34. package/dist/generated/FsPermissionScope.d.ts +3 -0
  35. package/dist/generated/FsPermissionScope.js +1 -0
  36. package/dist/generated/HttpLimitsConfig.d.ts +3 -0
  37. package/dist/generated/HttpLimitsConfig.js +2 -0
  38. package/dist/generated/JsModuleResolution.d.ts +1 -0
  39. package/dist/generated/JsModuleResolution.js +2 -0
  40. package/dist/generated/JsRuntimeConfig.d.ts +26 -0
  41. package/dist/generated/JsRuntimeConfig.js +1 -0
  42. package/dist/generated/JsRuntimeLimitsConfig.d.ts +7 -0
  43. package/dist/generated/JsRuntimeLimitsConfig.js +2 -0
  44. package/dist/generated/JsRuntimePlatform.d.ts +1 -0
  45. package/dist/generated/JsRuntimePlatform.js +2 -0
  46. package/dist/generated/MountPluginDescriptor.d.ts +4 -0
  47. package/dist/generated/MountPluginDescriptor.js +2 -0
  48. package/dist/generated/NativeRootFilesystemConfig.d.ts +5 -0
  49. package/dist/generated/NativeRootFilesystemConfig.js +1 -0
  50. package/dist/generated/PatternPermissionRule.d.ts +6 -0
  51. package/dist/generated/PatternPermissionRule.js +1 -0
  52. package/dist/generated/PatternPermissionRuleSet.d.ts +6 -0
  53. package/dist/generated/PatternPermissionRuleSet.js +1 -0
  54. package/dist/generated/PatternPermissionScope.d.ts +3 -0
  55. package/dist/generated/PatternPermissionScope.js +1 -0
  56. package/dist/generated/PermissionMode.d.ts +1 -0
  57. package/dist/generated/PermissionMode.js +2 -0
  58. package/dist/generated/PermissionsPolicy.d.ts +10 -0
  59. package/dist/generated/PermissionsPolicy.js +1 -0
  60. package/dist/generated/PluginLimitsConfig.d.ts +4 -0
  61. package/dist/generated/PluginLimitsConfig.js +2 -0
  62. package/dist/generated/PythonLimitsConfig.d.ts +5 -0
  63. package/dist/generated/PythonLimitsConfig.js +2 -0
  64. package/dist/generated/ResourceLimitsConfig.d.ts +22 -0
  65. package/dist/generated/ResourceLimitsConfig.js +2 -0
  66. package/dist/generated/RootFilesystemConfig.d.ts +9 -0
  67. package/dist/generated/RootFilesystemConfig.js +1 -0
  68. package/dist/generated/RootFilesystemEntry.d.ts +13 -0
  69. package/dist/generated/RootFilesystemEntry.js +1 -0
  70. package/dist/generated/RootFilesystemEntryEncoding.d.ts +1 -0
  71. package/dist/generated/RootFilesystemEntryEncoding.js +2 -0
  72. package/dist/generated/RootFilesystemEntryKind.d.ts +1 -0
  73. package/dist/generated/RootFilesystemEntryKind.js +2 -0
  74. package/dist/generated/RootFilesystemLowerDescriptor.d.ts +7 -0
  75. package/dist/generated/RootFilesystemLowerDescriptor.js +1 -0
  76. package/dist/generated/RootFilesystemMode.d.ts +1 -0
  77. package/dist/generated/RootFilesystemMode.js +2 -0
  78. package/dist/generated/ToolLimitsConfig.d.ts +10 -0
  79. package/dist/generated/ToolLimitsConfig.js +2 -0
  80. package/dist/generated/VmDnsConfig.d.ts +6 -0
  81. package/dist/generated/VmDnsConfig.js +2 -0
  82. package/dist/generated/VmLimitsConfig.d.ts +18 -0
  83. package/dist/generated/VmLimitsConfig.js +1 -0
  84. package/dist/generated/VmListenPolicyConfig.d.ts +5 -0
  85. package/dist/generated/VmListenPolicyConfig.js +2 -0
  86. package/dist/generated/WasmLimitsConfig.d.ts +5 -0
  87. package/dist/generated/WasmLimitsConfig.js +2 -0
  88. package/dist/generated-protocol.d.ts +1037 -0
  89. package/dist/generated-protocol.js +2887 -0
  90. package/dist/index.d.ts +24 -62
  91. package/dist/index.js +24 -53
  92. package/dist/json.d.ts +2 -0
  93. package/dist/json.js +20 -0
  94. package/dist/kernel-proxy.d.ts +149 -0
  95. package/dist/kernel-proxy.js +1733 -0
  96. package/dist/native-client.d.ts +41 -0
  97. package/dist/native-client.js +124 -0
  98. package/dist/node-runtime.d.ts +490 -0
  99. package/dist/node-runtime.js +585 -0
  100. package/dist/numbers.d.ts +1 -0
  101. package/dist/numbers.js +8 -0
  102. package/dist/ownership.d.ts +18 -0
  103. package/dist/ownership.js +77 -0
  104. package/dist/permissions.d.ts +29 -0
  105. package/dist/permissions.js +68 -0
  106. package/dist/process.d.ts +35 -0
  107. package/dist/process.js +125 -0
  108. package/dist/protocol-client.d.ts +46 -0
  109. package/dist/protocol-client.js +180 -0
  110. package/dist/protocol-frames.d.ts +68 -0
  111. package/dist/protocol-frames.js +139 -0
  112. package/dist/protocol-maps.d.ts +28 -0
  113. package/dist/protocol-maps.js +217 -0
  114. package/dist/protocol-schema.d.ts +10 -0
  115. package/dist/protocol-schema.js +11 -0
  116. package/dist/request-payloads.d.ts +137 -0
  117. package/dist/request-payloads.js +210 -0
  118. package/dist/response-payloads.d.ts +107 -0
  119. package/dist/response-payloads.js +161 -0
  120. package/dist/sidecar-client.d.ts +242 -0
  121. package/dist/sidecar-client.js +797 -0
  122. package/dist/state.d.ts +40 -0
  123. package/dist/state.js +44 -0
  124. package/dist/test-runtime.d.ts +526 -0
  125. package/dist/test-runtime.js +2119 -0
  126. package/dist/vm-config.d.ts +31 -0
  127. package/dist/vm-config.js +1 -0
  128. package/fixtures/alpine-defaults.json +520 -0
  129. package/fixtures/base-filesystem.json +528 -0
  130. package/package.json +193 -115
  131. package/LICENSE +0 -191
  132. package/dist/bridge-setup.d.ts +0 -6
  133. package/dist/bridge-setup.js +0 -9
  134. package/dist/esm-compiler.d.ts +0 -18
  135. package/dist/esm-compiler.js +0 -72
  136. package/dist/fs-helpers.d.ts +0 -23
  137. package/dist/fs-helpers.js +0 -41
  138. package/dist/generated/isolate-runtime.d.ts +0 -19
  139. package/dist/generated/isolate-runtime.js +0 -21
  140. package/dist/generated/polyfills.d.ts +0 -82
  141. package/dist/generated/polyfills.js +0 -82
  142. package/dist/isolate-runtime/apply-custom-global-policy.js +0 -53
  143. package/dist/isolate-runtime/apply-timing-mitigation-freeze.js +0 -130
  144. package/dist/isolate-runtime/apply-timing-mitigation-off.js +0 -14
  145. package/dist/isolate-runtime/bridge-attach.js +0 -29
  146. package/dist/isolate-runtime/bridge-initial-globals.js +0 -385
  147. package/dist/isolate-runtime/eval-script-result.js +0 -8
  148. package/dist/isolate-runtime/global-exposure-helpers.js +0 -36
  149. package/dist/isolate-runtime/init-commonjs-module-globals.js +0 -28
  150. package/dist/isolate-runtime/override-process-cwd.js +0 -8
  151. package/dist/isolate-runtime/override-process-env.js +0 -8
  152. package/dist/isolate-runtime/require-setup.js +0 -4153
  153. package/dist/isolate-runtime/set-commonjs-file-globals.js +0 -36
  154. package/dist/isolate-runtime/set-stdin-data.js +0 -10
  155. package/dist/isolate-runtime/setup-dynamic-import.js +0 -123
  156. package/dist/isolate-runtime/setup-fs-facade.js +0 -87
  157. package/dist/kernel/command-registry.d.ts +0 -44
  158. package/dist/kernel/command-registry.js +0 -114
  159. package/dist/kernel/device-backend.d.ts +0 -14
  160. package/dist/kernel/device-backend.js +0 -251
  161. package/dist/kernel/device-layer.d.ts +0 -12
  162. package/dist/kernel/device-layer.js +0 -271
  163. package/dist/kernel/dns-cache.d.ts +0 -29
  164. package/dist/kernel/dns-cache.js +0 -52
  165. package/dist/kernel/fd-table.d.ts +0 -84
  166. package/dist/kernel/fd-table.js +0 -278
  167. package/dist/kernel/file-lock.d.ts +0 -34
  168. package/dist/kernel/file-lock.js +0 -122
  169. package/dist/kernel/host-adapter.d.ts +0 -50
  170. package/dist/kernel/host-adapter.js +0 -8
  171. package/dist/kernel/index.d.ts +0 -36
  172. package/dist/kernel/index.js +0 -34
  173. package/dist/kernel/kernel.d.ts +0 -9
  174. package/dist/kernel/kernel.js +0 -1415
  175. package/dist/kernel/mount-table.d.ts +0 -75
  176. package/dist/kernel/mount-table.js +0 -353
  177. package/dist/kernel/permissions.d.ts +0 -36
  178. package/dist/kernel/permissions.js +0 -150
  179. package/dist/kernel/pipe-manager.d.ts +0 -64
  180. package/dist/kernel/pipe-manager.js +0 -267
  181. package/dist/kernel/proc-backend.d.ts +0 -30
  182. package/dist/kernel/proc-backend.js +0 -428
  183. package/dist/kernel/proc-layer.d.ts +0 -11
  184. package/dist/kernel/proc-layer.js +0 -507
  185. package/dist/kernel/process-table.d.ts +0 -126
  186. package/dist/kernel/process-table.js +0 -651
  187. package/dist/kernel/pty.d.ts +0 -109
  188. package/dist/kernel/pty.js +0 -552
  189. package/dist/kernel/socket-table.d.ts +0 -312
  190. package/dist/kernel/socket-table.js +0 -1188
  191. package/dist/kernel/timer-table.d.ts +0 -54
  192. package/dist/kernel/timer-table.js +0 -108
  193. package/dist/kernel/types.d.ts +0 -541
  194. package/dist/kernel/types.js +0 -98
  195. package/dist/kernel/user.d.ts +0 -29
  196. package/dist/kernel/user.js +0 -35
  197. package/dist/kernel/vfs.d.ts +0 -82
  198. package/dist/kernel/vfs.js +0 -25
  199. package/dist/kernel/wait.d.ts +0 -45
  200. package/dist/kernel/wait.js +0 -112
  201. package/dist/kernel/wstatus.d.ts +0 -21
  202. package/dist/kernel/wstatus.js +0 -33
  203. package/dist/module-resolver.d.ts +0 -29
  204. package/dist/module-resolver.js +0 -314
  205. package/dist/package-bundler.d.ts +0 -41
  206. package/dist/package-bundler.js +0 -497
  207. package/dist/runtime-driver.d.ts +0 -66
  208. package/dist/shared/api-types.d.ts +0 -83
  209. package/dist/shared/bridge-contract.d.ts +0 -772
  210. package/dist/shared/bridge-contract.js +0 -169
  211. package/dist/shared/console-formatter.d.ts +0 -22
  212. package/dist/shared/console-formatter.js +0 -161
  213. package/dist/shared/constants.d.ts +0 -3
  214. package/dist/shared/constants.js +0 -3
  215. package/dist/shared/errors.d.ts +0 -16
  216. package/dist/shared/errors.js +0 -21
  217. package/dist/shared/esm-utils.d.ts +0 -28
  218. package/dist/shared/esm-utils.js +0 -97
  219. package/dist/shared/global-exposure.d.ts +0 -38
  220. package/dist/shared/global-exposure.js +0 -876
  221. package/dist/shared/in-memory-fs.d.ts +0 -16
  222. package/dist/shared/in-memory-fs.js +0 -115
  223. package/dist/shared/permissions.d.ts +0 -36
  224. package/dist/shared/permissions.js +0 -314
  225. package/dist/shared/require-setup.d.ts +0 -6
  226. package/dist/shared/require-setup.js +0 -9
  227. package/dist/test/block-store-conformance.d.ts +0 -34
  228. package/dist/test/block-store-conformance.js +0 -251
  229. package/dist/test/metadata-store-conformance.d.ts +0 -37
  230. package/dist/test/metadata-store-conformance.js +0 -646
  231. package/dist/test/vfs-conformance.d.ts +0 -65
  232. package/dist/test/vfs-conformance.js +0 -842
  233. package/dist/types.d.ts +0 -98
  234. package/dist/types.js +0 -6
  235. package/dist/vfs/chunked-vfs.d.ts +0 -66
  236. package/dist/vfs/chunked-vfs.js +0 -1290
  237. package/dist/vfs/host-block-store.d.ts +0 -19
  238. package/dist/vfs/host-block-store.js +0 -97
  239. package/dist/vfs/memory-block-store.d.ts +0 -16
  240. package/dist/vfs/memory-block-store.js +0 -45
  241. package/dist/vfs/memory-metadata.d.ts +0 -75
  242. package/dist/vfs/memory-metadata.js +0 -528
  243. package/dist/vfs/sqlite-metadata.d.ts +0 -91
  244. package/dist/vfs/sqlite-metadata.js +0 -582
  245. package/dist/vfs/types.d.ts +0 -210
  246. package/dist/vfs/types.js +0 -8
  247. /package/dist/{runtime-driver.js → generated/CreateVmConfig.js} +0 -0
  248. /package/dist/{shared/api-types.js → generated/FsPermissionRule.js} +0 -0
@@ -0,0 +1,313 @@
1
+ import { fromGeneratedExtEnvelope, } from "./ext.js";
2
+ import { ownershipMatchesSelector, ownershipSelectorKey, } from "./ownership.js";
3
+ import { fromGeneratedStreamChannel, fromGeneratedVmLifecycleState, } from "./protocol-maps.js";
4
+ export const ANY_BUFFERED_EVENT_KEY = "*";
5
+ export class SidecarEventBufferOverflow extends Error {
6
+ capacity;
7
+ bufferedEvents;
8
+ eventType;
9
+ constructor(options) {
10
+ super(`sidecar event buffer overflow after ${options.bufferedEvents} queued events (capacity ${options.capacity}) while buffering ${options.eventType}`);
11
+ this.name = "SidecarEventBufferOverflow";
12
+ this.capacity = options.capacity;
13
+ this.bufferedEvents = options.bufferedEvents;
14
+ this.eventType = options.eventType;
15
+ }
16
+ }
17
+ export class SidecarEventBuffer {
18
+ capacity;
19
+ bufferedEvents = new Map();
20
+ bufferedEventQueues = new Map();
21
+ nextBufferedEventId = 1;
22
+ constructor(capacity) {
23
+ this.capacity = capacity;
24
+ }
25
+ get size() {
26
+ return this.bufferedEvents.size;
27
+ }
28
+ buffer(event) {
29
+ if (this.bufferedEvents.size >= this.capacity) {
30
+ return new SidecarEventBufferOverflow({
31
+ capacity: this.capacity,
32
+ bufferedEvents: this.bufferedEvents.size,
33
+ eventType: event.payload.type,
34
+ });
35
+ }
36
+ const eventId = this.nextBufferedEventId++;
37
+ const keys = sidecarEventBufferKeys(event);
38
+ this.bufferedEvents.set(eventId, {
39
+ event,
40
+ keys,
41
+ });
42
+ for (const key of keys) {
43
+ const queue = this.bufferedEventQueues.get(key);
44
+ if (queue) {
45
+ queue.add(eventId);
46
+ continue;
47
+ }
48
+ this.bufferedEventQueues.set(key, new Set([eventId]));
49
+ }
50
+ return null;
51
+ }
52
+ take(matcher) {
53
+ if (matcher.bufferKey !== null) {
54
+ return this.takeFromKey(matcher.bufferKey);
55
+ }
56
+ const queue = this.bufferedEventQueues.get(ANY_BUFFERED_EVENT_KEY);
57
+ if (!queue) {
58
+ return null;
59
+ }
60
+ for (const eventId of queue) {
61
+ const record = this.bufferedEvents.get(eventId);
62
+ if (!record) {
63
+ continue;
64
+ }
65
+ if (!matcher.matches(record.event)) {
66
+ continue;
67
+ }
68
+ return this.remove(eventId);
69
+ }
70
+ return null;
71
+ }
72
+ takeFromKey(key) {
73
+ const queue = this.bufferedEventQueues.get(key);
74
+ if (!queue) {
75
+ return null;
76
+ }
77
+ for (const eventId of queue) {
78
+ const record = this.bufferedEvents.get(eventId);
79
+ if (!record) {
80
+ queue.delete(eventId);
81
+ continue;
82
+ }
83
+ return this.remove(eventId);
84
+ }
85
+ return null;
86
+ }
87
+ remove(eventId) {
88
+ const record = this.bufferedEvents.get(eventId);
89
+ if (!record) {
90
+ return null;
91
+ }
92
+ this.bufferedEvents.delete(eventId);
93
+ for (const key of record.keys) {
94
+ const queue = this.bufferedEventQueues.get(key);
95
+ if (!queue) {
96
+ continue;
97
+ }
98
+ queue.delete(eventId);
99
+ if (queue.size === 0) {
100
+ this.bufferedEventQueues.delete(key);
101
+ }
102
+ }
103
+ return record.event;
104
+ }
105
+ }
106
+ function buildBufferKey(type, options) {
107
+ const parts = [`type:${type}`];
108
+ if (options?.ownership) {
109
+ parts.push(`ownership:${ownershipSelectorKey(options.ownership)}`);
110
+ }
111
+ if (options?.state) {
112
+ parts.push(`state:${options.state}`);
113
+ }
114
+ if (options?.processId) {
115
+ parts.push(`process:${options.processId}`);
116
+ }
117
+ if (options?.channel) {
118
+ parts.push(`channel:${options.channel}`);
119
+ }
120
+ if (options?.name) {
121
+ parts.push(`name:${options.name}`);
122
+ }
123
+ return parts.join("|");
124
+ }
125
+ export function sidecarSelectorMatchesEvent(selector, event) {
126
+ if ("any" in selector) {
127
+ return true;
128
+ }
129
+ if (event.payload.type !== selector.type) {
130
+ return false;
131
+ }
132
+ if (!ownershipMatchesSelector(selector.ownership, event.ownership)) {
133
+ return false;
134
+ }
135
+ switch (selector.type) {
136
+ case "vm_lifecycle": {
137
+ const payload = event.payload;
138
+ return selector.state === undefined || payload.state === selector.state;
139
+ }
140
+ case "process_output": {
141
+ const payload = event.payload;
142
+ return ((selector.processId === undefined ||
143
+ payload.process_id === selector.processId) &&
144
+ (selector.channel === undefined || payload.channel === selector.channel));
145
+ }
146
+ case "process_exited": {
147
+ const payload = event.payload;
148
+ return (selector.processId === undefined ||
149
+ payload.process_id === selector.processId);
150
+ }
151
+ case "structured": {
152
+ const payload = event.payload;
153
+ if (selector.name !== undefined && payload.name !== selector.name) {
154
+ return false;
155
+ }
156
+ if (!selector.detail) {
157
+ return true;
158
+ }
159
+ for (const [key, value] of Object.entries(selector.detail)) {
160
+ if (payload.detail[key] !== value) {
161
+ return false;
162
+ }
163
+ }
164
+ return true;
165
+ }
166
+ }
167
+ }
168
+ export function sidecarSelectorBufferKey(selector) {
169
+ if ("any" in selector) {
170
+ return ANY_BUFFERED_EVENT_KEY;
171
+ }
172
+ switch (selector.type) {
173
+ case "vm_lifecycle":
174
+ return buildBufferKey(selector.type, {
175
+ ownership: selector.ownership,
176
+ state: selector.state,
177
+ });
178
+ case "process_output":
179
+ return buildBufferKey(selector.type, {
180
+ ownership: selector.ownership,
181
+ processId: selector.processId,
182
+ channel: selector.channel,
183
+ });
184
+ case "process_exited":
185
+ return buildBufferKey(selector.type, {
186
+ ownership: selector.ownership,
187
+ processId: selector.processId,
188
+ });
189
+ case "structured":
190
+ if (selector.detail) {
191
+ return null;
192
+ }
193
+ return buildBufferKey(selector.type, {
194
+ ownership: selector.ownership,
195
+ name: selector.name,
196
+ });
197
+ }
198
+ }
199
+ export function normalizeSidecarEventMatcher(selector) {
200
+ if (typeof selector === "function") {
201
+ return {
202
+ matches: selector,
203
+ bufferKey: null,
204
+ };
205
+ }
206
+ return {
207
+ matches: (event) => sidecarSelectorMatchesEvent(selector, event),
208
+ bufferKey: sidecarSelectorBufferKey(selector),
209
+ };
210
+ }
211
+ export function fromGeneratedEventPayload(payload) {
212
+ switch (payload.tag) {
213
+ case "VmLifecycleEvent":
214
+ return {
215
+ type: "vm_lifecycle",
216
+ state: fromGeneratedVmLifecycleState(payload.val.state),
217
+ };
218
+ case "ProcessOutputEvent":
219
+ return {
220
+ type: "process_output",
221
+ process_id: payload.val.processId,
222
+ channel: fromGeneratedStreamChannel(payload.val.channel),
223
+ chunk: Buffer.from(payload.val.chunk),
224
+ };
225
+ case "ProcessExitedEvent":
226
+ return {
227
+ type: "process_exited",
228
+ process_id: payload.val.processId,
229
+ exit_code: payload.val.exitCode,
230
+ };
231
+ case "StructuredEvent":
232
+ return {
233
+ type: "structured",
234
+ name: payload.val.name,
235
+ detail: Object.fromEntries(payload.val.detail),
236
+ };
237
+ case "ExtEnvelope":
238
+ return {
239
+ type: "ext",
240
+ envelope: fromGeneratedExtEnvelope(payload.val),
241
+ };
242
+ }
243
+ }
244
+ export function sidecarEventWaitAbortError(reason) {
245
+ return reason instanceof Error
246
+ ? reason
247
+ : new Error(reason ? String(reason) : "sidecar event wait aborted");
248
+ }
249
+ export function sidecarEventBufferKeys(event) {
250
+ const owner = event.ownership;
251
+ const keys = new Set([
252
+ ANY_BUFFERED_EVENT_KEY,
253
+ buildBufferKey(event.payload.type),
254
+ buildBufferKey(event.payload.type, { ownership: owner }),
255
+ ]);
256
+ switch (event.payload.type) {
257
+ case "vm_lifecycle":
258
+ keys.add(buildBufferKey(event.payload.type, {
259
+ state: event.payload.state,
260
+ }));
261
+ keys.add(buildBufferKey(event.payload.type, {
262
+ ownership: owner,
263
+ state: event.payload.state,
264
+ }));
265
+ break;
266
+ case "process_output":
267
+ keys.add(buildBufferKey(event.payload.type, {
268
+ processId: event.payload.process_id,
269
+ }));
270
+ keys.add(buildBufferKey(event.payload.type, {
271
+ channel: event.payload.channel,
272
+ }));
273
+ keys.add(buildBufferKey(event.payload.type, {
274
+ processId: event.payload.process_id,
275
+ channel: event.payload.channel,
276
+ }));
277
+ keys.add(buildBufferKey(event.payload.type, {
278
+ ownership: owner,
279
+ processId: event.payload.process_id,
280
+ }));
281
+ keys.add(buildBufferKey(event.payload.type, {
282
+ ownership: owner,
283
+ channel: event.payload.channel,
284
+ }));
285
+ keys.add(buildBufferKey(event.payload.type, {
286
+ ownership: owner,
287
+ processId: event.payload.process_id,
288
+ channel: event.payload.channel,
289
+ }));
290
+ break;
291
+ case "process_exited":
292
+ keys.add(buildBufferKey(event.payload.type, {
293
+ processId: event.payload.process_id,
294
+ }));
295
+ keys.add(buildBufferKey(event.payload.type, {
296
+ ownership: owner,
297
+ processId: event.payload.process_id,
298
+ }));
299
+ break;
300
+ case "structured":
301
+ keys.add(buildBufferKey(event.payload.type, {
302
+ name: event.payload.name,
303
+ }));
304
+ keys.add(buildBufferKey(event.payload.type, {
305
+ ownership: owner,
306
+ name: event.payload.name,
307
+ }));
308
+ break;
309
+ case "ext":
310
+ break;
311
+ }
312
+ return [...keys];
313
+ }
package/dist/ext.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ import type * as sidecarProtocol from "./generated-protocol.js";
2
+ export interface LiveExtEnvelope {
3
+ namespace: string;
4
+ payload: Uint8Array;
5
+ }
6
+ export declare function toGeneratedExtEnvelope(envelope: LiveExtEnvelope): sidecarProtocol.ExtEnvelope;
7
+ export declare function fromGeneratedExtEnvelope(envelope: sidecarProtocol.ExtEnvelope): LiveExtEnvelope;
package/dist/ext.js ADDED
@@ -0,0 +1,13 @@
1
+ import { toExactArrayBuffer } from "./bytes.js";
2
+ export function toGeneratedExtEnvelope(envelope) {
3
+ return {
4
+ namespace: envelope.namespace,
5
+ payload: toExactArrayBuffer(envelope.payload),
6
+ };
7
+ }
8
+ export function fromGeneratedExtEnvelope(envelope) {
9
+ return {
10
+ namespace: envelope.namespace,
11
+ payload: Buffer.from(envelope.payload),
12
+ };
13
+ }
@@ -0,0 +1,41 @@
1
+ import * as protocol from "./generated-protocol.js";
2
+ import { type LiveRootFilesystemEntryEncoding } from "./protocol-maps.js";
3
+ export type { LiveRootFilesystemEntryEncoding } from "./protocol-maps.js";
4
+ export type GuestFilesystemContentEncoding = "utf8" | "base64";
5
+ export interface GuestFilesystemContentResult {
6
+ path: string;
7
+ content?: string;
8
+ encoding?: GuestFilesystemContentEncoding;
9
+ }
10
+ export type LiveRootFilesystemEntry = {
11
+ path: string;
12
+ kind: "file" | "directory" | "symlink";
13
+ mode?: number;
14
+ uid?: number;
15
+ gid?: number;
16
+ content?: string;
17
+ encoding?: LiveRootFilesystemEntryEncoding;
18
+ target?: string;
19
+ executable?: boolean;
20
+ };
21
+ export type LiveRootFilesystemLowerDescriptor = {
22
+ kind: "snapshot";
23
+ entries: LiveRootFilesystemEntry[];
24
+ } | {
25
+ kind: "bundled_base_filesystem";
26
+ };
27
+ export type LiveRootFilesystemDescriptor = {
28
+ mode?: "ephemeral" | "read_only";
29
+ disable_default_base_layer?: boolean;
30
+ lowers?: LiveRootFilesystemLowerDescriptor[];
31
+ bootstrap_entries?: LiveRootFilesystemEntry[];
32
+ };
33
+ export declare function encodeGuestFilesystemContent(content: string | Uint8Array): {
34
+ content: string;
35
+ encoding?: GuestFilesystemContentEncoding;
36
+ };
37
+ export declare function decodeGuestFilesystemContent(response: GuestFilesystemContentResult): Uint8Array;
38
+ export declare function toGeneratedRootFilesystemDescriptor(descriptor: LiveRootFilesystemDescriptor): protocol.RootFilesystemDescriptor;
39
+ export declare function toGeneratedRootFilesystemLower(lower: LiveRootFilesystemLowerDescriptor): protocol.RootFilesystemLowerDescriptor;
40
+ export declare function toGeneratedRootFilesystemEntry(entry: LiveRootFilesystemEntry): protocol.RootFilesystemEntry;
41
+ export declare function fromGeneratedRootFilesystemEntry(entry: protocol.RootFilesystemEntry): LiveRootFilesystemEntry;
@@ -0,0 +1,70 @@
1
+ import { fromGeneratedRootFilesystemEntryEncoding, fromGeneratedRootFilesystemEntryKind, toGeneratedRootFilesystemEntryEncoding, toGeneratedRootFilesystemEntryKind, toGeneratedRootFilesystemMode, } from "./protocol-maps.js";
2
+ export function encodeGuestFilesystemContent(content) {
3
+ if (typeof content === "string") {
4
+ return { content };
5
+ }
6
+ return {
7
+ content: Buffer.from(content).toString("base64"),
8
+ encoding: "base64",
9
+ };
10
+ }
11
+ export function decodeGuestFilesystemContent(response) {
12
+ if (response.content === undefined) {
13
+ throw new Error(`sidecar returned no file content for ${response.path}`);
14
+ }
15
+ if (response.encoding === "base64") {
16
+ return Buffer.from(response.content, "base64");
17
+ }
18
+ return Buffer.from(response.content, "utf8");
19
+ }
20
+ export function toGeneratedRootFilesystemDescriptor(descriptor) {
21
+ return {
22
+ mode: toGeneratedRootFilesystemMode(descriptor.mode ?? "ephemeral"),
23
+ disableDefaultBaseLayer: descriptor.disable_default_base_layer ?? false,
24
+ lowers: (descriptor.lowers ?? []).map(toGeneratedRootFilesystemLower),
25
+ bootstrapEntries: (descriptor.bootstrap_entries ?? []).map(toGeneratedRootFilesystemEntry),
26
+ };
27
+ }
28
+ export function toGeneratedRootFilesystemLower(lower) {
29
+ switch (lower.kind) {
30
+ case "snapshot":
31
+ return {
32
+ tag: "SnapshotRootFilesystemLower",
33
+ val: {
34
+ entries: (lower.entries ?? []).map(toGeneratedRootFilesystemEntry),
35
+ },
36
+ };
37
+ case "bundled_base_filesystem":
38
+ return { tag: "BundledBaseFilesystemLower", val: null };
39
+ }
40
+ }
41
+ export function toGeneratedRootFilesystemEntry(entry) {
42
+ return {
43
+ path: entry.path,
44
+ kind: toGeneratedRootFilesystemEntryKind(entry.kind),
45
+ mode: entry.mode ?? null,
46
+ uid: entry.uid ?? null,
47
+ gid: entry.gid ?? null,
48
+ content: entry.content ?? null,
49
+ encoding: entry.encoding === undefined
50
+ ? null
51
+ : toGeneratedRootFilesystemEntryEncoding(entry.encoding),
52
+ target: entry.target ?? null,
53
+ executable: entry.executable ?? false,
54
+ };
55
+ }
56
+ export function fromGeneratedRootFilesystemEntry(entry) {
57
+ return {
58
+ path: entry.path,
59
+ kind: fromGeneratedRootFilesystemEntryKind(entry.kind),
60
+ ...(entry.mode !== null ? { mode: entry.mode } : {}),
61
+ ...(entry.uid !== null ? { uid: entry.uid } : {}),
62
+ ...(entry.gid !== null ? { gid: entry.gid } : {}),
63
+ ...(entry.content !== null ? { content: entry.content } : {}),
64
+ ...(entry.encoding !== null
65
+ ? { encoding: fromGeneratedRootFilesystemEntryEncoding(entry.encoding) }
66
+ : {}),
67
+ ...(entry.target !== null ? { target: entry.target } : {}),
68
+ executable: entry.executable,
69
+ };
70
+ }
@@ -0,0 +1,8 @@
1
+ export type TransportPayloadCodec = "bare" | "json";
2
+ export declare function encodeJsonFramePayload(frame: unknown): Buffer;
3
+ export declare function decodeJsonFramePayload<TFrame extends {
4
+ payload?: {
5
+ type?: string;
6
+ chunk?: unknown;
7
+ };
8
+ }>(payload: Uint8Array): TFrame;
@@ -0,0 +1,14 @@
1
+ export function encodeJsonFramePayload(frame) {
2
+ // BARE `data` fields are Uint8Array; JSON.stringify renders those as objects, so encode them
3
+ // as number arrays to match serde_json's Vec<u8> representation on the Rust side.
4
+ return Buffer.from(JSON.stringify(frame, (_key, value) => value instanceof Uint8Array ? Array.from(value) : value), "utf8");
5
+ }
6
+ export function decodeJsonFramePayload(payload) {
7
+ const frame = JSON.parse(Buffer.from(payload).toString("utf8"));
8
+ const decodedPayload = frame.payload;
9
+ if (decodedPayload?.type === "process_output" &&
10
+ Array.isArray(decodedPayload.chunk)) {
11
+ decodedPayload.chunk = Uint8Array.from(decodedPayload.chunk);
12
+ }
13
+ return frame;
14
+ }
@@ -0,0 +1,38 @@
1
+ import type { Readable, Writable } from "node:stream";
2
+ export type ClassifiedFrame<TResponseFrame, TEventFrame, TSidecarRequestFrame> = {
3
+ kind: "response";
4
+ requestId: number;
5
+ frame: TResponseFrame;
6
+ } | {
7
+ kind: "event";
8
+ frame: TEventFrame;
9
+ } | {
10
+ kind: "sidecarRequest";
11
+ frame: TSidecarRequestFrame;
12
+ };
13
+ export interface FrameRpcTransportOptions<TReadFrame, TWriteFrame, TResponseFrame, TEventFrame, TSidecarRequestFrame> {
14
+ stdin: Writable;
15
+ stdout: Readable;
16
+ encodeFrame: (frame: TWriteFrame) => Uint8Array;
17
+ decodeFrame: (payload: Uint8Array) => TReadFrame;
18
+ classifyFrame: (frame: TReadFrame) => ClassifiedFrame<TResponseFrame, TEventFrame, TSidecarRequestFrame>;
19
+ }
20
+ export declare class FrameRpcTransport<TReadFrame, TWriteFrame, TResponseFrame, TEventFrame, TSidecarRequestFrame> {
21
+ private readonly frameTransport;
22
+ private readonly pendingResponses;
23
+ private readonly eventListeners;
24
+ private readonly sidecarRequestListeners;
25
+ constructor(options: FrameRpcTransportOptions<TReadFrame, TWriteFrame, TResponseFrame, TEventFrame, TSidecarRequestFrame>);
26
+ onEvent(handler: (event: TEventFrame) => void): () => void;
27
+ onSidecarRequest(handler: (request: TSidecarRequestFrame) => void): () => void;
28
+ onError(handler: (error: Error) => void): () => void;
29
+ onEnd(handler: () => void): () => void;
30
+ sendFrame(requestId: number, frame: TWriteFrame, options: {
31
+ timeoutMs: number;
32
+ timeoutMessage: () => string;
33
+ }): Promise<TResponseFrame>;
34
+ writeFrame(frame: TWriteFrame): Promise<void>;
35
+ rejectAll(error: Error): void;
36
+ dispose(): void;
37
+ private dispatchFrame;
38
+ }
@@ -0,0 +1,73 @@
1
+ import { PendingResponseRegistry } from "./correlation.js";
2
+ import { StdioFrameTransport } from "./frame-stream.js";
3
+ export class FrameRpcTransport {
4
+ frameTransport;
5
+ pendingResponses = new PendingResponseRegistry();
6
+ eventListeners = new Set();
7
+ sidecarRequestListeners = new Set();
8
+ constructor(options) {
9
+ this.frameTransport = new StdioFrameTransport({
10
+ stdin: options.stdin,
11
+ stdout: options.stdout,
12
+ encodeFrame: options.encodeFrame,
13
+ decodeFrame: options.decodeFrame,
14
+ });
15
+ this.frameTransport.onFrame((frame) => {
16
+ this.dispatchFrame(options.classifyFrame(frame));
17
+ });
18
+ }
19
+ onEvent(handler) {
20
+ this.eventListeners.add(handler);
21
+ return () => {
22
+ this.eventListeners.delete(handler);
23
+ };
24
+ }
25
+ onSidecarRequest(handler) {
26
+ this.sidecarRequestListeners.add(handler);
27
+ return () => {
28
+ this.sidecarRequestListeners.delete(handler);
29
+ };
30
+ }
31
+ onError(handler) {
32
+ return this.frameTransport.onError(handler);
33
+ }
34
+ onEnd(handler) {
35
+ return this.frameTransport.onEnd(handler);
36
+ }
37
+ async sendFrame(requestId, frame, options) {
38
+ const response = this.pendingResponses.waitForResponse(requestId, options);
39
+ void this.writeFrame(frame).catch((error) => {
40
+ this.pendingResponses.reject(requestId, error instanceof Error ? error : new Error(String(error)));
41
+ });
42
+ return await response;
43
+ }
44
+ async writeFrame(frame) {
45
+ await this.frameTransport.writeFrame(frame);
46
+ }
47
+ rejectAll(error) {
48
+ this.pendingResponses.rejectAll(error);
49
+ }
50
+ dispose() {
51
+ this.frameTransport.dispose();
52
+ this.pendingResponses.rejectAll(new Error("frame rpc transport disposed"));
53
+ this.eventListeners.clear();
54
+ this.sidecarRequestListeners.clear();
55
+ }
56
+ dispatchFrame(classified) {
57
+ switch (classified.kind) {
58
+ case "response":
59
+ this.pendingResponses.resolve(classified.requestId, classified.frame);
60
+ return;
61
+ case "event":
62
+ for (const listener of this.eventListeners) {
63
+ listener(classified.frame);
64
+ }
65
+ return;
66
+ case "sidecarRequest":
67
+ for (const listener of this.sidecarRequestListeners) {
68
+ listener(classified.frame);
69
+ }
70
+ return;
71
+ }
72
+ }
73
+ }
@@ -0,0 +1,27 @@
1
+ import type { Readable, Writable } from "node:stream";
2
+ export interface StdioFrameTransportOptions<TReadFrame, TWriteFrame> {
3
+ stdin: Writable;
4
+ stdout: Readable;
5
+ encodeFrame: (frame: TWriteFrame) => Uint8Array;
6
+ decodeFrame: (payload: Uint8Array) => TReadFrame;
7
+ }
8
+ export declare class StdioFrameTransport<TReadFrame, TWriteFrame = TReadFrame> {
9
+ private readonly stdin;
10
+ private readonly stdout;
11
+ private readonly encodeFrame;
12
+ private readonly decodeFrame;
13
+ private readonly frameListeners;
14
+ private readonly errorListeners;
15
+ private readonly endListeners;
16
+ private stdoutBuffer;
17
+ constructor(options: StdioFrameTransportOptions<TReadFrame, TWriteFrame>);
18
+ onFrame(handler: (frame: TReadFrame) => void): () => void;
19
+ onError(handler: (error: Error) => void): () => void;
20
+ onEnd(handler: () => void): () => void;
21
+ writeFrame(frame: TWriteFrame): Promise<void>;
22
+ dispose(): void;
23
+ private readonly handleData;
24
+ private readonly handleEnd;
25
+ private readonly handleError;
26
+ private drainFrames;
27
+ }