@silvery/examples 0.5.6 → 0.17.4

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 (112) hide show
  1. package/dist/UPNG-Cy7ViL8f.mjs +5074 -0
  2. package/dist/__vite-browser-external-2447137e-BML7CYau.mjs +4 -0
  3. package/dist/_banner-DLPxCqVy.mjs +44 -0
  4. package/dist/ansi-CCE2pVS0.mjs +16397 -0
  5. package/dist/apng-HhhBjRGt.mjs +68 -0
  6. package/dist/apng-mwUQbTTF.mjs +3 -0
  7. package/dist/apps/aichat/index.mjs +1299 -0
  8. package/dist/apps/app-todo.mjs +139 -0
  9. package/dist/apps/async-data.mjs +204 -0
  10. package/dist/apps/cli-wizard.mjs +339 -0
  11. package/dist/apps/clipboard.mjs +198 -0
  12. package/dist/apps/components.mjs +864 -0
  13. package/dist/apps/data-explorer.mjs +483 -0
  14. package/dist/apps/dev-tools.mjs +397 -0
  15. package/dist/apps/explorer.mjs +698 -0
  16. package/dist/apps/gallery.mjs +766 -0
  17. package/dist/apps/inline-bench.mjs +115 -0
  18. package/dist/apps/kanban.mjs +280 -0
  19. package/dist/apps/layout-ref.mjs +187 -0
  20. package/dist/apps/outline.mjs +203 -0
  21. package/dist/apps/paste-demo.mjs +189 -0
  22. package/dist/apps/scroll.mjs +86 -0
  23. package/dist/apps/search-filter.mjs +287 -0
  24. package/dist/apps/selection.mjs +355 -0
  25. package/dist/apps/spatial-focus-demo.mjs +388 -0
  26. package/dist/apps/task-list.mjs +258 -0
  27. package/dist/apps/terminal-caps-demo.mjs +315 -0
  28. package/dist/apps/terminal.mjs +872 -0
  29. package/dist/apps/text-selection-demo.mjs +254 -0
  30. package/dist/apps/textarea.mjs +178 -0
  31. package/dist/apps/theme.mjs +661 -0
  32. package/dist/apps/transform.mjs +215 -0
  33. package/dist/apps/virtual-10k.mjs +422 -0
  34. package/dist/assets/resvgjs.darwin-arm64-BtufyGW1.node +0 -0
  35. package/dist/backends-Bahh9mKN.mjs +1179 -0
  36. package/dist/backends-CCtCDQ94.mjs +3 -0
  37. package/dist/{cli.mjs → bin/cli.mjs} +21 -25
  38. package/dist/chunk-BSw8zbkd.mjs +37 -0
  39. package/dist/components/counter.mjs +48 -0
  40. package/dist/components/hello.mjs +31 -0
  41. package/dist/components/progress-bar.mjs +59 -0
  42. package/dist/components/select-list.mjs +85 -0
  43. package/dist/components/spinner.mjs +57 -0
  44. package/dist/components/text-input.mjs +62 -0
  45. package/dist/components/virtual-list.mjs +51 -0
  46. package/dist/flexily-zero-adapter-UB-ra8fR.mjs +3374 -0
  47. package/dist/gif-BZaqPPVX.mjs +3 -0
  48. package/dist/gif-BtnXuxLF.mjs +71 -0
  49. package/dist/gifenc-CLRW41dk.mjs +728 -0
  50. package/dist/jsx-runtime-dMs_8fNu.mjs +241 -0
  51. package/dist/key-mapping-5oYQdAQE.mjs +3 -0
  52. package/dist/key-mapping-D4LR1go6.mjs +130 -0
  53. package/dist/layout/dashboard.mjs +1204 -0
  54. package/dist/layout/live-resize.mjs +303 -0
  55. package/dist/layout/overflow.mjs +70 -0
  56. package/dist/layout/text-layout.mjs +335 -0
  57. package/dist/node-NuJ94BWl.mjs +1083 -0
  58. package/dist/plugins-D1KtkT4a.mjs +3057 -0
  59. package/dist/resvg-js-C_8Wps1F.mjs +201 -0
  60. package/dist/src-BTEVGpd9.mjs +23538 -0
  61. package/dist/src-CUUOuRH6.mjs +5322 -0
  62. package/dist/src-CzfRafCQ.mjs +814 -0
  63. package/dist/usingCtx-CsEf0xO3.mjs +57 -0
  64. package/dist/yoga-adapter-BVtQ5OJR.mjs +237 -0
  65. package/package.json +19 -14
  66. package/_banner.tsx +0 -60
  67. package/apps/aichat/components.tsx +0 -469
  68. package/apps/aichat/index.tsx +0 -220
  69. package/apps/aichat/script.ts +0 -460
  70. package/apps/aichat/state.ts +0 -325
  71. package/apps/aichat/types.ts +0 -19
  72. package/apps/app-todo.tsx +0 -201
  73. package/apps/async-data.tsx +0 -196
  74. package/apps/cli-wizard.tsx +0 -332
  75. package/apps/clipboard.tsx +0 -183
  76. package/apps/components.tsx +0 -658
  77. package/apps/data-explorer.tsx +0 -490
  78. package/apps/dev-tools.tsx +0 -395
  79. package/apps/explorer.tsx +0 -731
  80. package/apps/gallery.tsx +0 -653
  81. package/apps/inline-bench.tsx +0 -138
  82. package/apps/kanban.tsx +0 -265
  83. package/apps/layout-ref.tsx +0 -173
  84. package/apps/outline.tsx +0 -160
  85. package/apps/panes/index.tsx +0 -203
  86. package/apps/paste-demo.tsx +0 -185
  87. package/apps/scroll.tsx +0 -77
  88. package/apps/search-filter.tsx +0 -240
  89. package/apps/selection.tsx +0 -342
  90. package/apps/spatial-focus-demo.tsx +0 -368
  91. package/apps/task-list.tsx +0 -271
  92. package/apps/terminal-caps-demo.tsx +0 -334
  93. package/apps/terminal.tsx +0 -800
  94. package/apps/text-selection-demo.tsx +0 -189
  95. package/apps/textarea.tsx +0 -155
  96. package/apps/theme.tsx +0 -515
  97. package/apps/transform.tsx +0 -229
  98. package/apps/virtual-10k.tsx +0 -405
  99. package/apps/vterm-demo/index.tsx +0 -216
  100. package/components/counter.tsx +0 -45
  101. package/components/hello.tsx +0 -34
  102. package/components/progress-bar.tsx +0 -48
  103. package/components/select-list.tsx +0 -50
  104. package/components/spinner.tsx +0 -40
  105. package/components/text-input.tsx +0 -57
  106. package/components/virtual-list.tsx +0 -52
  107. package/dist/cli.d.mts +0 -1
  108. package/dist/cli.mjs.map +0 -1
  109. package/layout/dashboard.tsx +0 -953
  110. package/layout/live-resize.tsx +0 -282
  111. package/layout/overflow.tsx +0 -51
  112. package/layout/text-layout.tsx +0 -283
