almostnode 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +731 -0
  3. package/dist/__sw__.js +394 -0
  4. package/dist/ai-chatbot-demo-entry.d.ts +6 -0
  5. package/dist/ai-chatbot-demo-entry.d.ts.map +1 -0
  6. package/dist/ai-chatbot-demo.d.ts +42 -0
  7. package/dist/ai-chatbot-demo.d.ts.map +1 -0
  8. package/dist/assets/runtime-worker-D9x_Ddwz.js +60543 -0
  9. package/dist/assets/runtime-worker-D9x_Ddwz.js.map +1 -0
  10. package/dist/convex-app-demo-entry.d.ts +6 -0
  11. package/dist/convex-app-demo-entry.d.ts.map +1 -0
  12. package/dist/convex-app-demo.d.ts +68 -0
  13. package/dist/convex-app-demo.d.ts.map +1 -0
  14. package/dist/cors-proxy.d.ts +46 -0
  15. package/dist/cors-proxy.d.ts.map +1 -0
  16. package/dist/create-runtime.d.ts +42 -0
  17. package/dist/create-runtime.d.ts.map +1 -0
  18. package/dist/demo.d.ts +6 -0
  19. package/dist/demo.d.ts.map +1 -0
  20. package/dist/dev-server.d.ts +97 -0
  21. package/dist/dev-server.d.ts.map +1 -0
  22. package/dist/frameworks/next-dev-server.d.ts +202 -0
  23. package/dist/frameworks/next-dev-server.d.ts.map +1 -0
  24. package/dist/frameworks/vite-dev-server.d.ts +85 -0
  25. package/dist/frameworks/vite-dev-server.d.ts.map +1 -0
  26. package/dist/index.cjs +14965 -0
  27. package/dist/index.cjs.map +1 -0
  28. package/dist/index.d.ts +71 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.mjs +14867 -0
  31. package/dist/index.mjs.map +1 -0
  32. package/dist/next-demo.d.ts +49 -0
  33. package/dist/next-demo.d.ts.map +1 -0
  34. package/dist/npm/index.d.ts +71 -0
  35. package/dist/npm/index.d.ts.map +1 -0
  36. package/dist/npm/registry.d.ts +66 -0
  37. package/dist/npm/registry.d.ts.map +1 -0
  38. package/dist/npm/resolver.d.ts +52 -0
  39. package/dist/npm/resolver.d.ts.map +1 -0
  40. package/dist/npm/tarball.d.ts +29 -0
  41. package/dist/npm/tarball.d.ts.map +1 -0
  42. package/dist/runtime-interface.d.ts +90 -0
  43. package/dist/runtime-interface.d.ts.map +1 -0
  44. package/dist/runtime.d.ts +103 -0
  45. package/dist/runtime.d.ts.map +1 -0
  46. package/dist/sandbox-helpers.d.ts +43 -0
  47. package/dist/sandbox-helpers.d.ts.map +1 -0
  48. package/dist/sandbox-runtime.d.ts +65 -0
  49. package/dist/sandbox-runtime.d.ts.map +1 -0
  50. package/dist/server-bridge.d.ts +89 -0
  51. package/dist/server-bridge.d.ts.map +1 -0
  52. package/dist/shims/assert.d.ts +51 -0
  53. package/dist/shims/assert.d.ts.map +1 -0
  54. package/dist/shims/async_hooks.d.ts +37 -0
  55. package/dist/shims/async_hooks.d.ts.map +1 -0
  56. package/dist/shims/buffer.d.ts +20 -0
  57. package/dist/shims/buffer.d.ts.map +1 -0
  58. package/dist/shims/child_process-browser.d.ts +92 -0
  59. package/dist/shims/child_process-browser.d.ts.map +1 -0
  60. package/dist/shims/child_process.d.ts +93 -0
  61. package/dist/shims/child_process.d.ts.map +1 -0
  62. package/dist/shims/chokidar.d.ts +55 -0
  63. package/dist/shims/chokidar.d.ts.map +1 -0
  64. package/dist/shims/cluster.d.ts +52 -0
  65. package/dist/shims/cluster.d.ts.map +1 -0
  66. package/dist/shims/crypto.d.ts +122 -0
  67. package/dist/shims/crypto.d.ts.map +1 -0
  68. package/dist/shims/dgram.d.ts +34 -0
  69. package/dist/shims/dgram.d.ts.map +1 -0
  70. package/dist/shims/diagnostics_channel.d.ts +80 -0
  71. package/dist/shims/diagnostics_channel.d.ts.map +1 -0
  72. package/dist/shims/dns.d.ts +87 -0
  73. package/dist/shims/dns.d.ts.map +1 -0
  74. package/dist/shims/domain.d.ts +25 -0
  75. package/dist/shims/domain.d.ts.map +1 -0
  76. package/dist/shims/esbuild.d.ts +105 -0
  77. package/dist/shims/esbuild.d.ts.map +1 -0
  78. package/dist/shims/events.d.ts +37 -0
  79. package/dist/shims/events.d.ts.map +1 -0
  80. package/dist/shims/fs.d.ts +115 -0
  81. package/dist/shims/fs.d.ts.map +1 -0
  82. package/dist/shims/fsevents.d.ts +67 -0
  83. package/dist/shims/fsevents.d.ts.map +1 -0
  84. package/dist/shims/http.d.ts +217 -0
  85. package/dist/shims/http.d.ts.map +1 -0
  86. package/dist/shims/http2.d.ts +81 -0
  87. package/dist/shims/http2.d.ts.map +1 -0
  88. package/dist/shims/https.d.ts +36 -0
  89. package/dist/shims/https.d.ts.map +1 -0
  90. package/dist/shims/inspector.d.ts +25 -0
  91. package/dist/shims/inspector.d.ts.map +1 -0
  92. package/dist/shims/module.d.ts +22 -0
  93. package/dist/shims/module.d.ts.map +1 -0
  94. package/dist/shims/net.d.ts +100 -0
  95. package/dist/shims/net.d.ts.map +1 -0
  96. package/dist/shims/os.d.ts +159 -0
  97. package/dist/shims/os.d.ts.map +1 -0
  98. package/dist/shims/path.d.ts +72 -0
  99. package/dist/shims/path.d.ts.map +1 -0
  100. package/dist/shims/perf_hooks.d.ts +50 -0
  101. package/dist/shims/perf_hooks.d.ts.map +1 -0
  102. package/dist/shims/process.d.ts +93 -0
  103. package/dist/shims/process.d.ts.map +1 -0
  104. package/dist/shims/querystring.d.ts +23 -0
  105. package/dist/shims/querystring.d.ts.map +1 -0
  106. package/dist/shims/readdirp.d.ts +52 -0
  107. package/dist/shims/readdirp.d.ts.map +1 -0
  108. package/dist/shims/readline.d.ts +62 -0
  109. package/dist/shims/readline.d.ts.map +1 -0
  110. package/dist/shims/rollup.d.ts +34 -0
  111. package/dist/shims/rollup.d.ts.map +1 -0
  112. package/dist/shims/sentry.d.ts +163 -0
  113. package/dist/shims/sentry.d.ts.map +1 -0
  114. package/dist/shims/stream.d.ts +181 -0
  115. package/dist/shims/stream.d.ts.map +1 -0
  116. package/dist/shims/tls.d.ts +53 -0
  117. package/dist/shims/tls.d.ts.map +1 -0
  118. package/dist/shims/tty.d.ts +30 -0
  119. package/dist/shims/tty.d.ts.map +1 -0
  120. package/dist/shims/url.d.ts +64 -0
  121. package/dist/shims/url.d.ts.map +1 -0
  122. package/dist/shims/util.d.ts +106 -0
  123. package/dist/shims/util.d.ts.map +1 -0
  124. package/dist/shims/v8.d.ts +73 -0
  125. package/dist/shims/v8.d.ts.map +1 -0
  126. package/dist/shims/vfs-adapter.d.ts +126 -0
  127. package/dist/shims/vfs-adapter.d.ts.map +1 -0
  128. package/dist/shims/vm.d.ts +45 -0
  129. package/dist/shims/vm.d.ts.map +1 -0
  130. package/dist/shims/worker_threads.d.ts +66 -0
  131. package/dist/shims/worker_threads.d.ts.map +1 -0
  132. package/dist/shims/ws.d.ts +66 -0
  133. package/dist/shims/ws.d.ts.map +1 -0
  134. package/dist/shims/zlib.d.ts +161 -0
  135. package/dist/shims/zlib.d.ts.map +1 -0
  136. package/dist/transform.d.ts +24 -0
  137. package/dist/transform.d.ts.map +1 -0
  138. package/dist/virtual-fs.d.ts +226 -0
  139. package/dist/virtual-fs.d.ts.map +1 -0
  140. package/dist/vite-demo.d.ts +35 -0
  141. package/dist/vite-demo.d.ts.map +1 -0
  142. package/dist/vite-sw.js +132 -0
  143. package/dist/worker/runtime-worker.d.ts +8 -0
  144. package/dist/worker/runtime-worker.d.ts.map +1 -0
  145. package/dist/worker-runtime.d.ts +50 -0
  146. package/dist/worker-runtime.d.ts.map +1 -0
  147. package/package.json +85 -0
  148. package/src/ai-chatbot-demo-entry.ts +244 -0
  149. package/src/ai-chatbot-demo.ts +509 -0
  150. package/src/convex-app-demo-entry.ts +1107 -0
  151. package/src/convex-app-demo.ts +1316 -0
  152. package/src/cors-proxy.ts +81 -0
  153. package/src/create-runtime.ts +147 -0
  154. package/src/demo.ts +304 -0
  155. package/src/dev-server.ts +274 -0
  156. package/src/frameworks/next-dev-server.ts +2224 -0
  157. package/src/frameworks/vite-dev-server.ts +702 -0
  158. package/src/index.ts +101 -0
  159. package/src/next-demo.ts +1784 -0
  160. package/src/npm/index.ts +347 -0
  161. package/src/npm/registry.ts +152 -0
  162. package/src/npm/resolver.ts +385 -0
  163. package/src/npm/tarball.ts +209 -0
  164. package/src/runtime-interface.ts +103 -0
  165. package/src/runtime.ts +1046 -0
  166. package/src/sandbox-helpers.ts +173 -0
  167. package/src/sandbox-runtime.ts +252 -0
  168. package/src/server-bridge.ts +426 -0
  169. package/src/shims/assert.ts +664 -0
  170. package/src/shims/async_hooks.ts +86 -0
  171. package/src/shims/buffer.ts +75 -0
  172. package/src/shims/child_process-browser.ts +217 -0
  173. package/src/shims/child_process.ts +463 -0
  174. package/src/shims/chokidar.ts +313 -0
  175. package/src/shims/cluster.ts +67 -0
  176. package/src/shims/crypto.ts +830 -0
  177. package/src/shims/dgram.ts +47 -0
  178. package/src/shims/diagnostics_channel.ts +196 -0
  179. package/src/shims/dns.ts +172 -0
  180. package/src/shims/domain.ts +58 -0
  181. package/src/shims/esbuild.ts +805 -0
  182. package/src/shims/events.ts +195 -0
  183. package/src/shims/fs.ts +803 -0
  184. package/src/shims/fsevents.ts +63 -0
  185. package/src/shims/http.ts +904 -0
  186. package/src/shims/http2.ts +96 -0
  187. package/src/shims/https.ts +86 -0
  188. package/src/shims/inspector.ts +30 -0
  189. package/src/shims/module.ts +82 -0
  190. package/src/shims/net.ts +359 -0
  191. package/src/shims/os.ts +195 -0
  192. package/src/shims/path.ts +199 -0
  193. package/src/shims/perf_hooks.ts +92 -0
  194. package/src/shims/process.ts +346 -0
  195. package/src/shims/querystring.ts +97 -0
  196. package/src/shims/readdirp.ts +228 -0
  197. package/src/shims/readline.ts +110 -0
  198. package/src/shims/rollup.ts +80 -0
  199. package/src/shims/sentry.ts +133 -0
  200. package/src/shims/stream.ts +1126 -0
  201. package/src/shims/tls.ts +95 -0
  202. package/src/shims/tty.ts +64 -0
  203. package/src/shims/url.ts +171 -0
  204. package/src/shims/util.ts +312 -0
  205. package/src/shims/v8.ts +113 -0
  206. package/src/shims/vfs-adapter.ts +402 -0
  207. package/src/shims/vm.ts +83 -0
  208. package/src/shims/worker_threads.ts +111 -0
  209. package/src/shims/ws.ts +382 -0
  210. package/src/shims/zlib.ts +289 -0
  211. package/src/transform.ts +313 -0
  212. package/src/types/external.d.ts +67 -0
  213. package/src/virtual-fs.ts +903 -0
  214. package/src/vite-demo.ts +577 -0
  215. package/src/worker/runtime-worker.ts +128 -0
  216. package/src/worker-runtime.ts +145 -0
