@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.
@@ -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,6 @@
1
+ /**
2
+ * dbreact Types
3
+ *
4
+ * Re-exports from @promakeai/orm and React-specific types.
5
+ */
6
+ export {};
@@ -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
+ }