@@ -0,0 +1,397 @@
1
+ import { t as _usingCtx } from "../usingCtx-CsEf0xO3.mjs";
2
+ import { t as require_jsx_runtime } from "../jsx-runtime-dMs_8fNu.mjs";
3
+ import { t as ExampleBanner } from "../_banner-DLPxCqVy.mjs";
4
+ import { useCallback, useMemo, useState } from "react";
5
+ import { Box, Divider, ListView, Muted, Strong, Text, createTerm, render, useApp, useBoxRect, useInput } from "silvery";
6
+ //#region apps/dev-tools.tsx
7
+ /**
8
+ * Dev Tools — Log Viewer Example
9
+ *
10
+ * A live log viewer demonstrating:
11
+ * - ListView for efficient rendering of thousands of log entries
12
+ * - Keyboard shortcuts to add log entries at different severity levels
13
+ * - Color-coded severity levels (DEBUG, INFO, WARN, ERROR)
14
+ * - j/k navigation through log history
15
+ * - Auto-scroll to latest entry
16
+ *
17
+ * Usage: bun run examples/apps/dev-tools.tsx
18
+ *
19
+ * Controls:
20
+ * j/k or Up/Down - Navigate through log entries
21
+ * g/G - Jump to first/last entry
22
+ * d - Add DEBUG entry
23
+ * i - Add INFO entry
24
+ * w - Add WARN entry
25
+ * e - Add ERROR entry
26
+ * c - Clear all logs
27
+ * q or Esc - Quit
28
+ */
29
+ var import_jsx_runtime = require_jsx_runtime();
30
+ const meta = {
31
+ name: "Dev Tools",
32
+ description: "Log viewer with severity levels, ListView, and keyboard-driven log injection",
33
+ features: [
34
+ "ListView",
35
+ "useInput()",
36
+ "useBoxRect()",
37
+ "keyboard navigation"
38
+ ]
39
+ };
40
+ const SOURCES = [
41
+ "http",
42
+ "db",
43
+ "auth",
44
+ "cache",
45
+ "worker",
46
+ "api",
47
+ "scheduler",
48
+ "queue",
49
+ "metrics",
50
+ "ws"
51
+ ];
52
+ const LOG_TEMPLATES = {
53
+ DEBUG: [
54
+ "Cache miss for key user:session:{{id}}",
55
+ "Query plan: sequential scan on events ({{n}} rows)",
56
+ "WebSocket frame received: {{n}} bytes",
57
+ "GC pause: {{n}}ms (minor collection)",
58
+ "Connection pool stats: {{n}} active, {{n}} idle",
59
+ "Route matched: GET /api/v2/resources/{{id}}"
60
+ ],
61
+ INFO: [
62
+ "Request completed: 200 OK ({{n}}ms)",
63
+ "User {{id}} authenticated via OAuth",
64
+ "Background job processed: email_dispatch #{{id}}",
65
+ "Server listening on port {{n}}",
66
+ "Database migration applied: v{{n}}",
67
+ "Health check passed (latency: {{n}}ms)"
68
+ ],
69
+ WARN: [
70
+ "Slow query detected: {{n}}ms (threshold: 200ms)",
71
+ "Rate limit approaching: {{n}}/1000 requests",
72
+ "Memory usage: {{n}}% of allocated heap",
73
+ "Retry attempt {{n}}/3 for external API call",
74
+ "Certificate expires in {{n}} days",
75
+ "Connection pool near capacity: {{n}}/100"
76
+ ],
77
+ ERROR: [
78
+ "Unhandled exception in request handler: TypeError",
79
+ "Database connection refused: ECONNREFUSED",
80
+ "Authentication failed for user {{id}}: invalid token",
81
+ "Timeout after {{n}}ms waiting for upstream service",
82
+ "Disk usage critical: {{n}}% on /var/data",
83
+ "Failed to process message from queue: malformed payload"
84
+ ]
85
+ };
86
+ let nextLogId = 1;
87
+ function seededRandom(seed) {
88
+ let s = seed;
89
+ return () => {
90
+ s = s * 1664525 + 1013904223 & 2147483647;
91
+ return s / 2147483647;
92
+ };
93
+ }
94
+ function generateMessage(level, rng) {
95
+ const templates = LOG_TEMPLATES[level];
96
+ return templates[Math.floor(rng() * templates.length)].replace(/\{\{id\}\}/g, () => String(Math.floor(rng() * 99999))).replace(/\{\{n\}\}/g, () => String(Math.floor(rng() * 999)));
97
+ }
98
+ function createLogEntry(level, rng) {
99
+ return {
100
+ id: nextLogId++,
101
+ timestamp: /* @__PURE__ */ new Date(),
102
+ level,
103
+ source: SOURCES[Math.floor(rng() * SOURCES.length)],
104
+ message: generateMessage(level, rng)
105
+ };
106
+ }
107
+ function generateInitialLogs(count) {
108
+ const rng = seededRandom(42);
109
+ const levels = [
110
+ "DEBUG",
111
+ "INFO",
112
+ "INFO",
113
+ "INFO",
114
+ "WARN",
115
+ "ERROR"
116
+ ];
117
+ const entries = [];
118
+ const now = Date.now();
119
+ for (let i = 0; i < count; i++) {
120
+ const level = levels[Math.floor(rng() * levels.length)];
121
+ const entry = createLogEntry(level, rng);
122
+ entry.timestamp = /* @__PURE__ */ new Date(now - (count - i) * 1200);
123
+ entries.push(entry);
124
+ }
125
+ return entries;
126
+ }
127
+ const LEVEL_COLORS = {
128
+ DEBUG: "$muted",
129
+ INFO: "$primary",
130
+ WARN: "$warning",
131
+ ERROR: "$error"
132
+ };
133
+ const LEVEL_BADGES = {
134
+ DEBUG: "DBG",
135
+ INFO: "INF",
136
+ WARN: "WRN",
137
+ ERROR: "ERR"
138
+ };
139
+ function formatTime(date) {
140
+ return date.toLocaleTimeString("en-US", {
141
+ hour: "2-digit",
142
+ minute: "2-digit",
143
+ second: "2-digit",
144
+ hour12: false
145
+ });
146
+ }
147
+ function LogRow({ entry, isSelected }) {
148
+ const badge = LEVEL_BADGES[entry.level];
149
+ const color = LEVEL_COLORS[entry.level];
150
+ if (isSelected) return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
151
+ paddingX: 1,
152
+ backgroundColor: "$primary",
153
+ children: [
154
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
155
+ color: "$primary-fg",
156
+ children: [formatTime(entry.timestamp), " "]
157
+ }),
158
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
159
+ color: "$primary-fg",
160
+ bold: true,
161
+ children: badge
162
+ }),
163
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
164
+ color: "$primary-fg",
165
+ children: [
166
+ " [",
167
+ entry.source.padEnd(9),
168
+ "] "
169
+ ]
170
+ }),
171
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
172
+ color: "$primary-fg",
173
+ bold: true,
174
+ children: entry.message
175
+ })
176
+ ]
177
+ });
178
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
179
+ paddingX: 1,
180
+ children: [
181
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [formatTime(entry.timestamp), " "] }),
182
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Strong, {
183
+ color,
184
+ children: badge
185
+ }),
186
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: [
187
+ " [",
188
+ entry.source.padEnd(9),
189
+ "] "
190
+ ] }),
191
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, { children: entry.message })
192
+ ]
193
+ });
194
+ }
195
+ function LevelCounts({ entries }) {
196
+ const counts = useMemo(() => {
197
+ const c = {
198
+ DEBUG: 0,
199
+ INFO: 0,
200
+ WARN: 0,
201
+ ERROR: 0
202
+ };
203
+ for (const e of entries) c[e.level]++;
204
+ return c;
205
+ }, [entries]);
206
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
207
+ gap: 2,
208
+ children: [
209
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Strong, {
210
+ color: "$muted",
211
+ children: [
212
+ LEVEL_BADGES.DEBUG,
213
+ ":",
214
+ counts.DEBUG
215
+ ]
216
+ }),
217
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Strong, {
218
+ color: "$primary",
219
+ children: [
220
+ LEVEL_BADGES.INFO,
221
+ ":",
222
+ counts.INFO
223
+ ]
224
+ }),
225
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Strong, {
226
+ color: "$warning",
227
+ children: [
228
+ LEVEL_BADGES.WARN,
229
+ ":",
230
+ counts.WARN
231
+ ]
232
+ }),
233
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Strong, {
234
+ color: "$error",
235
+ children: [
236
+ LEVEL_BADGES.ERROR,
237
+ ":",
238
+ counts.ERROR
239
+ ]
240
+ })
241
+ ]
242
+ });
243
+ }
244
+ /** Inner component that reads the flex container's height via useBoxRect */
245
+ function LogListArea({ entries, cursor }) {
246
+ const { height } = useBoxRect();
247
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ListView, {
248
+ items: entries,
249
+ height,
250
+ estimateHeight: 1,
251
+ scrollTo: cursor,
252
+ overscan: 5,
253
+ renderItem: (entry, index) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogRow, {
254
+ entry,
255
+ isSelected: index === cursor
256
+ }, entry.id)
257
+ });
258
+ }
259
+ const INITIAL_COUNT = 200;
260
+ const rng = seededRandom(12345);
261
+ function DevTools() {
262
+ const { exit } = useApp();
263
+ const [entries, setEntries] = useState(() => generateInitialLogs(INITIAL_COUNT));
264
+ const [cursor, setCursor] = useState(INITIAL_COUNT - 1);
265
+ const [autoScroll, setAutoScroll] = useState(true);
266
+ const addEntry = useCallback((level) => {
267
+ const entry = createLogEntry(level, rng);
268
+ setEntries((prev) => [...prev, entry]);
269
+ if (autoScroll) setCursor((prev) => prev + 1);
270
+ }, [autoScroll]);
271
+ useInput(useCallback((input, key) => {
272
+ if (input === "q" || key.escape) {
273
+ exit();
274
+ return;
275
+ }
276
+ if (input === "j" || key.downArrow) {
277
+ setCursor((c) => Math.min(entries.length - 1, c + 1));
278
+ setAutoScroll(false);
279
+ return;
280
+ }
281
+ if (input === "k" || key.upArrow) {
282
+ setCursor((c) => Math.max(0, c - 1));
283
+ setAutoScroll(false);
284
+ return;
285
+ }
286
+ if (input === "g" || key.home) {
287
+ setCursor(0);
288
+ setAutoScroll(false);
289
+ return;
290
+ }
291
+ if (input === "G" || key.end) {
292
+ setCursor(entries.length - 1);
293
+ setAutoScroll(true);
294
+ return;
295
+ }
296
+ if (input === "d") {
297
+ addEntry("DEBUG");
298
+ return;
299
+ }
300
+ if (input === "i") {
301
+ addEntry("INFO");
302
+ return;
303
+ }
304
+ if (input === "w") {
305
+ addEntry("WARN");
306
+ return;
307
+ }
308
+ if (input === "e") {
309
+ addEntry("ERROR");
310
+ return;
311
+ }
312
+ if (input === "c") {
313
+ setEntries([]);
314
+ setCursor(0);
315
+ setAutoScroll(true);
316
+ return;
317
+ }
318
+ }, [
319
+ entries.length,
320
+ exit,
321
+ addEntry
322
+ ]));
323
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
324
+ flexDirection: "column",
325
+ flexGrow: 1,
326
+ padding: 1,
327
+ children: [
328
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
329
+ justifyContent: "space-between",
330
+ backgroundColor: "$surfacebg",
331
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
332
+ gap: 2,
333
+ children: [/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Text, {
334
+ bold: true,
335
+ color: "$primary",
336
+ children: ["▸", " Log Viewer"]
337
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LevelCounts, { entries })]
338
+ }), /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
339
+ gap: 1,
340
+ children: [
341
+ autoScroll && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Text, {
342
+ backgroundColor: "$success",
343
+ color: "$success-fg",
344
+ bold: true,
345
+ children: " LIVE "
346
+ }),
347
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Strong, {
348
+ color: "$primary",
349
+ children: cursor + 1
350
+ }),
351
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: ["/ ", entries.length] })
352
+ ]
353
+ })]
354
+ }),
355
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Box, {
356
+ paddingX: 1,
357
+ children: [
358
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: ["Time ", " "] }),
359
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: ["Lvl", " "] }),
360
+ /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(Muted, { children: ["[Source ]", " "] }),
361
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Muted, { children: "Message" })
362
+ ]
363
+ }),
364
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
365
+ paddingX: 1,
366
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Divider, {})
367
+ }),
368
+ /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Box, {
369
+ flexGrow: 1,
370
+ flexDirection: "column",
371
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(LogListArea, {
372
+ entries,
373
+ cursor
374
+ })
375
+ })
376
+ ]
377
+ });
378
+ }
379
+ async function main() {
380
+ try {
381
+ var _usingCtx$1 = _usingCtx();
382
+ const term = _usingCtx$1.u(createTerm());
383
+ const { waitUntilExit } = await render(/* @__PURE__ */ (0, import_jsx_runtime.jsx)(ExampleBanner, {
384
+ meta,
385
+ controls: "j/k navigate g/G start/end d/i/w/e add log c clear Esc/q quit",
386
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DevTools, {})
387
+ }), term);
388
+ await waitUntilExit();
389
+ } catch (_) {
390
+ _usingCtx$1.e = _;
391
+ } finally {
392
+ _usingCtx$1.d();
393
+ }
394
+ }
395
+ if (import.meta.main) await main();
396
+ //#endregion
397
+ export { DevTools, main, meta };