@pol-studios/db 1.0.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.
Binary file
@@ -0,0 +1,201 @@
1
+ // src/client/config.ts
2
+ var supabaseUrl = process.env.SUPABASE_URL;
3
+ var supabaseKey = process.env.SUPABASE_ANON_KEY ?? "";
4
+ function setSupabaseUrl(url) {
5
+ supabaseUrl = url;
6
+ }
7
+ function getSupabaseUrl() {
8
+ return supabaseUrl;
9
+ }
10
+ function setSupabaseKey(key) {
11
+ supabaseKey = key;
12
+ }
13
+ function getSupabaseKey() {
14
+ return supabaseKey;
15
+ }
16
+
17
+ // src/client/useSupabase.tsx
18
+ import {
19
+ createContext,
20
+ useContext,
21
+ useEffect,
22
+ useMemo,
23
+ useState
24
+ } from "react";
25
+ import {
26
+ createClient
27
+ } from "@supabase/supabase-js";
28
+ import { jsx } from "react/jsx-runtime";
29
+ function newUuid() {
30
+ return crypto.randomUUID();
31
+ }
32
+ function isUsable(value) {
33
+ return value !== null && value !== void 0;
34
+ }
35
+ function delay(ms) {
36
+ return new Promise((resolve) => setTimeout(resolve, ms));
37
+ }
38
+ var UserSessionId = newUuid();
39
+ var defaultOptions = {
40
+ auth: {
41
+ autoRefreshToken: true,
42
+ persistSession: true,
43
+ detectSessionInUrl: true
44
+ },
45
+ global: {
46
+ headers: { "x-session-id": UserSessionId }
47
+ },
48
+ realtime: {}
49
+ };
50
+ function createNewSupabaseClient(options) {
51
+ const client = createClient(
52
+ getSupabaseUrl(),
53
+ getSupabaseKey(),
54
+ {
55
+ ...defaultOptions,
56
+ ...options
57
+ }
58
+ );
59
+ onSupabaseInitializedAction && onSupabaseInitializedAction(client);
60
+ return client;
61
+ }
62
+ var onSupabaseInitializedAction = void 0;
63
+ function onSupabaseInitialized(afterInitialize) {
64
+ onSupabaseInitializedAction = afterInitialize;
65
+ }
66
+ function setDefaultOptions(options) {
67
+ defaultOptions = options;
68
+ }
69
+ var typedSupabase = null;
70
+ var context = createContext({
71
+ supabaseClient: typedSupabase
72
+ });
73
+ function useSupabase() {
74
+ const supabaseContext = useContext(context);
75
+ if (isUsable(supabaseContext?.supabaseClient) === false) {
76
+ throw new Error("Hook not inside a supabase context provider.");
77
+ }
78
+ return supabaseContext.supabaseClient;
79
+ }
80
+ function SupabaseProvider({
81
+ children,
82
+ options,
83
+ afterInitialize,
84
+ supabaseClient: supabaseClientProp
85
+ }) {
86
+ const [supabaseClient, setSupabaseClient] = useState(
87
+ () => supabaseClientProp ?? createNewSupabaseClient({
88
+ ...defaultOptions,
89
+ ...options ? options : {}
90
+ })
91
+ );
92
+ const [wasHidden, setWasHidden] = useState(false);
93
+ const [connected, setConnected] = useState(true);
94
+ useEffect(() => {
95
+ afterInitialize && afterInitialize(supabaseClient);
96
+ }, [supabaseClient]);
97
+ useEffect(() => {
98
+ const checkVisibility = async () => {
99
+ if (typeof window.document === "undefined") return;
100
+ if (document?.hidden) {
101
+ await delay(60 * 1e3).then((x) => {
102
+ if (document.hidden) {
103
+ setWasHidden(true);
104
+ }
105
+ });
106
+ } else if (wasHidden) {
107
+ setWasHidden(false);
108
+ try {
109
+ setConnected(true);
110
+ } catch (error) {
111
+ console.error("Reconnection failed:", error);
112
+ setConnected(false);
113
+ }
114
+ }
115
+ };
116
+ const intervalId = setInterval(checkVisibility, 1e3);
117
+ return () => {
118
+ clearInterval(intervalId);
119
+ };
120
+ }, [wasHidden]);
121
+ return /* @__PURE__ */ jsx(
122
+ context.Provider,
123
+ {
124
+ value: useMemo(() => ({ supabaseClient }), [supabaseClient]),
125
+ children
126
+ }
127
+ );
128
+ }
129
+
130
+ // src/client/useFunction.ts
131
+ function useFunction() {
132
+ const supabase = useSupabase();
133
+ async function downloadFunctionResponse(functionName, body, name) {
134
+ const { data, error } = await supabase.auth.getSession();
135
+ if (error || !data.session) {
136
+ console.error("Error retrieving session:", error);
137
+ return;
138
+ }
139
+ const accessToken = data.session.access_token;
140
+ const response = await fetch(
141
+ `${getSupabaseUrl()}/functions/v1/${functionName}`,
142
+ {
143
+ method: "POST",
144
+ headers: {
145
+ "Content-Type": body && "application/json",
146
+ Authorization: `Bearer ${accessToken}`
147
+ },
148
+ body: body && JSON.stringify(body)
149
+ }
150
+ );
151
+ if (!response.ok) {
152
+ console.error("Error downloading invoice:", response.statusText);
153
+ return;
154
+ }
155
+ const contentDisposition = response.headers.get("Content-Disposition");
156
+ const mimeType = response.headers.get("Content-Type") || "application/octet-stream";
157
+ const filename = name ? name : (contentDisposition && contentDisposition.split("filename=")[1]) ?? "Unknown";
158
+ await downloadFile(response.body, filename, mimeType);
159
+ }
160
+ return { downloadFunctionResponse };
161
+ }
162
+ async function downloadFile(stream, filename, mimeType) {
163
+ const reader = stream.getReader();
164
+ const a = document.createElement("a");
165
+ a.style.display = "none";
166
+ document.body.appendChild(a);
167
+ try {
168
+ const chunks = [];
169
+ while (true) {
170
+ const { done, value } = await reader.read();
171
+ if (done) break;
172
+ chunks.push(value);
173
+ }
174
+ const blob = new Blob(chunks, { type: mimeType });
175
+ const url = window.URL.createObjectURL(blob);
176
+ a.href = url;
177
+ a.download = filename;
178
+ a.click();
179
+ window.URL.revokeObjectURL(url);
180
+ } catch (error) {
181
+ console.error("Error downloading file:", error);
182
+ } finally {
183
+ document.body.removeChild(a);
184
+ reader.releaseLock();
185
+ }
186
+ }
187
+ export {
188
+ SupabaseProvider,
189
+ UserSessionId,
190
+ createNewSupabaseClient,
191
+ getSupabaseKey,
192
+ getSupabaseUrl,
193
+ onSupabaseInitialized,
194
+ setDefaultOptions,
195
+ setSupabaseKey,
196
+ setSupabaseUrl,
197
+ typedSupabase,
198
+ useFunction,
199
+ useSupabase
200
+ };
201
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../src/client/config.ts","../../src/client/useSupabase.tsx","../../src/client/useFunction.ts"],"sourcesContent":["let supabaseUrl = process.env.SUPABASE_URL;\nlet supabaseKey = process.env.SUPABASE_ANON_KEY ?? \"\";\n\nexport function setSupabaseUrl(url: string) {\n supabaseUrl = url;\n}\n\nexport function getSupabaseUrl() {\n return supabaseUrl;\n}\n\nexport function setSupabaseKey(key: string) {\n supabaseKey = key;\n}\n\nexport function getSupabaseKey() {\n return supabaseKey;\n}\n","import {\n createContext,\n ReactNode,\n useContext,\n useEffect,\n useMemo,\n useState,\n} from \"react\";\nimport {\n createClient,\n SupabaseClient,\n SupabaseClientOptions,\n} from \"@supabase/supabase-js\";\nimport { getSupabaseUrl, getSupabaseKey } from \"./config\";\n\n// This interface is augmented by consumers to provide their database types\n// Example: declare module '@pol-studios/db' { interface SupabaseDatabaseTypes { Database: MyDatabaseType } }\n// eslint-disable-next-line @typescript-eslint/no-empty-object-type\nexport interface SupabaseDatabaseTypes {}\n\nexport type Database = SupabaseDatabaseTypes extends { Database: infer D }\n ? D\n : any;\n\nexport type TypedSupabaseClient = SupabaseClient<Database>;\n\nfunction newUuid(): string {\n return crypto.randomUUID();\n}\n\nfunction isUsable<T>(value: T | null | undefined): value is T {\n return value !== null && value !== undefined;\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\nexport const UserSessionId = newUuid();\nlet defaultOptions: any = {\n auth: {\n autoRefreshToken: true,\n persistSession: true,\n detectSessionInUrl: true,\n },\n global: {\n headers: { \"x-session-id\": UserSessionId },\n },\n realtime: {},\n};\n\nexport function createNewSupabaseClient<\n SchemaName extends string & keyof Database = \"public\" extends keyof Database\n ? \"public\"\n : string & keyof Database,\n>(options?: SupabaseClientOptions<SchemaName>) {\n const client = createClient<Database, SchemaName>(\n getSupabaseUrl()!,\n getSupabaseKey()!,\n {\n ...defaultOptions,\n ...options,\n }\n );\n\n onSupabaseInitializedAction && onSupabaseInitializedAction(client as any);\n\n return client;\n}\n\nlet onSupabaseInitializedAction:\n | ((supabase: SupabaseClient) => any)\n | undefined = undefined;\n\nexport function onSupabaseInitialized(\n afterInitialize: (supabase: SupabaseClient) => any\n) {\n onSupabaseInitializedAction = afterInitialize;\n}\n\nexport function setDefaultOptions(\n options: SupabaseClientOptions<string & keyof Database>\n) {\n defaultOptions = options;\n}\n\nexport let typedSupabase: SupabaseClient<Database> = null!;\n\nconst context = createContext({\n supabaseClient: typedSupabase as SupabaseClient<Database> | null,\n});\n\nexport default function useSupabase() {\n const supabaseContext = useContext(context);\n if (isUsable(supabaseContext?.supabaseClient) === false) {\n throw new Error(\"Hook not inside a supabase context provider.\");\n }\n\n return supabaseContext.supabaseClient!;\n}\n\nexport function SupabaseProvider({\n children,\n options,\n afterInitialize,\n supabaseClient: supabaseClientProp,\n}: {\n children: ReactNode;\n options?: SupabaseClientOptions<string & keyof Database>;\n afterInitialize?: (supabase: SupabaseClient<Database>) => any;\n supabaseClient?: SupabaseClient<Database>;\n}) {\n const [supabaseClient, setSupabaseClient] = useState(\n () =>\n supabaseClientProp ??\n (createNewSupabaseClient({\n ...defaultOptions,\n ...(options ? options : {}),\n }) as unknown as SupabaseClient<Database>)\n );\n\n const [wasHidden, setWasHidden] = useState<boolean>(false);\n const [connected, setConnected] = useState<boolean>(true);\n\n useEffect(() => {\n afterInitialize && afterInitialize(supabaseClient);\n }, [supabaseClient]);\n\n useEffect(() => {\n const checkVisibility = async () => {\n if (typeof window.document === \"undefined\") return;\n if (document?.hidden) {\n await delay(60 * 1000).then((x) => {\n if (document.hidden) {\n setWasHidden(true);\n }\n });\n } else if (wasHidden) {\n setWasHidden(false);\n try {\n setConnected(true);\n } catch (error) {\n console.error(\"Reconnection failed:\", error);\n setConnected(false);\n }\n }\n };\n\n const intervalId = setInterval(checkVisibility, 1000);\n\n return () => {\n clearInterval(intervalId);\n };\n }, [wasHidden]);\n\n return (\n <context.Provider\n value={useMemo(() => ({ supabaseClient }), [supabaseClient])}\n >\n {children}\n </context.Provider>\n );\n}\n","import { getSupabaseUrl } from \"./config\";\nimport useSupabase from \"./useSupabase\";\n\nexport default function useFunction() {\n const supabase = useSupabase();\n\n async function downloadFunctionResponse(\n functionName: string,\n body?: any,\n name?: string,\n ) {\n const { data, error } = await supabase.auth.getSession();\n if (error || !data.session) {\n console.error(\"Error retrieving session:\", error);\n return;\n }\n\n const accessToken = data.session.access_token;\n\n const response = await fetch(\n `${getSupabaseUrl()}/functions/v1/${functionName}`,\n {\n method: \"POST\",\n headers: {\n \"Content-Type\": body && \"application/json\",\n Authorization: `Bearer ${accessToken}`,\n },\n body: body && JSON.stringify(body),\n },\n );\n\n if (!response.ok) {\n console.error(\"Error downloading invoice:\", response.statusText);\n return;\n }\n\n const contentDisposition = response.headers.get(\"Content-Disposition\");\n const mimeType = response.headers.get(\"Content-Type\") ||\n \"application/octet-stream\";\n const filename = name\n ? name\n : (contentDisposition && contentDisposition.split(\"filename=\")[1]) ??\n \"Unknown\";\n\n await downloadFile(response.body!, filename, mimeType);\n }\n\n return { downloadFunctionResponse };\n}\n\nasync function downloadFile(\n stream: ReadableStream<Uint8Array>,\n filename: string,\n mimeType: string,\n) {\n const reader = stream.getReader();\n const a = document.createElement(\"a\");\n a.style.display = \"none\";\n document.body.appendChild(a);\n\n try {\n const chunks: Uint8Array[] = [];\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n chunks.push(value);\n }\n\n const blob = new Blob(chunks as BlobPart[], { type: mimeType });\n const url = window.URL.createObjectURL(blob);\n a.href = url;\n a.download = filename;\n a.click();\n window.URL.revokeObjectURL(url);\n } catch (error) {\n console.error(\"Error downloading file:\", error);\n } finally {\n document.body.removeChild(a);\n reader.releaseLock();\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1 @@
1
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}