@electric-sql/pglite-repl 0.0.1-alpha.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.
package/dist/Repl.js ADDED
@@ -0,0 +1,726 @@
1
+ import './style.css';
2
+ import { jsxs, Fragment, jsx } from "react/jsx-runtime";
3
+ import { useState, useEffect, useRef, useCallback, useMemo } from "react";
4
+ import CodeMirror from "@uiw/react-codemirror";
5
+ import { defaultKeymap } from "@codemirror/commands";
6
+ import { keymap } from "@codemirror/view";
7
+ import { PostgreSQL, schemaCompletionSource, keywordCompletionSource } from "@codemirror/lang-sql";
8
+ import { LanguageSupport } from "@codemirror/language";
9
+ import { describe } from "psql-describe";
10
+ import { xcodeLight, xcodeDark } from "@uiw/codemirror-theme-xcode";
11
+ const describeCompletions = [
12
+ {
13
+ label: "\\d",
14
+ type: "function",
15
+ displayLabel: "\\d[S+] [ pattern ]",
16
+ detail: "PSQL Describe"
17
+ },
18
+ {
19
+ label: "\\da",
20
+ type: "function",
21
+ displayLabel: "\\da[S] [ pattern ]",
22
+ detail: "Lists aggregate functions"
23
+ },
24
+ {
25
+ label: "\\dA",
26
+ type: "function",
27
+ displayLabel: "\\dA[+] [ pattern ]",
28
+ detail: "Lists access methods"
29
+ },
30
+ {
31
+ label: "\\dAc",
32
+ type: "function",
33
+ displayLabel: "\\dAc[+] [access-method-pattern [input-type-pattern]]",
34
+ detail: "Lists operator classes"
35
+ },
36
+ {
37
+ label: "\\dAf",
38
+ type: "function",
39
+ displayLabel: "\\dAf[+] [access-method-pattern [input-type-pattern]]",
40
+ detail: "Lists operator families"
41
+ },
42
+ {
43
+ label: "\\dAo",
44
+ type: "function",
45
+ displayLabel: "\\dAo[+] [access-method-pattern [operator-family-pattern]]",
46
+ detail: "Lists operators associated with operator families"
47
+ },
48
+ {
49
+ label: "\\dAp",
50
+ type: "function",
51
+ displayLabel: "\\dAp[+] [access-method-pattern [operator-family-pattern]]",
52
+ detail: "Lists support functions associated with operator families"
53
+ },
54
+ {
55
+ label: "\\db",
56
+ type: "function",
57
+ displayLabel: "\\db[+] [ pattern ]",
58
+ detail: "Lists tablespaces"
59
+ },
60
+ {
61
+ label: "\\dc",
62
+ type: "function",
63
+ displayLabel: "\\dc[S+] [ pattern ]",
64
+ detail: "Lists conversions between character-set encodings"
65
+ },
66
+ {
67
+ label: "\\dconfig",
68
+ type: "function",
69
+ displayLabel: "\\dconfig[+] [ pattern ]",
70
+ detail: "Lists server configuration parameters and their values"
71
+ },
72
+ {
73
+ label: "\\dC",
74
+ type: "function",
75
+ displayLabel: "\\dC[+] [ pattern ]",
76
+ detail: "Lists type casts"
77
+ },
78
+ {
79
+ label: "\\dd",
80
+ type: "function",
81
+ displayLabel: "\\dd[S] [ pattern ]",
82
+ detail: "Shows the descriptions of objects of type constraint, operator class, operator family, rule, and trigger"
83
+ },
84
+ {
85
+ label: "\\dD",
86
+ type: "function",
87
+ displayLabel: "\\dD[S+] [ pattern ]",
88
+ detail: "Lists domains"
89
+ },
90
+ {
91
+ label: "\\ddp",
92
+ type: "function",
93
+ displayLabel: "\\ddp [ pattern ]",
94
+ detail: "Lists default access privilege settings"
95
+ },
96
+ {
97
+ label: "\\dE",
98
+ type: "function",
99
+ displayLabel: "\\dE[S+] [ pattern ]",
100
+ detail: "Lists foreign tables"
101
+ },
102
+ {
103
+ label: "\\di",
104
+ type: "function",
105
+ displayLabel: "\\di[S+] [ pattern ]",
106
+ detail: "Lists indexes"
107
+ },
108
+ {
109
+ label: "\\dm",
110
+ type: "function",
111
+ displayLabel: "\\dm[S+] [ pattern ]",
112
+ detail: "Lists materialized views"
113
+ },
114
+ {
115
+ label: "\\ds",
116
+ type: "function",
117
+ displayLabel: "\\ds[S+] [ pattern ]",
118
+ detail: "Lists sequences"
119
+ },
120
+ {
121
+ label: "\\dt",
122
+ type: "function",
123
+ displayLabel: "\\dt[S+] [ pattern ]",
124
+ detail: "Lists tables"
125
+ },
126
+ {
127
+ label: "\\dv",
128
+ type: "function",
129
+ displayLabel: "\\dv[S+] [ pattern ]",
130
+ detail: "Lists views"
131
+ },
132
+ {
133
+ label: "\\des",
134
+ type: "function",
135
+ displayLabel: "\\des[+] [ pattern ]",
136
+ detail: "Lists foreign servers"
137
+ },
138
+ {
139
+ label: "\\det",
140
+ type: "function",
141
+ displayLabel: "\\det[+] [ pattern ]",
142
+ detail: "Lists foreign tables"
143
+ },
144
+ {
145
+ label: "\\deu",
146
+ type: "function",
147
+ displayLabel: "\\deu[+] [ pattern ]",
148
+ detail: "Lists user mappings"
149
+ },
150
+ {
151
+ label: "\\dew",
152
+ type: "function",
153
+ displayLabel: "\\dew[+] [ pattern ]",
154
+ detail: "Lists foreign-data wrappers"
155
+ },
156
+ {
157
+ label: "\\df",
158
+ type: "function",
159
+ displayLabel: "\\df[anptwS+] [ pattern [ arg_pattern ... ] ]",
160
+ detail: "Lists functions"
161
+ },
162
+ {
163
+ label: "\\dF",
164
+ type: "function",
165
+ displayLabel: "\\dF[+] [ pattern ]",
166
+ detail: "Lists text search configurations"
167
+ },
168
+ {
169
+ label: "\\dFd",
170
+ type: "function",
171
+ displayLabel: "\\dFd[+] [ pattern ]",
172
+ detail: "Lists text search dictionaries"
173
+ },
174
+ {
175
+ label: "\\dFp",
176
+ type: "function",
177
+ displayLabel: "\\dFp[+] [ pattern ]",
178
+ detail: "Lists text search parsers"
179
+ },
180
+ {
181
+ label: "\\dFt",
182
+ type: "function",
183
+ displayLabel: "\\dFt[+] [ pattern ]",
184
+ detail: "Lists text search templates"
185
+ },
186
+ {
187
+ label: "\\dg",
188
+ type: "function",
189
+ displayLabel: "\\dg[S+] [ pattern ]",
190
+ detail: "Lists database roles"
191
+ },
192
+ {
193
+ label: "\\dl",
194
+ type: "function",
195
+ displayLabel: "\\dl[+] ",
196
+ detail: "List large objects"
197
+ },
198
+ {
199
+ label: "\\dL",
200
+ type: "function",
201
+ displayLabel: "\\dL[S+] [ pattern ]",
202
+ detail: "Lists procedural languages"
203
+ },
204
+ {
205
+ label: "\\dn",
206
+ type: "function",
207
+ displayLabel: "\\dn[S+] [ pattern ]",
208
+ detail: "Lists schemas"
209
+ },
210
+ {
211
+ label: "\\do",
212
+ type: "function",
213
+ displayLabel: "\\do[S+] [ pattern [ arg_pattern [ arg_pattern ] ] ]",
214
+ detail: "Lists operators with their operand and result types"
215
+ },
216
+ {
217
+ label: "\\dO",
218
+ type: "function",
219
+ displayLabel: "\\dO[S+] [ pattern ]",
220
+ detail: "Lists collations"
221
+ },
222
+ {
223
+ label: "\\dp",
224
+ type: "function",
225
+ displayLabel: "\\dp[S] [ pattern ]",
226
+ detail: "Lists tables, views and sequences with their associated access privileges"
227
+ },
228
+ {
229
+ label: "\\dP",
230
+ type: "function",
231
+ displayLabel: "\\dP[itn+] [ pattern ]",
232
+ detail: "Lists partitioned relations"
233
+ },
234
+ {
235
+ label: "\\drds",
236
+ type: "function",
237
+ displayLabel: "\\drds [ role-pattern [ database-pattern ] ]",
238
+ detail: "Lists defined configuration settings"
239
+ },
240
+ {
241
+ label: "\\drg",
242
+ type: "function",
243
+ displayLabel: "\\drg[S] [ pattern ]",
244
+ detail: "Lists information about each granted role membership"
245
+ },
246
+ {
247
+ label: "\\dRp",
248
+ type: "function",
249
+ displayLabel: "\\dRp[+] [ pattern ]",
250
+ detail: "Lists replication publications"
251
+ },
252
+ {
253
+ label: "\\dRs",
254
+ type: "function",
255
+ displayLabel: "\\dRs[+] [ pattern ]",
256
+ detail: "Lists replication subscriptions"
257
+ },
258
+ {
259
+ label: "\\dT",
260
+ type: "function",
261
+ displayLabel: "\\dT[S+] [ pattern ]",
262
+ detail: "Lists data types"
263
+ },
264
+ {
265
+ label: "\\du",
266
+ type: "function",
267
+ displayLabel: "\\du[S+] [ pattern ]",
268
+ detail: "Lists database roles"
269
+ },
270
+ {
271
+ label: "\\dx",
272
+ type: "function",
273
+ displayLabel: "\\dx[+] [ pattern ]",
274
+ detail: "Lists installed extensions"
275
+ },
276
+ {
277
+ label: "\\dX",
278
+ type: "function",
279
+ displayLabel: "\\dX [ pattern ]",
280
+ detail: "Lists extended statistics"
281
+ },
282
+ {
283
+ label: "\\dy",
284
+ type: "function",
285
+ displayLabel: "\\dy[+] [ pattern ]",
286
+ detail: "Lists event triggers"
287
+ }
288
+ ];
289
+ function describeCompletionsAutoComplete(context) {
290
+ const word = context.matchBefore(/\\\w*/);
291
+ if (!word || word.from === word.to) return null;
292
+ return {
293
+ from: word.from,
294
+ options: describeCompletions
295
+ };
296
+ }
297
+ function makeSqlExt(config = {}) {
298
+ let lang = config.dialect || PostgreSQL;
299
+ return new LanguageSupport(lang.language, [
300
+ // schemaCompletion(config),
301
+ config.schema ? lang.language.data.of({
302
+ autocomplete: schemaCompletionSource(config)
303
+ }) : [],
304
+ // keywordCompletion(lang, !!config.upperCaseKeywords)
305
+ lang.language.data.of({
306
+ autocomplete: keywordCompletionSource(lang, !!config.upperCaseKeywords)
307
+ }),
308
+ lang.language.data.of({
309
+ autocomplete: describeCompletionsAutoComplete
310
+ })
311
+ ]);
312
+ }
313
+ async function runQuery(query, pg) {
314
+ if (query.trim().toLowerCase().startsWith("\\")) {
315
+ return runDescribe(query, pg);
316
+ }
317
+ const start = performance.now();
318
+ try {
319
+ const result = await pg.exec(query, {
320
+ rowMode: "array"
321
+ });
322
+ const elapsed = performance.now() - start;
323
+ return {
324
+ query,
325
+ results: result,
326
+ time: elapsed
327
+ };
328
+ } catch (err) {
329
+ return {
330
+ query,
331
+ error: err.message,
332
+ time: performance.now() - start
333
+ };
334
+ }
335
+ }
336
+ async function runDescribe(query, pg) {
337
+ const start = performance.now();
338
+ let out;
339
+ let ret;
340
+ const { promise, cancel: _cancel } = describe(
341
+ query,
342
+ "postgres",
343
+ async (sql) => {
344
+ ret = (await pg.exec(sql, { rowMode: "array" }))[0];
345
+ return {
346
+ rows: ret.rows,
347
+ fields: ret.fields,
348
+ rowCount: ret.rows.length
349
+ };
350
+ },
351
+ (output) => {
352
+ out = output;
353
+ }
354
+ );
355
+ await promise;
356
+ const elapsed = performance.now() - start;
357
+ if (!out) {
358
+ return {
359
+ query,
360
+ error: "No output",
361
+ time: elapsed
362
+ };
363
+ } else if (typeof out === "string") {
364
+ if (out.startsWith("ERROR:")) {
365
+ return {
366
+ query,
367
+ error: out,
368
+ time: elapsed
369
+ };
370
+ } else {
371
+ return {
372
+ query,
373
+ text: out,
374
+ time: elapsed
375
+ };
376
+ }
377
+ } else {
378
+ return {
379
+ query,
380
+ text: out.title,
381
+ results: [ret],
382
+ time: elapsed
383
+ };
384
+ }
385
+ }
386
+ async function getSchema(pg) {
387
+ const ret = await pg.query(`
388
+ SELECT
389
+ table_schema AS schema,
390
+ table_name AS table,
391
+ array_agg(column_name) AS columns
392
+ FROM
393
+ information_schema.columns
394
+ GROUP BY
395
+ table_schema, table_name
396
+ ORDER BY
397
+ table_schema, table_name;
398
+ `);
399
+ const schema = {};
400
+ for (const row of ret.rows) {
401
+ schema[`${row.schema}.${row.table}`] = Array.isArray(row.columns) ? row.columns : row.columns.slice(1, -1).split(",");
402
+ }
403
+ return schema;
404
+ }
405
+ const tableRowIncrement = 100;
406
+ const maxCellLength = 200;
407
+ function cellClass(value) {
408
+ if (value === null) {
409
+ return "PGliteRepl-null";
410
+ } else if (typeof value === "number") {
411
+ return "PGliteRepl-number";
412
+ } else if (typeof value === "boolean") {
413
+ return "PGliteRepl-boolean";
414
+ } else {
415
+ return "";
416
+ }
417
+ }
418
+ function cellValue(value) {
419
+ let str;
420
+ if (value === null) {
421
+ str = "null";
422
+ } else if (typeof value === "number") {
423
+ str = value.toString();
424
+ } else if (typeof value === "boolean") {
425
+ str = value ? "true" : "false";
426
+ } else if (value instanceof Date) {
427
+ str = value.toISOString();
428
+ } else if (Array.isArray(value)) {
429
+ str = `[${value.map(cellValue).join(", ")}]`;
430
+ } else if (typeof value === "object") {
431
+ str = JSON.stringify(value);
432
+ } else if (ArrayBuffer.isView(value)) {
433
+ str = `${value.byteLength} bytes`;
434
+ } else {
435
+ str = value.toString();
436
+ }
437
+ return str.length > maxCellLength ? str.slice(0, maxCellLength) + "…" : str;
438
+ }
439
+ function ReplTable({ result }) {
440
+ const [maxRows, setMaxRows] = useState(tableRowIncrement);
441
+ const rows = result.rows.slice(0, maxRows);
442
+ useEffect(() => {
443
+ setMaxRows(tableRowIncrement);
444
+ }, [result]);
445
+ const showMore = () => {
446
+ setMaxRows((prev) => prev + tableRowIncrement);
447
+ };
448
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
449
+ /* @__PURE__ */ jsx("div", { className: "PGliteRepl-table-scroll", children: /* @__PURE__ */ jsxs("table", { className: "PGliteRepl-table", children: [
450
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: result.fields.map((col, i) => /* @__PURE__ */ jsx("th", { children: col.name }, i)) }) }),
451
+ /* @__PURE__ */ jsx("tbody", { children: rows.map((row, i) => /* @__PURE__ */ jsx("tr", { children: row.map((col, j) => /* @__PURE__ */ jsx("td", { className: cellClass(col), children: cellValue(col) }, j)) }, i)) })
452
+ ] }) }),
453
+ /* @__PURE__ */ jsxs("div", { className: "PGliteRepl-table-row-count", children: [
454
+ result.rows.length > maxRows ? `${maxRows} of ` : "",
455
+ result.rows.length,
456
+ " rows",
457
+ " ",
458
+ result.rows.length > maxRows && /* @__PURE__ */ jsx(
459
+ "a",
460
+ {
461
+ href: "",
462
+ onClick: (e) => {
463
+ e.preventDefault();
464
+ showMore();
465
+ },
466
+ children: "Show more"
467
+ }
468
+ )
469
+ ] })
470
+ ] });
471
+ }
472
+ function OutLine({ result }) {
473
+ return /* @__PURE__ */ jsx("div", { className: "PGliteRepl-line", children: result.fields.length > 0 ? /* @__PURE__ */ jsx(ReplTable, { result }) : /* @__PURE__ */ jsx("div", { className: "PGliteRepl-null", children: "null" }) });
474
+ }
475
+ function ReplResponse({
476
+ response,
477
+ showTime
478
+ }) {
479
+ var _a;
480
+ let out;
481
+ if (response.error) {
482
+ out = /* @__PURE__ */ jsx("div", { className: "PGliteRepl-line PGliteRepl-error", children: response.error });
483
+ } else {
484
+ out = /* @__PURE__ */ jsx(Fragment, { children: (_a = response.results) == null ? void 0 : _a.map((result, i) => /* @__PURE__ */ jsx(OutLine, { result }, i)) });
485
+ }
486
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
487
+ /* @__PURE__ */ jsx("pre", { className: "PGliteRepl-line PGliteRepl-query", children: response.query }),
488
+ response.text && /* @__PURE__ */ jsx("div", { className: "PGliteRepl-line PGliteRepl-text", children: response.text }),
489
+ out,
490
+ /* @__PURE__ */ jsxs("div", { className: "PGliteRepl-divider", children: [
491
+ /* @__PURE__ */ jsx("hr", {}),
492
+ showTime && /* @__PURE__ */ jsxs("div", { className: "PGliteRepl-time", children: [
493
+ response.time.toFixed(1),
494
+ "ms"
495
+ ] })
496
+ ] })
497
+ ] });
498
+ }
499
+ const baseKeymap = defaultKeymap.filter((key) => key.key !== "Enter");
500
+ function Repl({
501
+ pg,
502
+ border = false,
503
+ lightTheme = xcodeLight,
504
+ darkTheme = xcodeDark,
505
+ theme = "auto",
506
+ showTime = false,
507
+ disableUpdateSchema = false
508
+ }) {
509
+ const [value, setValue] = useState("");
510
+ const valueNoHistory = useRef("");
511
+ const [loading, setLoading] = useState(true);
512
+ const [output, setOutput] = useState([]);
513
+ const outputRef = useRef(null);
514
+ const [schema, setSchema] = useState({});
515
+ const historyPos = useRef(-1);
516
+ const rcm = useRef(null);
517
+ const [themeToUse, setThemeToUse] = useState(
518
+ theme === "dark" ? darkTheme : lightTheme
519
+ );
520
+ const [styles, setStyles] = useState({});
521
+ useEffect(() => {
522
+ let ignore = false;
523
+ const init = async () => {
524
+ await pg.waitReady;
525
+ if (ignore) return;
526
+ setLoading(false);
527
+ };
528
+ setLoading(true);
529
+ init();
530
+ return () => {
531
+ ignore = true;
532
+ };
533
+ }, [pg]);
534
+ useEffect(() => {
535
+ if (theme === "auto") {
536
+ const systemTheme = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
537
+ setThemeToUse(systemTheme === "dark" ? darkTheme : lightTheme);
538
+ const listener = (e) => {
539
+ setThemeToUse(e.matches ? darkTheme : lightTheme);
540
+ setTimeout(() => {
541
+ extractStyles();
542
+ }, 0);
543
+ };
544
+ window.matchMedia("(prefers-color-scheme: dark)").addEventListener("change", listener);
545
+ return () => {
546
+ window.matchMedia("(prefers-color-scheme: dark)").removeEventListener("change", listener);
547
+ };
548
+ } else {
549
+ setThemeToUse(theme === "dark" ? darkTheme : lightTheme);
550
+ setTimeout(() => {
551
+ extractStyles();
552
+ }, 0);
553
+ }
554
+ }, [theme, lightTheme, darkTheme]);
555
+ const onChange = useCallback((val, _viewUpdate) => {
556
+ extractStyles();
557
+ setValue(val);
558
+ if (historyPos.current === -1) {
559
+ valueNoHistory.current = val;
560
+ }
561
+ }, []);
562
+ const extensions = useMemo(
563
+ () => [
564
+ keymap.of([
565
+ {
566
+ key: "Enter",
567
+ preventDefault: true,
568
+ run: () => {
569
+ if (value.trim() === "") return false;
570
+ runQuery(value, pg).then((response) => {
571
+ setOutput((prev) => [...prev, response]);
572
+ if (outputRef.current) {
573
+ setTimeout(() => {
574
+ outputRef.current.scrollTop = outputRef.current.scrollHeight;
575
+ }, 0);
576
+ }
577
+ if (!disableUpdateSchema) {
578
+ getSchema(pg).then(setSchema);
579
+ }
580
+ });
581
+ historyPos.current = -1;
582
+ valueNoHistory.current = "";
583
+ setValue("");
584
+ return true;
585
+ }
586
+ },
587
+ {
588
+ key: "ArrowUp",
589
+ run: (view) => {
590
+ const state = view.state;
591
+ const cursorLine = state.doc.lineAt(
592
+ state.selection.main.head
593
+ ).number;
594
+ if (cursorLine === 1) {
595
+ const currentPos = historyPos.current;
596
+ historyPos.current++;
597
+ if (historyPos.current >= output.length) {
598
+ historyPos.current = output.length - 1;
599
+ }
600
+ if (historyPos.current < -1) {
601
+ historyPos.current = -1;
602
+ }
603
+ if (historyPos.current === currentPos) return true;
604
+ if (historyPos.current === -1) {
605
+ setValue(valueNoHistory.current);
606
+ } else {
607
+ setValue(output[output.length - historyPos.current - 1].query);
608
+ }
609
+ return true;
610
+ }
611
+ return false;
612
+ }
613
+ },
614
+ {
615
+ key: "ArrowDown",
616
+ run: (view) => {
617
+ const state = view.state;
618
+ const cursorLine = state.doc.lineAt(
619
+ state.selection.main.head
620
+ ).number;
621
+ const lastLine = state.doc.lines;
622
+ if (cursorLine === lastLine) {
623
+ const currentPos = historyPos.current;
624
+ historyPos.current--;
625
+ if (historyPos.current >= output.length) {
626
+ historyPos.current = output.length - 1;
627
+ }
628
+ if (historyPos.current < -1) {
629
+ historyPos.current = -1;
630
+ }
631
+ if (historyPos.current === currentPos) return true;
632
+ if (historyPos.current === -1) {
633
+ setValue(valueNoHistory.current);
634
+ } else {
635
+ setValue(output[output.length - historyPos.current - 1].query);
636
+ }
637
+ return true;
638
+ }
639
+ return false;
640
+ }
641
+ },
642
+ ...baseKeymap
643
+ ]),
644
+ makeSqlExt({
645
+ dialect: PostgreSQL,
646
+ schema,
647
+ tables: [
648
+ {
649
+ label: "d",
650
+ displayLabel: "\\d"
651
+ }
652
+ ],
653
+ defaultSchema: "public"
654
+ })
655
+ ],
656
+ [pg, schema, value, output]
657
+ );
658
+ const extractStyles = () => {
659
+ var _a;
660
+ const cmEditorEl = (_a = rcm.current) == null ? void 0 : _a.editor.querySelector(".cm-editor");
661
+ const gutterEl = cmEditorEl.querySelector(".cm-gutters");
662
+ const cmEditorElComputedStyles = window.getComputedStyle(cmEditorEl);
663
+ const foregroundColor = cmEditorElComputedStyles.color;
664
+ const backgroundColor = cmEditorElComputedStyles.backgroundColor;
665
+ const gutterElComputedStyles = window.getComputedStyle(gutterEl);
666
+ const gutterBorder = gutterElComputedStyles.borderRight;
667
+ const borderWidth = parseInt(gutterElComputedStyles.borderRightWidth) || 0;
668
+ const borderColor = borderWidth ? gutterElComputedStyles.borderRightColor : foregroundColor.replace("rgb", "rgba").replace(")", ", 0.15)");
669
+ const border2 = borderWidth ? gutterElComputedStyles.borderRight : `1px solid ${borderColor}`;
670
+ setStyles({
671
+ "--PGliteRepl-foreground-color": foregroundColor,
672
+ "--PGliteRepl-background-color": backgroundColor,
673
+ "--PGliteRepl-border": border2,
674
+ "--PGliteRepl-gutter-border": gutterBorder,
675
+ "--PGliteRepl-border-color": borderColor
676
+ });
677
+ };
678
+ return /* @__PURE__ */ jsxs(
679
+ "div",
680
+ {
681
+ className: `
682
+ PGliteRepl-root
683
+ ${border ? "PGliteRepl-root-border" : ""}
684
+ `,
685
+ style: styles,
686
+ children: [
687
+ /* @__PURE__ */ jsxs(
688
+ "div",
689
+ {
690
+ className: "PGliteRepl-output",
691
+ ref: (ref) => outputRef.current = ref,
692
+ children: [
693
+ loading && /* @__PURE__ */ jsx("div", { className: "PGliteRepl-loading-msg", children: "Loading..." }),
694
+ output.map((response, i) => /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ReplResponse, { response: response || [], showTime }) }, i))
695
+ ]
696
+ }
697
+ ),
698
+ /* @__PURE__ */ jsx(
699
+ CodeMirror,
700
+ {
701
+ ref: rcm,
702
+ className: `PGliteRepl-input ${loading ? "PGliteRepl-input-loading" : ""}`,
703
+ width: "100%",
704
+ value,
705
+ basicSetup: {
706
+ defaultKeymap: false
707
+ },
708
+ extensions,
709
+ theme: themeToUse,
710
+ onChange,
711
+ editable: !loading,
712
+ onCreateEditor: () => {
713
+ extractStyles();
714
+ setTimeout(extractStyles, 0);
715
+ getSchema(pg).then(setSchema);
716
+ }
717
+ }
718
+ )
719
+ ]
720
+ }
721
+ );
722
+ }
723
+ export {
724
+ Repl
725
+ };
726
+ //# sourceMappingURL=Repl.js.map