electrobun 0.0.19-beta.97 → 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 (77) hide show
  1. package/README.md +1 -1
  2. package/dist/api/browser/webviewtag.ts +54 -2
  3. package/dist/api/bun/ElectrobunConfig.ts +171 -0
  4. package/dist/api/bun/core/BrowserWindow.ts +4 -0
  5. package/dist/api/bun/core/Tray.ts +14 -0
  6. package/dist/api/bun/core/Updater.ts +4 -3
  7. package/dist/api/bun/index.ts +2 -0
  8. package/dist/api/bun/proc/native.ts +107 -5
  9. package/dist/main.js +5 -4
  10. package/package.json +4 -2
  11. package/src/cli/index.ts +565 -148
  12. package/templates/hello-world/bun.lock +164 -2
  13. package/templates/hello-world/electrobun.config.ts +28 -0
  14. package/templates/hello-world/src/bun/index.ts +2 -2
  15. package/templates/hello-world/src/mainview/index.html +5 -6
  16. package/templates/hello-world/src/mainview/index.ts +1 -5
  17. package/templates/interactive-playground/README.md +26 -0
  18. package/templates/interactive-playground/assets/tray-icon.png +0 -0
  19. package/templates/interactive-playground/electrobun.config.ts +36 -0
  20. package/templates/interactive-playground/package-lock.json +36 -0
  21. package/templates/interactive-playground/package.json +15 -0
  22. package/templates/interactive-playground/src/bun/demos/files.ts +70 -0
  23. package/templates/interactive-playground/src/bun/demos/menus.ts +139 -0
  24. package/templates/interactive-playground/src/bun/demos/rpc.ts +83 -0
  25. package/templates/interactive-playground/src/bun/demos/system.ts +72 -0
  26. package/templates/interactive-playground/src/bun/demos/updates.ts +105 -0
  27. package/templates/interactive-playground/src/bun/demos/windows.ts +90 -0
  28. package/templates/interactive-playground/src/bun/index.ts +124 -0
  29. package/templates/interactive-playground/src/bun/types/rpc.ts +109 -0
  30. package/templates/interactive-playground/src/mainview/components/EventLog.ts +107 -0
  31. package/templates/interactive-playground/src/mainview/components/Sidebar.ts +65 -0
  32. package/templates/interactive-playground/src/mainview/components/Toast.ts +57 -0
  33. package/templates/interactive-playground/src/mainview/demos/FileDemo.ts +211 -0
  34. package/templates/interactive-playground/src/mainview/demos/MenuDemo.ts +102 -0
  35. package/templates/interactive-playground/src/mainview/demos/RPCDemo.ts +229 -0
  36. package/templates/interactive-playground/src/mainview/demos/TrayDemo.ts +132 -0
  37. package/templates/interactive-playground/src/mainview/demos/WebViewDemo.ts +411 -0
  38. package/templates/interactive-playground/src/mainview/demos/WindowDemo.ts +207 -0
  39. package/templates/interactive-playground/src/mainview/index.css +538 -0
  40. package/templates/interactive-playground/src/mainview/index.html +103 -0
  41. package/templates/interactive-playground/src/mainview/index.ts +238 -0
  42. package/templates/multitab-browser/README.md +34 -0
  43. package/templates/multitab-browser/bun.lock +224 -0
  44. package/templates/multitab-browser/electrobun.config.ts +32 -0
  45. package/templates/multitab-browser/package-lock.json +20 -0
  46. package/templates/multitab-browser/package.json +12 -0
  47. package/templates/multitab-browser/src/bun/index.ts +144 -0
  48. package/templates/multitab-browser/src/bun/tabManager.ts +200 -0
  49. package/templates/multitab-browser/src/bun/types/rpc.ts +78 -0
  50. package/templates/multitab-browser/src/mainview/index.css +487 -0
  51. package/templates/multitab-browser/src/mainview/index.html +94 -0
  52. package/templates/multitab-browser/src/mainview/index.ts +634 -0
  53. package/templates/photo-booth/README.md +108 -0
  54. package/templates/photo-booth/bun.lock +239 -0
  55. package/templates/photo-booth/electrobun.config.ts +28 -0
  56. package/templates/photo-booth/package.json +16 -0
  57. package/templates/photo-booth/src/bun/index.ts +92 -0
  58. package/templates/photo-booth/src/mainview/index.css +465 -0
  59. package/templates/photo-booth/src/mainview/index.html +124 -0
  60. package/templates/photo-booth/src/mainview/index.ts +499 -0
  61. package/tests/bun.lock +14 -0
  62. package/tests/electrobun.config.ts +45 -0
  63. package/tests/package-lock.json +36 -0
  64. package/tests/package.json +13 -0
  65. package/tests/src/bun/index.ts +100 -0
  66. package/tests/src/bun/test-runner.ts +508 -0
  67. package/tests/src/mainview/index.html +110 -0
  68. package/tests/src/mainview/index.ts +458 -0
  69. package/tests/src/mainview/styles/main.css +451 -0
  70. package/tests/src/testviews/tray-test.html +57 -0
  71. package/tests/src/testviews/webview-mask.html +114 -0
  72. package/tests/src/testviews/webview-navigation.html +36 -0
  73. package/tests/src/testviews/window-create.html +17 -0
  74. package/tests/src/testviews/window-events.html +29 -0
  75. package/tests/src/testviews/window-focus.html +37 -0
  76. package/tests/src/webviewtag/index.ts +11 -0
  77. package/templates/hello-world/electrobun.config +0 -18
