@rozenite/sqlite-plugin 2.0.0 → 2.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.
- package/CHANGELOG.md +8 -0
- package/dist/devtools/assets/{panel-CsA6Ejak.js → panel-BsdCagVv.js} +3 -3
- package/dist/devtools/panel.html +1 -1
- package/dist/react-native/chunks/index.require.js +4 -16
- package/dist/react-native/chunks/sql.require.js +1 -3
- package/dist/react-native/chunks/useRozeniteSqlitePlugin.require.js +92 -110
- package/dist/react-native/index.d.ts +1 -1
- package/dist/rozenite.json +1 -1
- package/package.json +23 -23
- package/react-native.ts +7 -14
- package/src/react-native/adapters/__tests__/expo-sqlite.test.ts +4 -14
- package/src/react-native/adapters/expo-sqlite.ts +11 -40
- package/src/react-native/adapters/generic.ts +5 -13
- package/src/react-native/adapters/index.ts +1 -4
- package/src/react-native/sqlite-view.ts +2 -8
- package/src/react-native/useRozeniteSqlitePlugin.ts +110 -130
- package/src/react-native/useSqliteAgentTools.ts +6 -18
- package/src/shared/__tests__/bridge-values.test.ts +6 -11
- package/src/shared/__tests__/sql.test.ts +4 -8
- package/src/shared/bridge-values.ts +2 -5
- package/src/shared/sql.ts +3 -7
- package/src/ui/__tests__/sql-editor-utils.test.ts +1 -5
- package/src/ui/__tests__/sqlite-drop-mutations.test.ts +6 -3
- package/src/ui/__tests__/sqlite-row-mutations.test.ts +1 -3
- package/src/ui/__tests__/sqlite-table-column-order.test.ts +4 -19
- package/src/ui/cell-detail-drawer.tsx +1 -6
- package/src/ui/globals.css +14 -65
- package/src/ui/panel.tsx +256 -596
- package/src/ui/query-result-table.tsx +8 -26
- package/src/ui/sql-editor-utils.ts +24 -55
- package/src/ui/sql-editor.tsx +13 -46
- package/src/ui/sqlite-data-table.tsx +11 -28
- package/src/ui/sqlite-drop-modal.tsx +17 -43
- package/src/ui/sqlite-drop-mutations.ts +3 -10
- package/src/ui/sqlite-introspection.ts +9 -25
- package/src/ui/sqlite-row-delete-modal.tsx +5 -12
- package/src/ui/sqlite-row-edit-modal.tsx +22 -64
- package/src/ui/sqlite-row-edit-value.ts +2 -11
- package/src/ui/sqlite-row-mutations.ts +10 -32
- package/src/ui/sqlite-table-column-order.ts +8 -23
- package/src/ui/use-sqlite-requests.ts +46 -86
- package/src/ui/utils.ts +1 -5
- package/src/ui/value-utils.tsx +3 -11
|
@@ -10,19 +10,11 @@ import type {
|
|
|
10
10
|
} from '../shared/types';
|
|
11
11
|
import { newRequestId, withTimeout } from './utils';
|
|
12
12
|
|
|
13
|
-
type PendingListResolver = (
|
|
14
|
-
|
|
15
|
-
) => void;
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
) => void;
|
|
19
|
-
type PendingScriptResolver = (
|
|
20
|
-
payload: SqliteEventMap['sqlite:execute-script:result'],
|
|
21
|
-
) => void;
|
|
22
|
-
|
|
23
|
-
export const useSqliteRequests = (
|
|
24
|
-
client: RozeniteDevToolsClient<SqliteEventMap> | null,
|
|
25
|
-
) => {
|
|
13
|
+
type PendingListResolver = (payload: SqliteEventMap['sqlite:list-databases:result']) => void;
|
|
14
|
+
type PendingQueryResolver = (payload: SqliteEventMap['sqlite:query:result']) => void;
|
|
15
|
+
type PendingScriptResolver = (payload: SqliteEventMap['sqlite:execute-script:result']) => void;
|
|
16
|
+
|
|
17
|
+
export const useSqliteRequests = (client: RozeniteDevToolsClient<SqliteEventMap> | null) => {
|
|
26
18
|
const listResolversRef = useRef(new Map<string, PendingListResolver>());
|
|
27
19
|
const queryResolversRef = useRef(new Map<string, PendingQueryResolver>());
|
|
28
20
|
const scriptResolversRef = useRef(new Map<string, PendingScriptResolver>());
|
|
@@ -32,44 +24,35 @@ export const useSqliteRequests = (
|
|
|
32
24
|
return;
|
|
33
25
|
}
|
|
34
26
|
|
|
35
|
-
const listSubscription = client.onMessage(
|
|
36
|
-
|
|
37
|
-
(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
const resolve = scriptResolversRef.current.get(payload.requestId);
|
|
65
|
-
if (!resolve) {
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
scriptResolversRef.current.delete(payload.requestId);
|
|
70
|
-
resolve(payload);
|
|
71
|
-
},
|
|
72
|
-
);
|
|
27
|
+
const listSubscription = client.onMessage('sqlite:list-databases:result', (payload) => {
|
|
28
|
+
const resolve = listResolversRef.current.get(payload.requestId);
|
|
29
|
+
if (!resolve) {
|
|
30
|
+
return;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
listResolversRef.current.delete(payload.requestId);
|
|
34
|
+
resolve(payload);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const querySubscription = client.onMessage('sqlite:query:result', (payload) => {
|
|
38
|
+
const resolve = queryResolversRef.current.get(payload.requestId);
|
|
39
|
+
if (!resolve) {
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
queryResolversRef.current.delete(payload.requestId);
|
|
44
|
+
resolve(payload);
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
const scriptSubscription = client.onMessage('sqlite:execute-script:result', (payload) => {
|
|
48
|
+
const resolve = scriptResolversRef.current.get(payload.requestId);
|
|
49
|
+
if (!resolve) {
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
scriptResolversRef.current.delete(payload.requestId);
|
|
54
|
+
resolve(payload);
|
|
55
|
+
});
|
|
73
56
|
|
|
74
57
|
return () => {
|
|
75
58
|
listSubscription.remove();
|
|
@@ -81,27 +64,19 @@ export const useSqliteRequests = (
|
|
|
81
64
|
};
|
|
82
65
|
}, [client]);
|
|
83
66
|
|
|
84
|
-
const requestDatabases = useCallback(async (): Promise<
|
|
85
|
-
SqliteDatabaseInfo[]
|
|
86
|
-
> => {
|
|
67
|
+
const requestDatabases = useCallback(async (): Promise<SqliteDatabaseInfo[]> => {
|
|
87
68
|
if (!client) {
|
|
88
69
|
return [];
|
|
89
70
|
}
|
|
90
71
|
|
|
91
72
|
const requestId = newRequestId();
|
|
92
|
-
const pending = new Promise<SqliteEventMap['sqlite:list-databases:result']>(
|
|
93
|
-
(resolve)
|
|
94
|
-
|
|
95
|
-
},
|
|
96
|
-
);
|
|
73
|
+
const pending = new Promise<SqliteEventMap['sqlite:list-databases:result']>((resolve) => {
|
|
74
|
+
listResolversRef.current.set(requestId, resolve);
|
|
75
|
+
});
|
|
97
76
|
|
|
98
77
|
client.send('sqlite:list-databases', { requestId });
|
|
99
78
|
|
|
100
|
-
const response = await withTimeout(
|
|
101
|
-
pending,
|
|
102
|
-
8000,
|
|
103
|
-
'Timeout fetching databases.',
|
|
104
|
-
);
|
|
79
|
+
const response = await withTimeout(pending, 8000, 'Timeout fetching databases.');
|
|
105
80
|
|
|
106
81
|
if (response.error) {
|
|
107
82
|
throw new Error(response.error);
|
|
@@ -121,11 +96,9 @@ export const useSqliteRequests = (
|
|
|
121
96
|
}
|
|
122
97
|
|
|
123
98
|
const requestId = newRequestId();
|
|
124
|
-
const pending = new Promise<SqliteEventMap['sqlite:query:result']>(
|
|
125
|
-
(resolve)
|
|
126
|
-
|
|
127
|
-
},
|
|
128
|
-
);
|
|
99
|
+
const pending = new Promise<SqliteEventMap['sqlite:query:result']>((resolve) => {
|
|
100
|
+
queryResolversRef.current.set(requestId, resolve);
|
|
101
|
+
});
|
|
129
102
|
|
|
130
103
|
client.send('sqlite:query', {
|
|
131
104
|
requestId,
|
|
@@ -137,11 +110,7 @@ export const useSqliteRequests = (
|
|
|
137
110
|
: (encodeSqliteBridgeValue(input.params) as SqliteQueryParams),
|
|
138
111
|
});
|
|
139
112
|
|
|
140
|
-
const response = await withTimeout(
|
|
141
|
-
pending,
|
|
142
|
-
15000,
|
|
143
|
-
'Timeout executing SQL query.',
|
|
144
|
-
);
|
|
113
|
+
const response = await withTimeout(pending, 15000, 'Timeout executing SQL query.');
|
|
145
114
|
|
|
146
115
|
if (response.error) {
|
|
147
116
|
throw new Error(response.error);
|
|
@@ -157,18 +126,13 @@ export const useSqliteRequests = (
|
|
|
157
126
|
);
|
|
158
127
|
|
|
159
128
|
const requestScriptExecution = useCallback(
|
|
160
|
-
async (input: {
|
|
161
|
-
databaseId: string;
|
|
162
|
-
sql: string;
|
|
163
|
-
}): Promise<SqliteScriptResult> => {
|
|
129
|
+
async (input: { databaseId: string; sql: string }): Promise<SqliteScriptResult> => {
|
|
164
130
|
if (!client) {
|
|
165
131
|
throw new Error('Rozenite client is not connected.');
|
|
166
132
|
}
|
|
167
133
|
|
|
168
134
|
const requestId = newRequestId();
|
|
169
|
-
const pending = new Promise<
|
|
170
|
-
SqliteEventMap['sqlite:execute-script:result']
|
|
171
|
-
>((resolve) => {
|
|
135
|
+
const pending = new Promise<SqliteEventMap['sqlite:execute-script:result']>((resolve) => {
|
|
172
136
|
scriptResolversRef.current.set(requestId, resolve);
|
|
173
137
|
});
|
|
174
138
|
|
|
@@ -178,11 +142,7 @@ export const useSqliteRequests = (
|
|
|
178
142
|
sql: input.sql,
|
|
179
143
|
});
|
|
180
144
|
|
|
181
|
-
const response = await withTimeout(
|
|
182
|
-
pending,
|
|
183
|
-
30000,
|
|
184
|
-
'Timeout executing SQL script.',
|
|
185
|
-
);
|
|
145
|
+
const response = await withTimeout(pending, 30000, 'Timeout executing SQL script.');
|
|
186
146
|
|
|
187
147
|
if (response.error) {
|
|
188
148
|
throw new Error(response.error);
|
package/src/ui/utils.ts
CHANGED
|
@@ -2,11 +2,7 @@ export function newRequestId(): string {
|
|
|
2
2
|
return `${Date.now().toString(16)}-${Math.random().toString(16).slice(2)}`;
|
|
3
3
|
}
|
|
4
4
|
|
|
5
|
-
export async function withTimeout<T>(
|
|
6
|
-
promise: Promise<T>,
|
|
7
|
-
ms: number,
|
|
8
|
-
message: string,
|
|
9
|
-
): Promise<T> {
|
|
5
|
+
export async function withTimeout<T>(promise: Promise<T>, ms: number, message: string): Promise<T> {
|
|
10
6
|
let timeout: ReturnType<typeof setTimeout> | null = null;
|
|
11
7
|
|
|
12
8
|
try {
|
package/src/ui/value-utils.tsx
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { JSONTree } from 'react-json-tree';
|
|
2
|
-
import type {
|
|
3
|
-
SqliteQueryMetadata,
|
|
4
|
-
SqliteQueryResult,
|
|
5
|
-
SqliteScriptResult,
|
|
6
|
-
} from '../shared/types';
|
|
2
|
+
import type { SqliteQueryMetadata, SqliteQueryResult, SqliteScriptResult } from '../shared/types';
|
|
7
3
|
import { truncateText } from './utils';
|
|
8
4
|
|
|
9
5
|
const jsonTreeTheme = {
|
|
@@ -25,9 +21,7 @@ const jsonTreeTheme = {
|
|
|
25
21
|
base0F: '#f97316',
|
|
26
22
|
};
|
|
27
23
|
|
|
28
|
-
export const isStructuredValue = (
|
|
29
|
-
value: unknown,
|
|
30
|
-
): value is Record<string, unknown> | unknown[] => {
|
|
24
|
+
export const isStructuredValue = (value: unknown): value is Record<string, unknown> | unknown[] => {
|
|
31
25
|
return Array.isArray(value) || (!!value && typeof value === 'object');
|
|
32
26
|
};
|
|
33
27
|
|
|
@@ -37,9 +31,7 @@ export const getValueKind = (value: unknown) => {
|
|
|
37
31
|
}
|
|
38
32
|
|
|
39
33
|
if (Array.isArray(value)) {
|
|
40
|
-
return value.every((item) => typeof item === 'number')
|
|
41
|
-
? 'blob-ish'
|
|
42
|
-
: 'array';
|
|
34
|
+
return value.every((item) => typeof item === 'number') ? 'blob-ish' : 'array';
|
|
43
35
|
}
|
|
44
36
|
|
|
45
37
|
return typeof value;
|