litestream 0.10.3-arm64-darwin → 0.10.4-arm64-darwin

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f8b952e4ea0adb29dadd86f7e9db925e1040be4dbc7e105922cb1acb12da134e
4
- data.tar.gz: 397e84ab1764b775c44a303c228562c49575e2b8983c3367b32d8294a6873aaf
3
+ metadata.gz: 818ad4745febd87b60606e1b5fcdeba9a9537d3f35333ea6764622172531dffe
4
+ data.tar.gz: 728784729ceaa1a09a7eac31c4562c33b36c819a4c1eec9752cf106d309b93f2
5
5
  SHA512:
6
- metadata.gz: 8cba5e941e50e35a46b8bb9d67c2a01dfa52b4d1cee2cd5cb142a740b700527f612d719f28b7d7404dd1c98ae7b353cd9f169d62ee7c97101e1a338dfaba3941
7
- data.tar.gz: 6508fe73bf104ed6c77794bb29bd14621f407576ad452e169c8c0a505c5161ed35217f0b03b111b42faaab8b200fc989ff971468b611c55e4c8af9adbc439aab
6
+ metadata.gz: 34876ec58287b76c98dd87931f0237361e148417919eac79e4a972439057fe93244c126a9ef631dd6551584f2b6482ac885adccf7ff384261f07e9d20e98cc0b
7
+ data.tar.gz: 31c5dfda655753188e3e923ed6d46e0f9744076b99b48a1ec0bee18a4fb83b1ef03e3f087902a72a679ac3576707401942461b4b0e6ad38253a0279d18765771
@@ -0,0 +1,14 @@
1
+ module Litestream
2
+ class ApplicationController < ActionController::Base
3
+ protect_from_forgery with: :exception
4
+ around_action :force_english_locale!
5
+
6
+ http_basic_authenticate_with name: Litestream.username, password: Litestream.password if Litestream.password
7
+
8
+ private
9
+
10
+ def force_english_locale!(&action)
11
+ I18n.with_locale(:en, &action)
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,9 @@
1
+ module Litestream
2
+ class ProcessesController < ApplicationController
3
+ # GET /process
4
+ def show
5
+ @process = Litestream.replicate_process
6
+ @databases = Litestream.databases
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,17 @@
1
+ module Litestream
2
+ class RestorationsController < ApplicationController
3
+ # POST /restorations
4
+ def create
5
+ database = params[:database].remove("[ROOT]/")
6
+ dir, file = File.split(database)
7
+ ext = File.extname(file)
8
+ base = File.basename(file, ext)
9
+ now = Time.now.utc.strftime("%Y%m%d%H%M%S")
10
+ backup = File.join(dir, "#{base}-#{now}#{ext}")
11
+
12
+ Litestream::Commands.restore(database, async: false, **{"-o" => backup})
13
+
14
+ redirect_to root_path, notice: "Restored to <code>#{backup}</code>."
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,804 @@
1
+ <style>
2
+ /*
3
+ ! tailwindcss v3.4.3 | MIT License | https://tailwindcss.com
4
+ */
5
+ /*
6
+ 1. Prevent padding and border from affecting element width. (https://github.com/mozdevs/cssremedy/issues/4)
7
+ 2. Allow adding a border to an element by just adding a border-width. (https://github.com/tailwindcss/tailwindcss/pull/116)
8
+ */
9
+ *,
10
+ ::before,
11
+ ::after {
12
+ box-sizing: border-box;
13
+ /* 1 */
14
+ border-width: 0;
15
+ /* 2 */
16
+ border-style: solid;
17
+ /* 2 */
18
+ border-color: #e5e7eb;
19
+ /* 2 */
20
+ }
21
+ ::before,
22
+ ::after {
23
+ --tw-content: '';
24
+ }
25
+ /*
26
+ 1. Use a consistent sensible line-height in all browsers.
27
+ 2. Prevent adjustments of font size after orientation changes in iOS.
28
+ 3. Use a more readable tab size.
29
+ 4. Use the user's configured `sans` font-family by default.
30
+ 5. Use the user's configured `sans` font-feature-settings by default.
31
+ 6. Use the user's configured `sans` font-variation-settings by default.
32
+ 7. Disable tap highlights on iOS
33
+ */
34
+ html,
35
+ :host {
36
+ line-height: 1.5;
37
+ /* 1 */
38
+ -webkit-text-size-adjust: 100%;
39
+ /* 2 */
40
+ -moz-tab-size: 4;
41
+ /* 3 */
42
+ tab-size: 4;
43
+ /* 3 */
44
+ font-family: ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
45
+ /* 4 */
46
+ font-feature-settings: normal;
47
+ /* 5 */
48
+ font-variation-settings: normal;
49
+ /* 6 */
50
+ -webkit-tap-highlight-color: transparent;
51
+ /* 7 */
52
+ }
53
+ /*
54
+ 1. Remove the margin in all browsers.
55
+ 2. Inherit line-height from `html` so users can set them as a class directly on the `html` element.
56
+ */
57
+ body {
58
+ margin: 0;
59
+ /* 1 */
60
+ line-height: inherit;
61
+ /* 2 */
62
+ }
63
+ /*
64
+ 1. Add the correct height in Firefox.
65
+ 2. Correct the inheritance of border color in Firefox. (https://bugzilla.mozilla.org/show_bug.cgi?id=190655)
66
+ 3. Ensure horizontal rules are visible by default.
67
+ */
68
+ hr {
69
+ height: 0;
70
+ /* 1 */
71
+ color: inherit;
72
+ /* 2 */
73
+ border-top-width: 1px;
74
+ /* 3 */
75
+ }
76
+ /*
77
+ Add the correct text decoration in Chrome, Edge, and Safari.
78
+ */
79
+ abbr:where([title]) {
80
+ text-decoration: underline dotted;
81
+ }
82
+ /*
83
+ Remove the default font size and weight for headings.
84
+ */
85
+ h1,
86
+ h2,
87
+ h3,
88
+ h4,
89
+ h5,
90
+ h6 {
91
+ font-size: inherit;
92
+ font-weight: inherit;
93
+ }
94
+ /*
95
+ Reset links to optimize for opt-in styling instead of opt-out.
96
+ */
97
+ a {
98
+ color: inherit;
99
+ text-decoration: inherit;
100
+ }
101
+ /*
102
+ Add the correct font weight in Edge and Safari.
103
+ */
104
+ b,
105
+ strong {
106
+ font-weight: bolder;
107
+ }
108
+ /*
109
+ 1. Use the user's configured `mono` font-family by default.
110
+ 2. Use the user's configured `mono` font-feature-settings by default.
111
+ 3. Use the user's configured `mono` font-variation-settings by default.
112
+ 4. Correct the odd `em` font sizing in all browsers.
113
+ */
114
+ code,
115
+ kbd,
116
+ samp,
117
+ pre {
118
+ font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;
119
+ /* 1 */
120
+ font-feature-settings: normal;
121
+ /* 2 */
122
+ font-variation-settings: normal;
123
+ /* 3 */
124
+ font-size: 1em;
125
+ /* 4 */
126
+ }
127
+ /*
128
+ Add the correct font size in all browsers.
129
+ */
130
+ small {
131
+ font-size: 80%;
132
+ }
133
+ /*
134
+ Prevent `sub` and `sup` elements from affecting the line height in all browsers.
135
+ */
136
+ sub,
137
+ sup {
138
+ font-size: 75%;
139
+ line-height: 0;
140
+ position: relative;
141
+ vertical-align: baseline;
142
+ }
143
+ sub {
144
+ bottom: -0.25em;
145
+ }
146
+ sup {
147
+ top: -0.5em;
148
+ }
149
+ /*
150
+ 1. Remove text indentation from table contents in Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=999088, https://bugs.webkit.org/show_bug.cgi?id=201297)
151
+ 2. Correct table border color inheritance in all Chrome and Safari. (https://bugs.chromium.org/p/chromium/issues/detail?id=935729, https://bugs.webkit.org/show_bug.cgi?id=195016)
152
+ 3. Remove gaps between table borders by default.
153
+ */
154
+ table {
155
+ text-indent: 0;
156
+ /* 1 */
157
+ border-color: inherit;
158
+ /* 2 */
159
+ border-collapse: collapse;
160
+ /* 3 */
161
+ }
162
+ /*
163
+ 1. Change the font styles in all browsers.
164
+ 2. Remove the margin in Firefox and Safari.
165
+ 3. Remove default padding in all browsers.
166
+ */
167
+ button,
168
+ input,
169
+ optgroup,
170
+ select,
171
+ textarea {
172
+ font-family: inherit;
173
+ /* 1 */
174
+ font-feature-settings: inherit;
175
+ /* 1 */
176
+ font-variation-settings: inherit;
177
+ /* 1 */
178
+ font-size: 100%;
179
+ /* 1 */
180
+ font-weight: inherit;
181
+ /* 1 */
182
+ line-height: inherit;
183
+ /* 1 */
184
+ letter-spacing: inherit;
185
+ /* 1 */
186
+ color: inherit;
187
+ /* 1 */
188
+ margin: 0;
189
+ /* 2 */
190
+ padding: 0;
191
+ /* 3 */
192
+ }
193
+ /*
194
+ Remove the inheritance of text transform in Edge and Firefox.
195
+ */
196
+ button,
197
+ select {
198
+ text-transform: none;
199
+ }
200
+ /*
201
+ 1. Correct the inability to style clickable types in iOS and Safari.
202
+ 2. Remove default button styles.
203
+ */
204
+ button,
205
+ input:where([type='button']),
206
+ input:where([type='reset']),
207
+ input:where([type='submit']) {
208
+ -webkit-appearance: button;
209
+ /* 1 */
210
+ background-color: transparent;
211
+ /* 2 */
212
+ background-image: none;
213
+ /* 2 */
214
+ }
215
+ /*
216
+ Use the modern Firefox focus style for all focusable elements.
217
+ */
218
+ :-moz-focusring {
219
+ outline: auto;
220
+ }
221
+ /*
222
+ Remove the additional `:invalid` styles in Firefox. (https://github.com/mozilla/gecko-dev/blob/2f9eacd9d3d995c937b4251a5557d95d494c9be1/layout/style/res/forms.css#L728-L737)
223
+ */
224
+ :-moz-ui-invalid {
225
+ box-shadow: none;
226
+ }
227
+ /*
228
+ Add the correct vertical alignment in Chrome and Firefox.
229
+ */
230
+ progress {
231
+ vertical-align: baseline;
232
+ }
233
+ /*
234
+ Correct the cursor style of increment and decrement buttons in Safari.
235
+ */
236
+ ::-webkit-inner-spin-button,
237
+ ::-webkit-outer-spin-button {
238
+ height: auto;
239
+ }
240
+ /*
241
+ 1. Correct the odd appearance in Chrome and Safari.
242
+ 2. Correct the outline style in Safari.
243
+ */
244
+ [type='search'] {
245
+ -webkit-appearance: textfield;
246
+ /* 1 */
247
+ outline-offset: -2px;
248
+ /* 2 */
249
+ }
250
+ /*
251
+ Remove the inner padding in Chrome and Safari on macOS.
252
+ */
253
+ ::-webkit-search-decoration {
254
+ -webkit-appearance: none;
255
+ }
256
+ /*
257
+ 1. Correct the inability to style clickable types in iOS and Safari.
258
+ 2. Change font properties to `inherit` in Safari.
259
+ */
260
+ ::-webkit-file-upload-button {
261
+ -webkit-appearance: button;
262
+ /* 1 */
263
+ font: inherit;
264
+ /* 2 */
265
+ }
266
+ /*
267
+ Add the correct display in Chrome and Safari.
268
+ */
269
+ summary {
270
+ display: list-item;
271
+ }
272
+ /*
273
+ Removes the default spacing and border for appropriate elements.
274
+ */
275
+ blockquote,
276
+ dl,
277
+ dd,
278
+ h1,
279
+ h2,
280
+ h3,
281
+ h4,
282
+ h5,
283
+ h6,
284
+ hr,
285
+ figure,
286
+ p,
287
+ pre {
288
+ margin: 0;
289
+ }
290
+ fieldset {
291
+ margin: 0;
292
+ padding: 0;
293
+ }
294
+ legend {
295
+ padding: 0;
296
+ }
297
+ ol,
298
+ ul,
299
+ menu {
300
+ list-style: none;
301
+ margin: 0;
302
+ padding: 0;
303
+ }
304
+ /*
305
+ Reset default styling for dialogs.
306
+ */
307
+ dialog {
308
+ padding: 0;
309
+ }
310
+ /*
311
+ Prevent resizing textareas horizontally by default.
312
+ */
313
+ textarea {
314
+ resize: vertical;
315
+ }
316
+ /*
317
+ 1. Reset the default placeholder opacity in Firefox. (https://github.com/tailwindlabs/tailwindcss/issues/3300)
318
+ 2. Set the default placeholder color to the user's configured gray 400 color.
319
+ */
320
+ input::placeholder,
321
+ textarea::placeholder {
322
+ opacity: 1;
323
+ /* 1 */
324
+ color: #9ca3af;
325
+ /* 2 */
326
+ }
327
+ /*
328
+ Set the default cursor for buttons.
329
+ */
330
+ button,
331
+ [role="button"] {
332
+ cursor: pointer;
333
+ }
334
+ /*
335
+ Make sure disabled buttons don't get the pointer cursor.
336
+ */
337
+ :disabled {
338
+ cursor: default;
339
+ }
340
+ /*
341
+ 1. Make replaced elements `display: block` by default. (https://github.com/mozdevs/cssremedy/issues/14)
342
+ 2. Add `vertical-align: middle` to align replaced elements more sensibly by default. (https://github.com/jensimmons/cssremedy/issues/14#issuecomment-634934210)
343
+ This can trigger a poorly considered lint error in some tools but is included by design.
344
+ */
345
+ img,
346
+ svg,
347
+ video,
348
+ canvas,
349
+ audio,
350
+ iframe,
351
+ embed,
352
+ object {
353
+ display: block;
354
+ /* 1 */
355
+ vertical-align: middle;
356
+ /* 2 */
357
+ }
358
+ /*
359
+ Constrain images and videos to the parent width and preserve their intrinsic aspect ratio. (https://github.com/mozdevs/cssremedy/issues/14)
360
+ */
361
+ img,
362
+ video {
363
+ max-width: 100%;
364
+ height: auto;
365
+ }
366
+ /* Make elements with the HTML hidden attribute stay hidden by default */
367
+ [hidden] {
368
+ display: none;
369
+ }
370
+ *, ::before, ::after {
371
+ --tw-border-spacing-x: 0;
372
+ --tw-border-spacing-y: 0;
373
+ --tw-translate-x: 0;
374
+ --tw-translate-y: 0;
375
+ --tw-rotate: 0;
376
+ --tw-skew-x: 0;
377
+ --tw-skew-y: 0;
378
+ --tw-scale-x: 1;
379
+ --tw-scale-y: 1;
380
+ --tw-pan-x: ;
381
+ --tw-pan-y: ;
382
+ --tw-pinch-zoom: ;
383
+ --tw-scroll-snap-strictness: proximity;
384
+ --tw-gradient-from-position: ;
385
+ --tw-gradient-via-position: ;
386
+ --tw-gradient-to-position: ;
387
+ --tw-ordinal: ;
388
+ --tw-slashed-zero: ;
389
+ --tw-numeric-figure: ;
390
+ --tw-numeric-spacing: ;
391
+ --tw-numeric-fraction: ;
392
+ --tw-ring-inset: ;
393
+ --tw-ring-offset-width: 0px;
394
+ --tw-ring-offset-color: #fff;
395
+ --tw-ring-color: rgb(59 130 246 / 0.5);
396
+ --tw-ring-offset-shadow: 0 0 #0000;
397
+ --tw-ring-shadow: 0 0 #0000;
398
+ --tw-shadow: 0 0 #0000;
399
+ --tw-shadow-colored: 0 0 #0000;
400
+ --tw-blur: ;
401
+ --tw-brightness: ;
402
+ --tw-contrast: ;
403
+ --tw-grayscale: ;
404
+ --tw-hue-rotate: ;
405
+ --tw-invert: ;
406
+ --tw-saturate: ;
407
+ --tw-sepia: ;
408
+ --tw-drop-shadow: ;
409
+ --tw-backdrop-blur: ;
410
+ --tw-backdrop-brightness: ;
411
+ --tw-backdrop-contrast: ;
412
+ --tw-backdrop-grayscale: ;
413
+ --tw-backdrop-hue-rotate: ;
414
+ --tw-backdrop-invert: ;
415
+ --tw-backdrop-opacity: ;
416
+ --tw-backdrop-saturate: ;
417
+ --tw-backdrop-sepia: ;
418
+ --tw-contain-size: ;
419
+ --tw-contain-layout: ;
420
+ --tw-contain-paint: ;
421
+ --tw-contain-style: ;
422
+ }
423
+ ::backdrop {
424
+ --tw-border-spacing-x: 0;
425
+ --tw-border-spacing-y: 0;
426
+ --tw-translate-x: 0;
427
+ --tw-translate-y: 0;
428
+ --tw-rotate: 0;
429
+ --tw-skew-x: 0;
430
+ --tw-skew-y: 0;
431
+ --tw-scale-x: 1;
432
+ --tw-scale-y: 1;
433
+ --tw-pan-x: ;
434
+ --tw-pan-y: ;
435
+ --tw-pinch-zoom: ;
436
+ --tw-scroll-snap-strictness: proximity;
437
+ --tw-gradient-from-position: ;
438
+ --tw-gradient-via-position: ;
439
+ --tw-gradient-to-position: ;
440
+ --tw-ordinal: ;
441
+ --tw-slashed-zero: ;
442
+ --tw-numeric-figure: ;
443
+ --tw-numeric-spacing: ;
444
+ --tw-numeric-fraction: ;
445
+ --tw-ring-inset: ;
446
+ --tw-ring-offset-width: 0px;
447
+ --tw-ring-offset-color: #fff;
448
+ --tw-ring-color: rgb(59 130 246 / 0.5);
449
+ --tw-ring-offset-shadow: 0 0 #0000;
450
+ --tw-ring-shadow: 0 0 #0000;
451
+ --tw-shadow: 0 0 #0000;
452
+ --tw-shadow-colored: 0 0 #0000;
453
+ --tw-blur: ;
454
+ --tw-brightness: ;
455
+ --tw-contrast: ;
456
+ --tw-grayscale: ;
457
+ --tw-hue-rotate: ;
458
+ --tw-invert: ;
459
+ --tw-saturate: ;
460
+ --tw-sepia: ;
461
+ --tw-drop-shadow: ;
462
+ --tw-backdrop-blur: ;
463
+ --tw-backdrop-brightness: ;
464
+ --tw-backdrop-contrast: ;
465
+ --tw-backdrop-grayscale: ;
466
+ --tw-backdrop-hue-rotate: ;
467
+ --tw-backdrop-invert: ;
468
+ --tw-backdrop-opacity: ;
469
+ --tw-backdrop-saturate: ;
470
+ --tw-backdrop-sepia: ;
471
+ --tw-contain-size: ;
472
+ --tw-contain-layout: ;
473
+ --tw-contain-paint: ;
474
+ --tw-contain-style: ;
475
+ }
476
+ .container {
477
+ width: 100%;
478
+ }
479
+ @media (min-width: 640px) {
480
+ .container {
481
+ max-width: 640px;
482
+ }
483
+ }
484
+ @media (min-width: 768px) {
485
+ .container {
486
+ max-width: 768px;
487
+ }
488
+ }
489
+ @media (min-width: 1024px) {
490
+ .container {
491
+ max-width: 1024px;
492
+ }
493
+ }
494
+ @media (min-width: 1280px) {
495
+ .container {
496
+ max-width: 1280px;
497
+ }
498
+ }
499
+ @media (min-width: 1536px) {
500
+ .container {
501
+ max-width: 1536px;
502
+ }
503
+ }
504
+ .fixed {
505
+ position: fixed;
506
+ }
507
+ .left-0 {
508
+ left: 0px;
509
+ }
510
+ .right-0 {
511
+ right: 0px;
512
+ }
513
+ .top-0 {
514
+ top: 0px;
515
+ }
516
+ .col-span-2 {
517
+ grid-column: span 2 / span 2;
518
+ }
519
+ .mx-auto {
520
+ margin-left: auto;
521
+ margin-right: auto;
522
+ }
523
+ .mb-3 {
524
+ margin-bottom: 0.75rem;
525
+ }
526
+ .ml-2 {
527
+ margin-left: 0.5rem;
528
+ }
529
+ .ml-4 {
530
+ margin-left: 1rem;
531
+ }
532
+ .ml-7 {
533
+ margin-left: 1.75rem;
534
+ }
535
+ .mt-24 {
536
+ margin-top: 6rem;
537
+ }
538
+ .mt-4 {
539
+ margin-top: 1rem;
540
+ }
541
+ .flex {
542
+ display: flex;
543
+ }
544
+ .inline-flex {
545
+ display: inline-flex;
546
+ }
547
+ .inline-block {
548
+ display: inline-block;
549
+ }
550
+ .table {
551
+ display: table;
552
+ }
553
+ .grid {
554
+ display: grid;
555
+ }
556
+ .h-full {
557
+ height: 100%;
558
+ }
559
+ .min-w-full {
560
+ min-width: 100%;
561
+ }
562
+ .max-w-4xl {
563
+ max-width: 56rem;
564
+ }
565
+ .grow {
566
+ flex-grow: 1;
567
+ }
568
+ .cursor-help {
569
+ cursor: help;
570
+ }
571
+ .cursor-pointer {
572
+ cursor: pointer;
573
+ }
574
+ .list-outside {
575
+ list-style-position: outside;
576
+ }
577
+ .list-\[square\] {
578
+ list-style-type: square;
579
+ }
580
+ .grid-cols-\[fit-content\(100\%\)_1fr\] {
581
+ grid-template-columns: fit-content(100%) 1fr;
582
+ }
583
+ .flex-col {
584
+ flex-direction: column;
585
+ }
586
+ .items-center {
587
+ align-items: center;
588
+ }
589
+ .items-baseline {
590
+ align-items: baseline;
591
+ }
592
+ .justify-between {
593
+ justify-content: space-between;
594
+ }
595
+ .gap-2 {
596
+ gap: 0.5rem;
597
+ }
598
+ .gap-x-4 {
599
+ column-gap: 1rem;
600
+ }
601
+ .space-y-6 > :not([hidden]) ~ :not([hidden]) {
602
+ --tw-space-y-reverse: 0;
603
+ margin-top: calc(1.5rem * calc(1 - var(--tw-space-y-reverse)));
604
+ margin-bottom: calc(1.5rem * var(--tw-space-y-reverse));
605
+ }
606
+ .divide-y > :not([hidden]) ~ :not([hidden]) {
607
+ --tw-divide-y-reverse: 0;
608
+ border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
609
+ border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
610
+ }
611
+ .divide-gray-300 > :not([hidden]) ~ :not([hidden]) {
612
+ --tw-divide-opacity: 1;
613
+ border-color: rgb(209 213 219 / var(--tw-divide-opacity));
614
+ }
615
+ .whitespace-nowrap {
616
+ white-space: nowrap;
617
+ }
618
+ .rounded {
619
+ border-radius: 0.25rem;
620
+ }
621
+ .rounded-full {
622
+ border-radius: 9999px;
623
+ }
624
+ .rounded-md {
625
+ border-radius: 0.375rem;
626
+ }
627
+ .rounded-lg {
628
+ border-radius: 0.5rem;
629
+ }
630
+ .border-b {
631
+ border-bottom-width: 1px;
632
+ }
633
+ .border-t {
634
+ border-top-width: 1px;
635
+ }
636
+ .bg-green-50 {
637
+ --tw-bg-opacity: 1;
638
+ background-color: rgb(240 253 244 / var(--tw-bg-opacity));
639
+ }
640
+ .bg-red-50 {
641
+ --tw-bg-opacity: 1;
642
+ background-color: rgb(254 242 242 / var(--tw-bg-opacity));
643
+ }
644
+ .bg-green-100 {
645
+ --tw-bg-opacity: 1;
646
+ background-color: rgb(220 252 231 / var(--tw-bg-opacity));
647
+ }
648
+ .bg-red-100 {
649
+ --tw-bg-opacity: 1;
650
+ background-color: rgb(254 226 226 / var(--tw-bg-opacity));
651
+ }
652
+ .bg-yellow-100 {
653
+ --tw-bg-opacity: 1;
654
+ background-color: rgb(254 249 195 / var(--tw-bg-opacity));
655
+ }
656
+ .bg-slate-800 {
657
+ --tw-bg-opacity: 1;
658
+ background-color: rgb(30 41 59 / var(--tw-bg-opacity));
659
+ }
660
+ .bg-white {
661
+ --tw-bg-opacity: 1;
662
+ background-color: rgb(255 255 255 / var(--tw-bg-opacity));
663
+ }
664
+ .p-2 {
665
+ padding: 0.5rem;
666
+ }
667
+ .px-2 {
668
+ padding-left: 0.5rem;
669
+ padding-right: 0.5rem;
670
+ }
671
+ .px-2\.5 {
672
+ padding-left: 0.625rem;
673
+ padding-right: 0.625rem;
674
+ }
675
+ .px-3 {
676
+ padding-left: 0.75rem;
677
+ padding-right: 0.75rem;
678
+ }
679
+ .py-1 {
680
+ padding-top: 0.25rem;
681
+ padding-bottom: 0.25rem;
682
+ }
683
+ .py-1\.5 {
684
+ padding-top: 0.375rem;
685
+ padding-bottom: 0.375rem;
686
+ }
687
+ .py-2 {
688
+ padding-top: 0.5rem;
689
+ padding-bottom: 0.5rem;
690
+ }
691
+ .py-4 {
692
+ padding-top: 1rem;
693
+ padding-bottom: 1rem;
694
+ }
695
+ .text-left {
696
+ text-align: left;
697
+ }
698
+ .text-center {
699
+ text-align: center;
700
+ }
701
+ .text-right {
702
+ text-align: right;
703
+ }
704
+ .align-top {
705
+ vertical-align: top;
706
+ }
707
+ .text-2xl {
708
+ font-size: 1.5rem;
709
+ line-height: 2rem;
710
+ }
711
+ .text-base {
712
+ font-size: 1rem;
713
+ line-height: 1.5rem;
714
+ }
715
+ .text-lg {
716
+ font-size: 1.125rem;
717
+ line-height: 1.75rem;
718
+ }
719
+ .text-sm {
720
+ font-size: 0.875rem;
721
+ line-height: 1.25rem;
722
+ }
723
+ .font-medium {
724
+ font-weight: 500;
725
+ }
726
+ .font-bold {
727
+ font-weight: 700;
728
+ }
729
+ .font-semibold {
730
+ font-weight: 600;
731
+ }
732
+ .text-green-500 {
733
+ --tw-text-opacity: 1;
734
+ color: rgb(34 197 94 / var(--tw-text-opacity));
735
+ }
736
+ .text-red-500 {
737
+ --tw-text-opacity: 1;
738
+ color: rgb(239 68 68 / var(--tw-text-opacity));
739
+ }
740
+ .text-blue-500 {
741
+ --tw-text-opacity: 1;
742
+ color: rgb(59 130 246 / var(--tw-text-opacity));
743
+ }
744
+ .text-gray-900 {
745
+ --tw-text-opacity: 1;
746
+ color: rgb(17 24 39 / var(--tw-text-opacity));
747
+ }
748
+ .text-green-800 {
749
+ --tw-text-opacity: 1;
750
+ color: rgb(22 101 52 / var(--tw-text-opacity));
751
+ }
752
+ .text-red-800 {
753
+ --tw-text-opacity: 1;
754
+ color: rgb(153 27 27 / var(--tw-text-opacity));
755
+ }
756
+ .text-yellow-800 {
757
+ --tw-text-opacity: 1;
758
+ color: rgb(133 77 14 / var(--tw-text-opacity));
759
+ }
760
+ .text-white {
761
+ --tw-text-opacity: 1;
762
+ color: rgb(255 255 255 / var(--tw-text-opacity));
763
+ }
764
+ .underline {
765
+ text-decoration-line: underline;
766
+ }
767
+ .decoration-blue-500 {
768
+ text-decoration-color: #3b82f6;
769
+ }
770
+ .decoration-gray-500 {
771
+ text-decoration-color: #6b7280;
772
+ }
773
+ .decoration-dashed {
774
+ text-decoration-style: dashed;
775
+ }
776
+ .shadow-sm {
777
+ --tw-shadow: 0 1px 2px 0 rgb(0 0 0 / 0.05);
778
+ --tw-shadow-colored: 0 1px 2px 0 var(--tw-shadow-color);
779
+ box-shadow: var(--tw-ring-offset-shadow, 0 0 #0000), var(--tw-ring-shadow, 0 0 #0000), var(--tw-shadow);
780
+ }
781
+ html, body {
782
+ height: 100%;
783
+ }
784
+ body {
785
+ display: flex;
786
+ height: 100%;
787
+ flex-direction: column;
788
+ }
789
+ .even\:bg-gray-50:nth-child(even) {
790
+ --tw-bg-opacity: 1;
791
+ background-color: rgb(249 250 251 / var(--tw-bg-opacity));
792
+ }
793
+ .hover\:bg-gray-50:hover {
794
+ --tw-bg-opacity: 1;
795
+ background-color: rgb(249 250 251 / var(--tw-bg-opacity));
796
+ }
797
+ .hover\:bg-slate-700:hover {
798
+ --tw-bg-opacity: 1;
799
+ background-color: rgb(51 65 85 / var(--tw-bg-opacity));
800
+ }
801
+ .hover\:underline:hover {
802
+ text-decoration-line: underline;
803
+ }
804
+ </style>
@@ -0,0 +1,56 @@
1
+ <!DOCTYPE html>
2
+ <html class="h-full">
3
+ <head>
4
+ <title>Litestream</title>
5
+ <%= csrf_meta_tags %>
6
+ <%= csp_meta_tag %>
7
+
8
+ <%= render "layouts/litestream/style" %>
9
+ </head>
10
+ <body class="h-full flex flex-col">
11
+ <main class="container mx-auto max-w-4xl mt-4 px-2 grow">
12
+ <%= content_for?(:content) ? yield(:content) : yield %>
13
+ </main>
14
+
15
+ <footer class="container mx-auto mt-24 flex items-center justify-between border-t px-2 py-4 text-base">
16
+ <p>
17
+ <code><strong>Litestream</strong></code>&nbsp;&nbsp;|&nbsp;
18
+ Made by <a href="https://twitter.com/fractaledmind" class="text-blue-500 hover:underline decoration-blue-500">@fractaledmind</a> and <a href="https://github.com/fractaledmind/litestream/graphs/contributors" class="text-blue-500 hover:underline decoration-blue-500">friends</a>! Want to help? It's <a href="https://github.com/fractaledmind/litestream" class="text-blue-500 hover:underline decoration-blue-500">open source</a>!
19
+ </p>
20
+ </footer>
21
+
22
+ <div class="fixed top-0 left-0 right-0 text-center py-2">
23
+ <% if notice.present? %>
24
+ <p id="notice"
25
+ class="py-2 px-3 bg-green-50 text-green-500 font-medium rounded-lg inline-block"
26
+ data-controller="fade">
27
+ <%= notice.html_safe %>
28
+ </p>
29
+ <% end %>
30
+
31
+ <% if alert.present? %>
32
+ <p id="alert"
33
+ class="py-2 px-3 bg-red-50 text-red-500 font-medium rounded-lg inline-block"
34
+ data-controller="fade">
35
+ <%= alert.html_safe %>
36
+ </p>
37
+ <% end %>
38
+ </div>
39
+
40
+ <script nonce="<%= content_security_policy_nonce %>">
41
+ function fadeOut(element) {
42
+ element.classList.add('transition-opacity')
43
+ setTimeout(
44
+ () => {
45
+ element.classList.add('opacity-0')
46
+ element.remove()
47
+ },
48
+ 5000
49
+ )
50
+ }
51
+ document.querySelectorAll('[data-controller="fade"]').forEach(element => {
52
+ fadeOut(element);
53
+ });
54
+ </script>
55
+ </body>
56
+ </html>
@@ -0,0 +1,121 @@
1
+ <section id="process_<%= @process[:pid] %>" class="space-y-6">
2
+ <div class="flex items-center justify-between">
3
+ <h1 class="flex items-baseline gap-2 text-2xl font-bold">
4
+ Litestream
5
+
6
+ <% if @process[:status] == "sleeping" %>
7
+ <small class="inline-flex rounded-full px-2 text-sm font-semibold bg-yellow-100 text-yellow-800">
8
+ <%= @process[:status] %>
9
+ </small>
10
+ <% elsif @process[:status] %>
11
+ <small class="inline-flex rounded-full px-2 text-sm font-semibold bg-green-100 text-green-800">
12
+ <%= @process[:status] %>
13
+ </small>
14
+ <% else %>
15
+ <small class="inline-flex rounded-full px-2 text-sm font-semibold bg-red-100 text-red-800">
16
+ not running
17
+ </small>
18
+ <% end %>
19
+ </h1>
20
+
21
+ <% if @process[:status] %>
22
+ <small class="text-base">
23
+ #<code><%= @process[:pid] %></code>
24
+ </small>
25
+ <% end %>
26
+ </div>
27
+
28
+ <% if @process[:status] %>
29
+ <dl class="grid grid-cols-[fit-content(100%)_1fr] gap-x-4">
30
+ <dt class="font-bold">Started at</dt>
31
+ <dd class="">
32
+ <abbr title="<%= @process[:started] %>" class="underline decoration-dashed decoration-gray-500 cursor-help">
33
+ <time datetime="<%= @process[:started] %>"><%= @process[:started].to_formatted_s(:db) %></time>
34
+ </abbr>
35
+ </dd>
36
+ </dl>
37
+ <% end %>
38
+ </section>
39
+ <br>
40
+ <br>
41
+
42
+ <section id="databases" class="">
43
+ <div class="mb-3 flex items-center justify-between border-b">
44
+ <h2 class="text-2xl font-bold">Databases</h2>
45
+ <p class="text-right">Total: <strong><%= @databases.size %></strong></p>
46
+ </div>
47
+
48
+ <ul class="list-[square] list-outside ml-4">
49
+ <% @databases.each do |database| %>
50
+ <li>
51
+ <div class="flex items-center justify-between">
52
+ <h2 class="text-lg font-bold">
53
+ <code><%= database['path'] %></code>
54
+ </h2>
55
+ <%= button_to "Restore", restorations_path, class: "rounded-md bg-slate-800 px-2.5 py-1.5 text-sm font-semibold text-white shadow-sm hover:bg-slate-700", params: { database: database['path'] } %>
56
+ </div>
57
+
58
+ <br />
59
+ <section id="generations" class="ml-6">
60
+ <% database['generations'].each do |generation| %>
61
+ <details id="<%= generation['generation'] %>" open="open">
62
+ <summary class="cursor-pointer rounded p-2 hover:bg-gray-50">
63
+ <code><%= generation['generation'] %></code>
64
+ (<em><%= generation['lag'] %> lag</em>)
65
+ </summary>
66
+
67
+ <dl class="ml-7 grid grid-cols-[fit-content(100%)_1fr] gap-x-4">
68
+ <dt class="font-bold">Start</dt>
69
+ <dd class="">
70
+ <abbr title="<%= generation['start'] %>" class="underline decoration-dashed decoration-gray-500 cursor-help">
71
+ <time datetime="<%= generation['start'] %>"><%= DateTime.parse(generation['start']).to_formatted_s(:db) %></time>
72
+ </abbr>
73
+ </dd>
74
+
75
+ <dt class="font-bold">End</dt>
76
+ <dd class="">
77
+ <abbr title="<%= generation['end'] %>" class="underline decoration-dashed decoration-gray-500 cursor-help">
78
+ <time datetime="<%= generation['end'] %>"><%= DateTime.parse(generation['end']).to_formatted_s(:db) %></time>
79
+ </abbr>
80
+ </dd>
81
+
82
+ <div class="col-span-2">
83
+ <dt class="font-bold">Snapshots</dt>
84
+ <dd class="">
85
+ <table class="min-w-full divide-y divide-gray-300">
86
+ <thead>
87
+ <tr>
88
+ <th scope="col" class="whitespace-nowrap px-2 py-2 text-left text-sm font-semibold text-gray-900">Created at</th>
89
+ <th scope="col" class="whitespace-nowrap px-2 py-2 text-right text-sm font-semibold text-gray-900">Index</th>
90
+ <th scope="col" class="whitespace-nowrap px-2 py-2 text-right text-sm font-semibold text-gray-900">Size</th>
91
+ </tr>
92
+ </thead>
93
+
94
+ <tbody class="bg-white">
95
+ <% generation['snapshots'].each do |snapshot| %>
96
+ <tr class="align-top even:bg-gray-50">
97
+ <td scope="col" class="whitespace-nowrap px-2 py-2 text-sm text-gray-900">
98
+ <abbr title="<%= snapshot['created'] %>" class="underline decoration-dashed decoration-gray-500 cursor-help">
99
+ <time datetime="<%= snapshot['created'] %>"><%= DateTime.parse(snapshot['created']).to_formatted_s(:db) %></time>
100
+ </abbr>
101
+ </td>
102
+ <td scope="col" class="whitespace-nowrap px-2 py-2 text-sm text-gray-900 text-right">
103
+ <%= snapshot['index'] %>
104
+ </td>
105
+ <td scope="col" class="whitespace-nowrap px-2 py-2 text-sm text-gray-900 text-right">
106
+ <%= number_to_human_size snapshot['size'] %>
107
+ </td>
108
+ </tr>
109
+ <% end %>
110
+ </tbody>
111
+ </table>
112
+ </dd>
113
+ </div>
114
+ </dl>
115
+ </details>
116
+ <% end %>
117
+ </section>
118
+ </li>
119
+ <% end %>
120
+ </ul>
121
+ </section>
data/config/routes.rb ADDED
@@ -0,0 +1,6 @@
1
+ Litestream::Engine.routes.draw do
2
+ get "/" => "processes#show", :as => :root
3
+
4
+ resource :process, only: [:show], path: ""
5
+ resources :restorations, only: [:create]
6
+ end
@@ -1,3 +1,3 @@
1
1
  module Litestream
2
- VERSION = "0.10.3"
2
+ VERSION = "0.10.4"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: litestream
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.10.3
4
+ version: 0.10.4
5
5
  platform: arm64-darwin
6
6
  authors:
7
7
  - Stephen Margheim
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2024-06-10 00:00:00.000000000 Z
11
+ date: 2024-06-21 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: logfmt
@@ -92,6 +92,13 @@ files:
92
92
  - LICENSE-DEPENDENCIES
93
93
  - README.md
94
94
  - Rakefile
95
+ - app/controllers/litestream/application_controller.rb
96
+ - app/controllers/litestream/processes_controller.rb
97
+ - app/controllers/litestream/restorations_controller.rb
98
+ - app/views/layouts/litestream/_style.html
99
+ - app/views/layouts/litestream/application.html.erb
100
+ - app/views/litestream/processes/show.html.erb
101
+ - config/routes.rb
95
102
  - exe/arm64-darwin/litestream
96
103
  - exe/litestream
97
104
  - lib/litestream.rb