@promakeai/dbreact 1.0.1
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/README.md +633 -0
- package/SKILL.md +311 -0
- package/dist/adapters/RestAdapter.d.ts.map +1 -0
- package/dist/adapters/SqliteAdapter.d.ts.map +1 -0
- package/dist/adapters/SqliteAdapter.js +543 -0
- package/dist/core/DataManager.d.ts.map +1 -0
- package/dist/hooks/useDataManager.d.ts.map +1 -0
- package/dist/hooks/useDbHooks.d.ts.map +1 -0
- package/dist/hooks/useDbHooks.js +157 -0
- package/dist/hooks/useDbLang.d.ts.map +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +648 -0
- package/dist/providers/DbProvider.d.ts.map +1 -0
- package/dist/providers/DbProvider.js +134 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/utils/whereBuilder.d.ts.map +1 -0
- package/package.json +54 -0
- package/providers/DbProvider.tsx +191 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* Database Provider
|
|
4
|
+
*
|
|
5
|
+
* React context provider for database operations with language support.
|
|
6
|
+
*/
|
|
7
|
+
import { createContext, useContext, useState, useEffect, useMemo, useCallback, useRef, } from "react";
|
|
8
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
9
|
+
// Database context
|
|
10
|
+
const DbContext = createContext(null);
|
|
11
|
+
// Language context
|
|
12
|
+
const DbLangContext = createContext(null);
|
|
13
|
+
/**
|
|
14
|
+
* Default QueryClient for React Query
|
|
15
|
+
*/
|
|
16
|
+
const defaultQueryClient = new QueryClient({
|
|
17
|
+
defaultOptions: {
|
|
18
|
+
queries: {
|
|
19
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
20
|
+
gcTime: 1000 * 60 * 30, // 30 minutes (formerly cacheTime)
|
|
21
|
+
refetchOnWindowFocus: false,
|
|
22
|
+
},
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
/**
|
|
26
|
+
* Database Provider Component
|
|
27
|
+
*
|
|
28
|
+
* Wraps application with database context, language context, and React Query.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```tsx
|
|
32
|
+
* import { DbProvider, SqliteAdapter } from '@promakeai/dbreact';
|
|
33
|
+
*
|
|
34
|
+
* const adapter = new SqliteAdapter({ storageKey: 'myapp' });
|
|
35
|
+
*
|
|
36
|
+
* function App() {
|
|
37
|
+
* return (
|
|
38
|
+
* <DbProvider adapter={adapter} lang="tr" fallbackLang="en">
|
|
39
|
+
* <MyApp />
|
|
40
|
+
* </DbProvider>
|
|
41
|
+
* );
|
|
42
|
+
* }
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
export function DbProvider({ adapter, lang: langProp = "en", fallbackLang = "en", autoConnect = true, queryClient = defaultQueryClient, children, }) {
|
|
46
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
47
|
+
const [error, setError] = useState(null);
|
|
48
|
+
const [lang, setLangState] = useState(langProp);
|
|
49
|
+
const isFirstRender = useRef(true);
|
|
50
|
+
// Sync internal state when prop changes
|
|
51
|
+
useEffect(() => {
|
|
52
|
+
if (langProp !== lang) {
|
|
53
|
+
setLangState(langProp);
|
|
54
|
+
}
|
|
55
|
+
}, [langProp]);
|
|
56
|
+
// Invalidate all queries when language changes (skip first render)
|
|
57
|
+
useEffect(() => {
|
|
58
|
+
if (isFirstRender.current) {
|
|
59
|
+
isFirstRender.current = false;
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
// Invalidate all queries to refetch with new language
|
|
63
|
+
queryClient.invalidateQueries();
|
|
64
|
+
}, [lang]);
|
|
65
|
+
// Connect to adapter on mount
|
|
66
|
+
useEffect(() => {
|
|
67
|
+
if (!autoConnect)
|
|
68
|
+
return;
|
|
69
|
+
let mounted = true;
|
|
70
|
+
async function connect() {
|
|
71
|
+
try {
|
|
72
|
+
await adapter.connect?.();
|
|
73
|
+
if (mounted) {
|
|
74
|
+
setIsConnected(true);
|
|
75
|
+
setError(null);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
if (mounted) {
|
|
80
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
81
|
+
setIsConnected(false);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
connect();
|
|
86
|
+
return () => {
|
|
87
|
+
mounted = false;
|
|
88
|
+
};
|
|
89
|
+
}, [adapter, autoConnect]);
|
|
90
|
+
// setLang updates internal state (and triggers invalidation via effect)
|
|
91
|
+
const setLang = useCallback((newLang) => {
|
|
92
|
+
setLangState(newLang);
|
|
93
|
+
}, []);
|
|
94
|
+
// Database context value
|
|
95
|
+
const dbContextValue = useMemo(() => ({
|
|
96
|
+
adapter,
|
|
97
|
+
isConnected,
|
|
98
|
+
error,
|
|
99
|
+
}), [adapter, isConnected, error]);
|
|
100
|
+
// Language context value
|
|
101
|
+
const langContextValue = useMemo(() => ({
|
|
102
|
+
lang,
|
|
103
|
+
fallbackLang,
|
|
104
|
+
setLang,
|
|
105
|
+
}), [lang, fallbackLang, setLang]);
|
|
106
|
+
return (_jsx(QueryClientProvider, { client: queryClient, children: _jsx(DbContext.Provider, { value: dbContextValue, children: _jsx(DbLangContext.Provider, { value: langContextValue, children: children }) }) }));
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Hook to access database context
|
|
110
|
+
*/
|
|
111
|
+
export function useDb() {
|
|
112
|
+
const context = useContext(DbContext);
|
|
113
|
+
if (!context) {
|
|
114
|
+
throw new Error("useDb must be used within a DbProvider");
|
|
115
|
+
}
|
|
116
|
+
return context;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* Hook to access the raw adapter
|
|
120
|
+
*/
|
|
121
|
+
export function useAdapter() {
|
|
122
|
+
const { adapter } = useDb();
|
|
123
|
+
return adapter;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Hook to access language context
|
|
127
|
+
*/
|
|
128
|
+
export function useDbLang() {
|
|
129
|
+
const context = useContext(DbLangContext);
|
|
130
|
+
if (!context) {
|
|
131
|
+
throw new Error("useDbLang must be used within a DbProvider");
|
|
132
|
+
}
|
|
133
|
+
return context;
|
|
134
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../types.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,YAAY,EACV,YAAY,EACZ,YAAY,EACZ,eAAe,GAChB,MAAM,gBAAgB,CAAC;AAExB;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,gBAAgB,EAAE,YAAY,CAAC;IAC/C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,gBAAgB,EAAE,YAAY,CAAC;IAC/C,WAAW,EAAE,OAAO,CAAC;IACrB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACrB"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"whereBuilder.d.ts","sourceRoot":"","sources":["../../utils/whereBuilder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,MAAM,WAAW,WAAW;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,OAAO,EAAE,CAAC;CACnB;AAqHD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,WAAW,CAK7E"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@promakeai/dbreact",
|
|
3
|
+
"version": "1.0.1",
|
|
4
|
+
"description": "React client for schema-driven multi-language database",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"module": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"type": "module",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"import": "./dist/index.js",
|
|
12
|
+
"require": "./dist/index.js",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "bun build index.ts --outdir dist --target browser --packages=external && bun run build:types",
|
|
18
|
+
"build:types": "tsc --emitDeclarationOnly --declaration --outDir dist",
|
|
19
|
+
"dev": "bun build index.ts --outdir dist --target browser --packages=external --watch",
|
|
20
|
+
"test": "bun test",
|
|
21
|
+
"typecheck": "tsc --noEmit",
|
|
22
|
+
"release": "bun run build && npm publish --access public"
|
|
23
|
+
},
|
|
24
|
+
"keywords": [
|
|
25
|
+
"react",
|
|
26
|
+
"database",
|
|
27
|
+
"sqlite",
|
|
28
|
+
"multi-language",
|
|
29
|
+
"tanstack-query"
|
|
30
|
+
],
|
|
31
|
+
"author": "Promake Inc.",
|
|
32
|
+
"license": "MIT",
|
|
33
|
+
"peerDependencies": {
|
|
34
|
+
"react": ">=19.0.0",
|
|
35
|
+
"react-dom": ">=19.0.0",
|
|
36
|
+
"@tanstack/react-query": ">=5.0.0",
|
|
37
|
+
"sql.js": ">=1.11.0"
|
|
38
|
+
},
|
|
39
|
+
"dependencies": {
|
|
40
|
+
"@promakeai/orm": "1.0.1"
|
|
41
|
+
},
|
|
42
|
+
"devDependencies": {
|
|
43
|
+
"@tanstack/query-core": "5.90.20",
|
|
44
|
+
"@tanstack/react-query": "^5.66.0",
|
|
45
|
+
"@types/react": "^19.0.0",
|
|
46
|
+
"react": "^19.0.0",
|
|
47
|
+
"react-dom": "^19.0.0",
|
|
48
|
+
"sql.js": "^1.12.0",
|
|
49
|
+
"typescript": "^5.7.3"
|
|
50
|
+
},
|
|
51
|
+
"publishConfig": {
|
|
52
|
+
"access": "public"
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Database Provider
|
|
3
|
+
*
|
|
4
|
+
* React context provider for database operations with language support.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import {
|
|
8
|
+
createContext,
|
|
9
|
+
useContext,
|
|
10
|
+
useState,
|
|
11
|
+
useEffect,
|
|
12
|
+
useMemo,
|
|
13
|
+
useCallback,
|
|
14
|
+
useRef,
|
|
15
|
+
type ReactNode,
|
|
16
|
+
} from "react";
|
|
17
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
18
|
+
import type {
|
|
19
|
+
IDataAdapter,
|
|
20
|
+
DbProviderConfig,
|
|
21
|
+
DbLangContextValue,
|
|
22
|
+
DbContextValue,
|
|
23
|
+
} from "../types";
|
|
24
|
+
|
|
25
|
+
// Database context
|
|
26
|
+
const DbContext = createContext<DbContextValue | null>(null);
|
|
27
|
+
|
|
28
|
+
// Language context
|
|
29
|
+
const DbLangContext = createContext<DbLangContextValue | null>(null);
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Default QueryClient for React Query
|
|
33
|
+
*/
|
|
34
|
+
const defaultQueryClient = new QueryClient({
|
|
35
|
+
defaultOptions: {
|
|
36
|
+
queries: {
|
|
37
|
+
staleTime: 1000 * 60 * 5, // 5 minutes
|
|
38
|
+
gcTime: 1000 * 60 * 30, // 30 minutes (formerly cacheTime)
|
|
39
|
+
refetchOnWindowFocus: false,
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
interface DbProviderProps extends DbProviderConfig {
|
|
45
|
+
children: ReactNode;
|
|
46
|
+
queryClient?: QueryClient;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Database Provider Component
|
|
51
|
+
*
|
|
52
|
+
* Wraps application with database context, language context, and React Query.
|
|
53
|
+
*
|
|
54
|
+
* @example
|
|
55
|
+
* ```tsx
|
|
56
|
+
* import { DbProvider, SqliteAdapter } from '@promakeai/dbreact';
|
|
57
|
+
*
|
|
58
|
+
* const adapter = new SqliteAdapter({ storageKey: 'myapp' });
|
|
59
|
+
*
|
|
60
|
+
* function App() {
|
|
61
|
+
* return (
|
|
62
|
+
* <DbProvider adapter={adapter} lang="tr" fallbackLang="en">
|
|
63
|
+
* <MyApp />
|
|
64
|
+
* </DbProvider>
|
|
65
|
+
* );
|
|
66
|
+
* }
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
export function DbProvider({
|
|
70
|
+
adapter,
|
|
71
|
+
lang: langProp = "en",
|
|
72
|
+
fallbackLang = "en",
|
|
73
|
+
autoConnect = true,
|
|
74
|
+
queryClient = defaultQueryClient,
|
|
75
|
+
children,
|
|
76
|
+
}: DbProviderProps) {
|
|
77
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
78
|
+
const [error, setError] = useState<Error | null>(null);
|
|
79
|
+
const [lang, setLangState] = useState(langProp);
|
|
80
|
+
const isFirstRender = useRef(true);
|
|
81
|
+
|
|
82
|
+
// Sync internal state when prop changes
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
if (langProp !== lang) {
|
|
85
|
+
setLangState(langProp);
|
|
86
|
+
}
|
|
87
|
+
}, [langProp]);
|
|
88
|
+
|
|
89
|
+
// Invalidate all queries when language changes (skip first render)
|
|
90
|
+
useEffect(() => {
|
|
91
|
+
if (isFirstRender.current) {
|
|
92
|
+
isFirstRender.current = false;
|
|
93
|
+
return;
|
|
94
|
+
}
|
|
95
|
+
// Invalidate all queries to refetch with new language
|
|
96
|
+
queryClient.invalidateQueries();
|
|
97
|
+
}, [lang]);
|
|
98
|
+
|
|
99
|
+
// Connect to adapter on mount
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (!autoConnect) return;
|
|
102
|
+
|
|
103
|
+
let mounted = true;
|
|
104
|
+
|
|
105
|
+
async function connect() {
|
|
106
|
+
try {
|
|
107
|
+
await adapter.connect?.();
|
|
108
|
+
if (mounted) {
|
|
109
|
+
setIsConnected(true);
|
|
110
|
+
setError(null);
|
|
111
|
+
}
|
|
112
|
+
} catch (err) {
|
|
113
|
+
if (mounted) {
|
|
114
|
+
setError(err instanceof Error ? err : new Error(String(err)));
|
|
115
|
+
setIsConnected(false);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
connect();
|
|
121
|
+
|
|
122
|
+
return () => {
|
|
123
|
+
mounted = false;
|
|
124
|
+
};
|
|
125
|
+
}, [adapter, autoConnect]);
|
|
126
|
+
|
|
127
|
+
// setLang updates internal state (and triggers invalidation via effect)
|
|
128
|
+
const setLang = useCallback((newLang: string) => {
|
|
129
|
+
setLangState(newLang);
|
|
130
|
+
}, []);
|
|
131
|
+
|
|
132
|
+
// Database context value
|
|
133
|
+
const dbContextValue = useMemo<DbContextValue>(
|
|
134
|
+
() => ({
|
|
135
|
+
adapter,
|
|
136
|
+
isConnected,
|
|
137
|
+
error,
|
|
138
|
+
}),
|
|
139
|
+
[adapter, isConnected, error]
|
|
140
|
+
);
|
|
141
|
+
|
|
142
|
+
// Language context value
|
|
143
|
+
const langContextValue = useMemo<DbLangContextValue>(
|
|
144
|
+
() => ({
|
|
145
|
+
lang,
|
|
146
|
+
fallbackLang,
|
|
147
|
+
setLang,
|
|
148
|
+
}),
|
|
149
|
+
[lang, fallbackLang, setLang]
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
return (
|
|
153
|
+
<QueryClientProvider client={queryClient}>
|
|
154
|
+
<DbContext.Provider value={dbContextValue}>
|
|
155
|
+
<DbLangContext.Provider value={langContextValue}>
|
|
156
|
+
{children}
|
|
157
|
+
</DbLangContext.Provider>
|
|
158
|
+
</DbContext.Provider>
|
|
159
|
+
</QueryClientProvider>
|
|
160
|
+
);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Hook to access database context
|
|
165
|
+
*/
|
|
166
|
+
export function useDb(): DbContextValue {
|
|
167
|
+
const context = useContext(DbContext);
|
|
168
|
+
if (!context) {
|
|
169
|
+
throw new Error("useDb must be used within a DbProvider");
|
|
170
|
+
}
|
|
171
|
+
return context;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
/**
|
|
175
|
+
* Hook to access the raw adapter
|
|
176
|
+
*/
|
|
177
|
+
export function useAdapter(): IDataAdapter {
|
|
178
|
+
const { adapter } = useDb();
|
|
179
|
+
return adapter;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/**
|
|
183
|
+
* Hook to access language context
|
|
184
|
+
*/
|
|
185
|
+
export function useDbLang(): DbLangContextValue {
|
|
186
|
+
const context = useContext(DbLangContext);
|
|
187
|
+
if (!context) {
|
|
188
|
+
throw new Error("useDbLang must be used within a DbProvider");
|
|
189
|
+
}
|
|
190
|
+
return context;
|
|
191
|
+
}
|