package/dist/__sw__.js ADDED
@@ -0,0 +1,394 @@
1
+ /**
2
+ * Service Worker for Mini WebContainers
3
+ * Intercepts fetch requests and routes them to virtual servers
4
+ * Version: 12 - add COEP/COOP headers for iframe embedding
5
+ */
6
+
7
+ // Communication port with main thread
8
+ let mainPort = null;
9
+
10
+ // Pending requests waiting for response
11
+ const pendingRequests = new Map();
12
+ let requestId = 0;
13
+
14
+ // Registered virtual server ports
15
+ const registeredPorts = new Set();
16
+
17
+ /**
18
+ * Handle messages from main thread
19
+ */
20
+ self.addEventListener('message', (event) => {
21
+ const { type, data } = event.data;
22
+
23
+ console.log('[SW] Received message:', type, 'hasPort in event.ports:', event.ports?.length > 0);
24
+
25
+ // When a MessagePort is transferred, it's in event.ports[0], not event.data.port
26
+ if (type === 'init' && event.ports && event.ports[0]) {
27
+ // Initialize communication channel
28
+ mainPort = event.ports[0];
29
+ mainPort.onmessage = handleMainMessage;
30
+ console.log('[SW] Initialized communication channel with transferred port');
31
+ }
32
+
33
+ if (type === 'server-registered' && data) {
34
+ registeredPorts.add(data.port);
35
+ console.log(`[SW] Server registered on port ${data.port}`);
36
+ }
37
+
38
+ if (type === 'server-unregistered' && data) {
39
+ registeredPorts.delete(data.port);
40
+ console.log(`[SW] Server unregistered from port ${data.port}`);
41
+ }
42
+ });
43
+
44
+ /**
45
+ * Handle response messages from main thread
46
+ */
47
+ function handleMainMessage(event) {
48
+ const { type, id, data, error } = event.data;
49
+
50
+ console.log('[SW] Received message from main:', type, 'id:', id);
51
+
52
+ if (type === 'response') {
53
+ const pending = pendingRequests.get(id);
54
+ console.log('[SW] Looking for pending request:', id, 'found:', !!pending);
55
+
56
+ if (pending) {
57
+ pendingRequests.delete(id);
58
+
59
+ if (error) {
60
+ console.log('[SW] Response error:', error);
61
+ pending.reject(new Error(error));
62
+ } else {
63
+ console.log('[SW] Response data:', {
64
+ statusCode: data?.statusCode,
65
+ statusMessage: data?.statusMessage,
66
+ headers: data?.headers,
67
+ bodyType: data?.body?.constructor?.name,
68
+ bodyLength: data?.body?.length || data?.body?.byteLength,
69
+ });
70
+ pending.resolve(data);
71
+ }
72
+ }
73
+ }
74
+
75
+ // Handle streaming responses
76
+ if (type === 'stream-start') {
77
+ console.log('[SW] 🟢 stream-start received, id:', id);
78
+ const pending = pendingRequests.get(id);
79
+ if (pending && pending.streamController) {
80
+ // Store headers/status for the streaming response
81
+ pending.streamData = data;
82
+ pending.resolveHeaders(data);
83
+ console.log('[SW] 🟢 headers resolved for stream', id);
84
+ } else {
85
+ console.log('[SW] 🔴 No pending request or controller for stream-start', id, !!pending, pending?.streamController);
86
+ }
87
+ }
88
+
89
+ if (type === 'stream-chunk') {
90
+ console.log('[SW] 🟡 stream-chunk received, id:', id, 'size:', data?.chunkBase64?.length);
91
+ const pending = pendingRequests.get(id);
92
+ if (pending && pending.streamController) {
93
+ try {
94
+ // Decode base64 chunk and enqueue
95
+ if (data.chunkBase64) {
96
+ const binary = atob(data.chunkBase64);
97
+ const bytes = new Uint8Array(binary.length);
98
+ for (let i = 0; i < binary.length; i++) {
99
+ bytes[i] = binary.charCodeAt(i);
100
+ }
101
+ pending.streamController.enqueue(bytes);
102
+ console.log('[SW] 🟡 chunk enqueued, bytes:', bytes.length);
103
+ }
104
+ } catch (e) {
105
+ console.error('[SW] Error enqueueing chunk:', e);
106
+ }
107
+ } else {
108
+ console.log('[SW] 🔴 No pending request or controller for stream-chunk', id);
109
+ }
110
+ }
111
+
112
+ if (type === 'stream-end') {
113
+ console.log('[SW] 🟢 stream-end received, id:', id);
114
+ const pending = pendingRequests.get(id);
115
+ if (pending && pending.streamController) {
116
+ try {
117
+ pending.streamController.close();
118
+ console.log('[SW] 🟢 stream closed');
119
+ } catch (e) {
120
+ console.log('[SW] stream already closed');
121
+ }
122
+ pendingRequests.delete(id);
123
+ }
124
+ }
125
+ }
126
+
127
+ /**
128
+ * Send request to main thread and wait for response
129
+ */
130
+ async function sendRequest(port, method, url, headers, body) {
131
+ console.log('[SW] sendRequest called, mainPort:', !!mainPort, 'url:', url);
132
+
133
+ if (!mainPort) {
134
+ console.error('[SW] No mainPort available! Service Worker not connected to main thread.');
135
+ throw new Error('Service Worker not initialized - no connection to main thread');
136
+ }
137
+
138
+ const id = ++requestId;
139
+
140
+ return new Promise((resolve, reject) => {
141
+ pendingRequests.set(id, { resolve, reject });
142
+
143
+ // Set timeout for request
144
+ setTimeout(() => {
145
+ if (pendingRequests.has(id)) {
146
+ pendingRequests.delete(id);
147
+ reject(new Error('Request timeout'));
148
+ }
149
+ }, 30000);
150
+
151
+ mainPort.postMessage({
152
+ type: 'request',
153
+ id,
154
+ data: { port, method, url, headers, body },
155
+ });
156
+ });
157
+ }
158
+
159
+ /**
160
+ * Send streaming request to main thread
161
+ * Returns a ReadableStream that receives chunks from main thread
162
+ */
163
+ function sendStreamingRequest(port, method, url, headers, body) {
164
+ console.log('[SW] sendStreamingRequest called, url:', url);
165
+
166
+ if (!mainPort) {
167
+ throw new Error('Service Worker not initialized');
168
+ }
169
+
170
+ const id = ++requestId;
171
+
172
+ let streamController;
173
+ let resolveHeaders;
174
+ const headersPromise = new Promise(resolve => { resolveHeaders = resolve; });
175
+
176
+ const stream = new ReadableStream({
177
+ start(controller) {
178
+ streamController = controller;
179
+
180
+ // Store in pending requests so handleMainMessage can find it
181
+ pendingRequests.set(id, {
182
+ resolve: () => {},
183
+ reject: (err) => controller.error(err),
184
+ streamController: controller,
185
+ resolveHeaders,
186
+ });
187
+
188
+ // Send request to main thread with streaming flag
189
+ mainPort.postMessage({
190
+ type: 'request',
191
+ id,
192
+ data: { port, method, url, headers, body, streaming: true },
193
+ });
194
+ },
195
+ cancel() {
196
+ pendingRequests.delete(id);
197
+ }
198
+ });
199
+
200
+ return { stream, headersPromise, id };
201
+ }
202
+
203
+ /**
204
+ * Intercept fetch requests
205
+ */
206
+ self.addEventListener('fetch', (event) => {
207
+ const url = new URL(event.request.url);
208
+
209
+ console.log('[SW] Fetch:', url.pathname, 'mainPort:', !!mainPort);
210
+
211
+ // Check if this is a virtual server request
212
+ const match = url.pathname.match(/^\/__virtual__\/(\d+)(\/.*)?$/);
213
+
214
+ if (!match) {
215
+ // Not a virtual request, let it pass through
216
+ return;
217
+ }
218
+
219
+ console.log('[SW] Virtual request:', url.pathname);
220
+
221
+ const port = parseInt(match[1], 10);
222
+ const path = match[2] || '/';
223
+
224
+ // TEST MODE: Return hardcoded response to verify SW is working
225
+ if (url.searchParams.has('__sw_test__')) {
226
+ event.respondWith(new Response(
227
+ '<!DOCTYPE html><html><body><h1>SW Test OK</h1><div id="root">Service Worker is responding correctly!</div></body></html>',
228
+ {
229
+ status: 200,
230
+ headers: { 'Content-Type': 'text/html' },
231
+ }
232
+ ));
233
+ return;
234
+ }
235
+
236
+ // DEBUG MODE: Return info about what SW receives
237
+ if (url.searchParams.has('__sw_debug__')) {
238
+ event.respondWith((async () => {
239
+ try {
240
+ const response = await sendRequest(port, 'GET', path, {}, null);
241
+ return new Response(
242
+ `<!DOCTYPE html><html><body><h1>SW Debug</h1><pre>${JSON.stringify({
243
+ statusCode: response.statusCode,
244
+ statusMessage: response.statusMessage,
245
+ headers: response.headers,
246
+ bodyBase64Length: response.bodyBase64?.length,
247
+ bodyBase64Start: response.bodyBase64?.substring(0, 100),
248
+ }, null, 2)}</pre></body></html>`,
249
+ { status: 200, headers: { 'Content-Type': 'text/html' } }
250
+ );
251
+ } catch (error) {
252
+ return new Response(`Error: ${error.message}`, { status: 500 });
253
+ }
254
+ })());
255
+ return;
256
+ }
257
+
258
+ event.respondWith(handleVirtualRequest(event.request, port, path + url.search));
259
+ });
260
+
261
+ /**
262
+ * Handle a request to a virtual server
263
+ */
264
+ async function handleVirtualRequest(request, port, path) {
265
+ try {
266
+ // Build headers object
267
+ const headers = {};
268
+ request.headers.forEach((value, key) => {
269
+ headers[key] = value;
270
+ });
271
+
272
+ // Get body if present
273
+ let body = null;
274
+ if (request.method !== 'GET' && request.method !== 'HEAD') {
275
+ body = await request.arrayBuffer();
276
+ }
277
+
278
+ // Check if this is an API route that might stream (POST to /api/*)
279
+ const isStreamingCandidate = request.method === 'POST' && path.startsWith('/api/');
280
+
281
+ if (isStreamingCandidate) {
282
+ console.log('[SW] 🔴 Using streaming mode for:', path);
283
+ return handleStreamingRequest(port, request.method, path, headers, body);
284
+ }
285
+ console.log('[SW] Using non-streaming mode for:', request.method, path);
286
+
287
+ console.log('[SW] Sending request to main thread:', port, request.method, path);
288
+
289
+ // Send to main thread
290
+ const response = await sendRequest(port, request.method, path, headers, body);
291
+
292
+ console.log('[SW] Got response from main thread:', {
293
+ statusCode: response.statusCode,
294
+ headersKeys: response.headers ? Object.keys(response.headers) : [],
295
+ bodyBase64Length: response.bodyBase64?.length,
296
+ });
297
+
298
+ // Decode base64 body and create response
299
+ let finalResponse;
300
+ if (response.bodyBase64 && response.bodyBase64.length > 0) {
301
+ try {
302
+ const binary = atob(response.bodyBase64);
303
+ const bytes = new Uint8Array(binary.length);
304
+ for (let i = 0; i < binary.length; i++) {
305
+ bytes[i] = binary.charCodeAt(i);
306
+ }
307
+ console.log('[SW] Decoded body length:', bytes.length);
308
+
309
+ // Use Blob to ensure proper body handling
310
+ const blob = new Blob([bytes], { type: response.headers['Content-Type'] || 'application/octet-stream' });
311
+ console.log('[SW] Created blob size:', blob.size);
312
+
313
+ // Merge response headers with CORP/COEP headers to allow iframe embedding
314
+ // The parent page has COEP: credentialless, so we need matching headers
315
+ const respHeaders = new Headers(response.headers);
316
+ respHeaders.set('Cross-Origin-Embedder-Policy', 'credentialless');
317
+ respHeaders.set('Cross-Origin-Opener-Policy', 'same-origin');
318
+ respHeaders.set('Cross-Origin-Resource-Policy', 'cross-origin');
319
+ // Remove any headers that might block iframe loading
320
+ respHeaders.delete('X-Frame-Options');
321
+
322
+ finalResponse = new Response(blob, {
323
+ status: response.statusCode,
324
+ statusText: response.statusMessage,
325
+ headers: respHeaders,
326
+ });
327
+ } catch (decodeError) {
328
+ console.error('[SW] Failed to decode base64 body:', decodeError);
329
+ finalResponse = new Response(`Decode error: ${decodeError.message}`, {
330
+ status: 500,
331
+ headers: { 'Content-Type': 'text/plain' },
332
+ });
333
+ }
334
+ } else {
335
+ finalResponse = new Response(null, {
336
+ status: response.statusCode,
337
+ statusText: response.statusMessage,
338
+ headers: response.headers,
339
+ });
340
+ }
341
+
342
+ console.log('[SW] Final Response created, status:', finalResponse.status);
343
+
344
+ return finalResponse;
345
+ } catch (error) {
346
+ console.error('[SW] Error handling virtual request:', error);
347
+ return new Response(`Service Worker Error: ${error.message}`, {
348
+ status: 500,
349
+ statusText: 'Internal Server Error',
350
+ headers: { 'Content-Type': 'text/plain' },
351
+ });
352
+ }
353
+ }
354
+
355
+ /**
356
+ * Handle a streaming request
357
+ */
358
+ async function handleStreamingRequest(port, method, path, headers, body) {
359
+ const { stream, headersPromise, id } = sendStreamingRequest(port, method, path, headers, body);
360
+
361
+ // Wait for headers to arrive
362
+ const responseData = await headersPromise;
363
+
364
+ console.log('[SW] Streaming response started:', responseData?.statusCode);
365
+
366
+ // Build response headers
367
+ const respHeaders = new Headers(responseData?.headers || {});
368
+ respHeaders.set('Cross-Origin-Embedder-Policy', 'credentialless');
369
+ respHeaders.set('Cross-Origin-Opener-Policy', 'same-origin');
370
+ respHeaders.set('Cross-Origin-Resource-Policy', 'cross-origin');
371
+ respHeaders.delete('X-Frame-Options');
372
+
373
+ return new Response(stream, {
374
+ status: responseData?.statusCode || 200,
375
+ statusText: responseData?.statusMessage || 'OK',
376
+ headers: respHeaders,
377
+ });
378
+ }
379
+
380
+ /**
381
+ * Activate immediately
382
+ */
383
+ self.addEventListener('install', (event) => {
384
+ console.log('[SW] Installing...');
385
+ event.waitUntil(self.skipWaiting());
386
+ });
387
+
388
+ /**
389
+ * Claim all clients immediately
390
+ */
391
+ self.addEventListener('activate', (event) => {
392
+ console.log('[SW] Activated');
393
+ event.waitUntil(self.clients.claim());
394
+ });
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Entry point for AI Chatbot Demo
3
+ * This file is loaded by the HTML and bootstraps the demo
4
+ */
5
+ export {};
6
+ //# sourceMappingURL=ai-chatbot-demo-entry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-chatbot-demo-entry.d.ts","sourceRoot":"","sources":["../src/ai-chatbot-demo-entry.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
@@ -0,0 +1,42 @@
1
+ /**
2
+ * AI Chatbot Demo with Next.js + Vercel AI SDK
3
+ *
4
+ * This demo creates a chatbot application using:
5
+ * - Next.js App Router for the frontend
6
+ * - Pages Router API routes for the streaming endpoint
7
+ * - Vercel AI SDK with useChat hook
8
+ * - OpenAI (via CORS proxy for browser environment)
9
+ */
10
+ import { VirtualFS } from './virtual-fs';
11
+ /**
12
+ * Package.json for the AI chatbot app
13
+ */
14
+ declare const PACKAGE_JSON: {
15
+ name: string;
16
+ version: string;
17
+ private: boolean;
18
+ scripts: {
19
+ dev: string;
20
+ build: string;
21
+ start: string;
22
+ };
23
+ dependencies: {
24
+ next: string;
25
+ react: string;
26
+ "react-dom": string;
27
+ ai: string;
28
+ "@ai-sdk/openai": string;
29
+ };
30
+ devDependencies: {
31
+ "@types/node": string;
32
+ "@types/react": string;
33
+ "@types/react-dom": string;
34
+ typescript: string;
35
+ };
36
+ };
37
+ /**
38
+ * Create the AI chatbot project structure in the virtual filesystem
39
+ */
40
+ export declare function createAIChatbotProject(vfs: VirtualFS): void;
41
+ export { PACKAGE_JSON };
42
+ //# sourceMappingURL=ai-chatbot-demo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-chatbot-demo.d.ts","sourceRoot":"","sources":["../src/ai-chatbot-demo.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC;;GAEG;AACH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;CAsBjB,CAAC;AAEF;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,SAAS,GAAG,IAAI,CA+c3D;AAGD,OAAO,EAAE,YAAY,EAAE,CAAC"}