@@ -0,0 +1,465 @@
1
+ * {
2
+ margin: 0;
3
+ padding: 0;
4
+ box-sizing: border-box;
5
+ }
6
+
7
+ body {
8
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Helvetica, Arial, sans-serif;
9
+ background: #1a1a1a;
10
+ color: #ffffff;
11
+ overflow: hidden;
12
+ }
13
+
14
+ .container {
15
+ height: 100vh;
16
+ display: flex;
17
+ flex-direction: column;
18
+ }
19
+
20
+ header {
21
+ background: #2a2a2a;
22
+ padding: 1rem 2rem;
23
+ display: flex;
24
+ justify-content: space-between;
25
+ align-items: center;
26
+ border-bottom: 1px solid #3a3a3a;
27
+ gap: 2rem;
28
+ }
29
+
30
+ .mode-selector {
31
+ display: flex;
32
+ gap: 0.5rem;
33
+ background: #1a1a1a;
34
+ padding: 0.25rem;
35
+ border-radius: 8px;
36
+ border: 1px solid #3a3a3a;
37
+ }
38
+
39
+ .mode-btn {
40
+ display: flex;
41
+ align-items: center;
42
+ gap: 0.5rem;
43
+ padding: 0.75rem 1rem;
44
+ background: transparent;
45
+ color: #999;
46
+ border: none;
47
+ border-radius: 6px;
48
+ font-size: 0.875rem;
49
+ font-weight: 500;
50
+ cursor: pointer;
51
+ transition: all 0.2s;
52
+ }
53
+
54
+ .mode-btn:hover {
55
+ background: #333;
56
+ color: #fff;
57
+ }
58
+
59
+ .mode-btn.active {
60
+ background: #007aff;
61
+ color: white;
62
+ }
63
+
64
+ .mode-btn.active:hover {
65
+ background: #0056b3;
66
+ }
67
+
68
+ h1 {
69
+ font-size: 1.5rem;
70
+ font-weight: 600;
71
+ }
72
+
73
+ .status {
74
+ display: flex;
75
+ align-items: center;
76
+ gap: 0.5rem;
77
+ font-size: 0.875rem;
78
+ color: #999;
79
+ }
80
+
81
+ .status-dot {
82
+ width: 8px;
83
+ height: 8px;
84
+ border-radius: 50%;
85
+ background: #666;
86
+ transition: background 0.3s;
87
+ }
88
+
89
+ .status.active .status-dot {
90
+ background: #4CAF50;
91
+ box-shadow: 0 0 8px #4CAF50;
92
+ }
93
+
94
+ .status.error .status-dot {
95
+ background: #f44336;
96
+ }
97
+
98
+ main {
99
+ flex: 1;
100
+ display: flex;
101
+ overflow: hidden;
102
+ }
103
+
104
+ .camera-section {
105
+ flex: 1;
106
+ display: flex;
107
+ flex-direction: column;
108
+ padding: 2rem;
109
+ gap: 1.5rem;
110
+ }
111
+
112
+ .video-container {
113
+ flex: 1;
114
+ position: relative;
115
+ background: #000;
116
+ border-radius: 12px;
117
+ overflow: hidden;
118
+ display: flex;
119
+ align-items: center;
120
+ justify-content: center;
121
+ }
122
+
123
+ .native-capture-placeholder {
124
+ position: absolute;
125
+ top: 0;
126
+ left: 0;
127
+ right: 0;
128
+ bottom: 0;
129
+ display: flex;
130
+ align-items: center;
131
+ justify-content: center;
132
+ background: #1a1a1a;
133
+ color: #999;
134
+ z-index: 1;
135
+ }
136
+
137
+ .placeholder-content {
138
+ text-align: center;
139
+ display: flex;
140
+ flex-direction: column;
141
+ align-items: center;
142
+ gap: 1rem;
143
+ }
144
+
145
+ .placeholder-content svg {
146
+ opacity: 0.6;
147
+ }
148
+
149
+ .placeholder-content p {
150
+ margin: 0;
151
+ font-size: 0.875rem;
152
+ }
153
+
154
+ .placeholder-content p:first-of-type {
155
+ font-size: 1rem;
156
+ font-weight: 500;
157
+ color: #ccc;
158
+ }
159
+
160
+ #video {
161
+ width: 100%;
162
+ height: 100%;
163
+ object-fit: cover;
164
+ }
165
+
166
+ .countdown {
167
+ position: absolute;
168
+ top: 50%;
169
+ left: 50%;
170
+ transform: translate(-50%, -50%);
171
+ font-size: 8rem;
172
+ font-weight: bold;
173
+ color: white;
174
+ text-shadow: 0 0 20px rgba(0, 0, 0, 0.8);
175
+ opacity: 0;
176
+ transition: opacity 0.3s;
177
+ }
178
+
179
+ .countdown.active {
180
+ opacity: 1;
181
+ }
182
+
183
+ .controls {
184
+ display: flex;
185
+ flex-direction: column;
186
+ gap: 1rem;
187
+ align-items: center;
188
+ }
189
+
190
+ .capture-btn {
191
+ display: flex;
192
+ align-items: center;
193
+ gap: 0.75rem;
194
+ padding: 0.75rem 2rem;
195
+ font-size: 1rem;
196
+ font-weight: 500;
197
+ background: #007AFF;
198
+ color: white;
199
+ border: none;
200
+ border-radius: 8px;
201
+ cursor: pointer;
202
+ transition: all 0.3s;
203
+ }
204
+
205
+ .capture-btn:hover:not(:disabled) {
206
+ background: #0056b3;
207
+ transform: scale(1.05);
208
+ }
209
+
210
+ .capture-btn:active:not(:disabled) {
211
+ transform: scale(0.95);
212
+ }
213
+
214
+ .capture-btn:disabled {
215
+ background: #444;
216
+ cursor: not-allowed;
217
+ opacity: 0.6;
218
+ }
219
+
220
+ .settings {
221
+ display: flex;
222
+ gap: 2rem;
223
+ align-items: center;
224
+ }
225
+
226
+ .settings label {
227
+ display: flex;
228
+ align-items: center;
229
+ gap: 0.5rem;
230
+ cursor: pointer;
231
+ }
232
+
233
+ .settings input[type="checkbox"] {
234
+ width: 18px;
235
+ height: 18px;
236
+ cursor: pointer;
237
+ }
238
+
239
+ .camera-select {
240
+ padding: 0.5rem;
241
+ background: #2a2a2a;
242
+ color: white;
243
+ border: 1px solid #3a3a3a;
244
+ border-radius: 4px;
245
+ cursor: pointer;
246
+ }
247
+
248
+ .camera-only-control {
249
+ display: flex;
250
+ }
251
+
252
+ .screen-only-control {
253
+ display: none;
254
+ }
255
+
256
+ .mode-screen .camera-only-control {
257
+ display: none;
258
+ }
259
+
260
+ .mode-screen .screen-only-control {
261
+ display: flex;
262
+ }
263
+
264
+ .start-camera-btn,
265
+ .select-screen-btn {
266
+ display: flex;
267
+ align-items: center;
268
+ gap: 0.5rem;
269
+ padding: 0.5rem 1rem;
270
+ background: #007aff;
271
+ color: white;
272
+ border: none;
273
+ border-radius: 6px;
274
+ font-size: 0.875rem;
275
+ cursor: pointer;
276
+ transition: background 0.2s;
277
+ }
278
+
279
+ .start-camera-btn:hover,
280
+ .select-screen-btn:hover {
281
+ background: #0056b3;
282
+ }
283
+
284
+ .change-source-btn {
285
+ display: flex;
286
+ align-items: center;
287
+ gap: 0.5rem;
288
+ padding: 0.5rem 1rem;
289
+ background: #444;
290
+ color: white;
291
+ border: 1px solid #555;
292
+ border-radius: 4px;
293
+ cursor: pointer;
294
+ font-size: 0.875rem;
295
+ transition: background 0.2s;
296
+ }
297
+
298
+ .change-source-btn:hover {
299
+ background: #555;
300
+ }
301
+
302
+ .gallery-section {
303
+ width: 300px;
304
+ background: #2a2a2a;
305
+ padding: 1.5rem;
306
+ overflow-y: auto;
307
+ border-left: 1px solid #3a3a3a;
308
+ }
309
+
310
+ .gallery-section h2 {
311
+ font-size: 1.125rem;
312
+ margin-bottom: 1rem;
313
+ }
314
+
315
+ .gallery {
316
+ display: grid;
317
+ grid-template-columns: repeat(2, 1fr);
318
+ gap: 0.75rem;
319
+ }
320
+
321
+ .empty-state {
322
+ grid-column: 1 / -1;
323
+ text-align: center;
324
+ color: #666;
325
+ padding: 2rem 0;
326
+ font-size: 0.875rem;
327
+ }
328
+
329
+ .photo-item {
330
+ position: relative;
331
+ aspect-ratio: 1;
332
+ border-radius: 8px;
333
+ overflow: hidden;
334
+ cursor: pointer;
335
+ transition: transform 0.2s;
336
+ }
337
+
338
+ .photo-item:hover {
339
+ transform: scale(1.05);
340
+ }
341
+
342
+ .photo-item img {
343
+ width: 100%;
344
+ height: 100%;
345
+ object-fit: cover;
346
+ }
347
+
348
+ .photo-item .photo-time {
349
+ position: absolute;
350
+ bottom: 0;
351
+ left: 0;
352
+ right: 0;
353
+ background: linear-gradient(to top, rgba(0,0,0,0.7), transparent);
354
+ color: white;
355
+ font-size: 0.75rem;
356
+ padding: 0.5rem;
357
+ text-align: center;
358
+ }
359
+
360
+ .photo-modal {
361
+ display: none;
362
+ position: fixed;
363
+ top: 0;
364
+ left: 0;
365
+ right: 0;
366
+ bottom: 0;
367
+ background: rgba(0, 0, 0, 0.9);
368
+ z-index: 1000;
369
+ padding: 2rem;
370
+ }
371
+
372
+ .photo-modal.active {
373
+ display: flex;
374
+ align-items: center;
375
+ justify-content: center;
376
+ }
377
+
378
+ .modal-content {
379
+ position: relative;
380
+ max-width: 90vw;
381
+ max-height: 90vh;
382
+ display: flex;
383
+ flex-direction: column;
384
+ gap: 1rem;
385
+ }
386
+
387
+ .modal-close {
388
+ position: absolute;
389
+ top: -40px;
390
+ right: 0;
391
+ background: none;
392
+ border: none;
393
+ color: white;
394
+ font-size: 2rem;
395
+ cursor: pointer;
396
+ width: 40px;
397
+ height: 40px;
398
+ display: flex;
399
+ align-items: center;
400
+ justify-content: center;
401
+ border-radius: 4px;
402
+ transition: background 0.2s;
403
+ }
404
+
405
+ .modal-close:hover {
406
+ background: rgba(255, 255, 255, 0.1);
407
+ }
408
+
409
+ #modalImage {
410
+ max-width: 100%;
411
+ max-height: calc(90vh - 60px);
412
+ object-fit: contain;
413
+ border-radius: 8px;
414
+ }
415
+
416
+ .modal-actions {
417
+ display: flex;
418
+ gap: 1rem;
419
+ justify-content: center;
420
+ }
421
+
422
+ .action-btn {
423
+ display: flex;
424
+ align-items: center;
425
+ gap: 0.5rem;
426
+ padding: 0.75rem 1.5rem;
427
+ background: #007AFF;
428
+ color: white;
429
+ border: none;
430
+ border-radius: 6px;
431
+ cursor: pointer;
432
+ font-size: 0.875rem;
433
+ font-weight: 500;
434
+ transition: background 0.2s;
435
+ }
436
+
437
+ .action-btn:hover {
438
+ background: #0056b3;
439
+ }
440
+
441
+ .action-btn.danger {
442
+ background: #dc3545;
443
+ }
444
+
445
+ .action-btn.danger:hover {
446
+ background: #c82333;
447
+ }
448
+
449
+ @media (max-width: 768px) {
450
+ main {
451
+ flex-direction: column;
452
+ }
453
+
454
+ .gallery-section {
455
+ width: 100%;
456
+ border-left: none;
457
+ border-top: 1px solid #3a3a3a;
458
+ height: 200px;
459
+ flex-shrink: 0;
460
+ }
461
+
462
+ .gallery {
463
+ grid-template-columns: repeat(3, 1fr);
464
+ }
465
+ }
@@ -0,0 +1,124 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>Photo Booth</title>
7
+ <link rel="stylesheet" href="./index.css">
8
+ </head>
9
+ <body>
10
+ <div class="container">
11
+ <header>
12
+ <h1>Photo Booth / Screenshot Tool</h1>
13
+ <div class="mode-selector">
14
+ <button id="cameraModeBtn" class="mode-btn active">
15
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
16
+ <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
17
+ <circle cx="12" cy="13" r="4"/>
18
+ </svg>
19
+ Camera
20
+ </button>
21
+ <button id="screenModeBtn" class="mode-btn">
22
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
23
+ <rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
24
+ <line x1="8" y1="21" x2="16" y2="21"/>
25
+ <line x1="12" y1="17" x2="12" y2="21"/>
26
+ </svg>
27
+ Screen Capture
28
+ </button>
29
+ </div>
30
+ <div class="status" id="status">
31
+ <span class="status-dot"></span>
32
+ <span class="status-text">Initializing...</span>
33
+ </div>
34
+ </header>
35
+
36
+ <main>
37
+ <div class="camera-section">
38
+ <div class="video-container">
39
+ <video id="video" autoplay playsinline></video>
40
+ <canvas id="canvas" style="display: none;"></canvas>
41
+ <div class="countdown" id="countdown"></div>
42
+ </div>
43
+
44
+ <div class="controls">
45
+ <button id="captureBtn" class="capture-btn" disabled>
46
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="capture-icon-camera">
47
+ <circle cx="12" cy="12" r="10"/>
48
+ <circle cx="12" cy="12" r="7"/>
49
+ </svg>
50
+ <svg width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" class="capture-icon-screen" style="display: none;">
51
+ <rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
52
+ <circle cx="12" cy="10" r="2"/>
53
+ </svg>
54
+ <span class="capture-btn-text">Take Photo</span>
55
+ </button>
56
+
57
+ <div class="settings">
58
+ <label class="timer-setting">
59
+ <input type="checkbox" id="timerToggle">
60
+ <span>3s Timer</span>
61
+ </label>
62
+
63
+ <select id="cameraSelect" class="camera-select camera-only-control">
64
+ <option value="">Select Camera</option>
65
+ </select>
66
+
67
+ <button id="startCameraBtn" class="start-camera-btn camera-only-control" style="display: none;">
68
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
69
+ <path d="M23 19a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h4l2-3h6l2 3h4a2 2 0 0 1 2 2z"/>
70
+ <circle cx="12" cy="13" r="4"/>
71
+ </svg>
72
+ Start Camera
73
+ </button>
74
+
75
+ <button id="selectScreenBtn" class="select-screen-btn screen-only-control" style="display: none;">
76
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
77
+ <rect x="2" y="3" width="20" height="14" rx="2" ry="2"/>
78
+ <polyline points="8 17 12 21 16 17"/>
79
+ </svg>
80
+ Select Screen
81
+ </button>
82
+ </div>
83
+ </div>
84
+ </div>
85
+
86
+ <div class="gallery-section">
87
+ <h2>Captured Photos</h2>
88
+ <div class="gallery" id="gallery">
89
+ <div class="empty-state">
90
+ No photos/screenshots yet. Click the capture button to get started!
91
+ </div>
92
+ </div>
93
+ </div>
94
+ </main>
95
+ </div>
96
+
97
+ <div class="photo-modal" id="photoModal">
98
+ <div class="modal-content">
99
+ <button class="modal-close" id="modalClose">&times;</button>
100
+ <img id="modalImage" src="" alt="Full size photo">
101
+ <div class="modal-actions">
102
+ <button id="downloadBtn" class="action-btn">
103
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
104
+ <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
105
+ <polyline points="7 10 12 15 17 10"/>
106
+ <line x1="12" y1="15" x2="12" y2="3"/>
107
+ </svg>
108
+ Save
109
+ </button>
110
+ <button id="deleteBtn" class="action-btn danger">
111
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
112
+ <path d="M3 6h18"/>
113
+ <path d="M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6"/>
114
+ <path d="M8 6V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2"/>
115
+ </svg>
116
+ Delete
117
+ </button>
118
+ </div>
119
+ </div>
120
+ </div>
121
+
122
+ <script src="./index.js"></script>
123
+ </body>
124
+ </html>