@basictech/react 0.2.0-beta.5 → 0.2.0-beta.6

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.
@@ -139,7 +139,7 @@ type ErrorObject = {
139
139
  message: string;
140
140
  }
141
141
 
142
- export function BasicProvider({ children, project_id, schema }: { children: React.ReactNode, project_id: string, schema: any }) {
142
+ export function BasicProvider({ children, project_id, schema, debug = false }: { children: React.ReactNode, project_id: string, schema: any, debug?: boolean }) {
143
143
  const [isLoaded, setIsLoaded] = useState(false)
144
144
  const [isSignedIn, setIsSignedIn] = useState(false)
145
145
  const [token, setToken] = useState<Token | null>(null)
@@ -155,11 +155,11 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
155
155
  useEffect(() => {
156
156
  function initDb() {
157
157
  if (!validator(schema)) {
158
- console.error('Basic Schema is invalid!', validator.errors)
158
+ log('Basic Schema is invalid!', validator.errors)
159
159
  console.group('Schema Errors')
160
160
  let errorMessage = ''
161
161
  validator.errors.forEach((error, index) => {
162
- console.log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`)
162
+ log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`)
163
163
  errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}\n`
164
164
  })
165
165
  console.groupEnd('Schema Errors')
@@ -175,10 +175,10 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
175
175
  if (!syncRef.current) {
176
176
  syncRef.current = new BasicSync('basicdb', { schema: schema });
177
177
 
178
- // console.log('db is open', syncRef.current.isOpen())
178
+ // log('db is open', syncRef.current.isOpen())
179
179
  // syncRef.current.open()
180
180
  // .then(() => {
181
- // console.log("is open now:", syncRef.current.isOpen())
181
+ // log("is open now:", syncRef.current.isOpen())
182
182
  // })
183
183
 
184
184
  syncRef.current.handleStatusChange((status: number, url: string) => {
@@ -186,7 +186,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
186
186
  })
187
187
 
188
188
  syncRef.current.syncable.getStatus().then((status) => {
189
- console.log('sync status', getSyncStatus(status))
189
+ log('sync status', getSyncStatus(status))
190
190
  })
191
191
  }
192
192
 
@@ -203,11 +203,11 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
203
203
 
204
204
  const tok = await getToken()
205
205
 
206
- console.log('connecting to db...', tok.substring(0, 10))
206
+ log('connecting to db...', tok.substring(0, 10))
207
207
 
208
208
  syncRef.current.connect({ access_token: tok })
209
209
  .catch((e) => {
210
- console.log('error connecting to db', e)
210
+ log('error connecting to db', e)
211
211
  })
212
212
  }
213
213
 
@@ -218,7 +218,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
218
218
  }, [token])
219
219
 
220
220
  const getSignInLink = () => {
221
- console.log('getting sign in link...')
221
+ log('getting sign in link...')
222
222
 
223
223
  const randomState = Math.random().toString(36).substring(7);
224
224
 
@@ -233,14 +233,14 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
233
233
  }
234
234
 
235
235
  const signin = () => {
236
- console.log('signing in: ', getSignInLink())
236
+ log('signing in: ', getSignInLink())
237
237
  const signInLink = getSignInLink()
238
238
  //todo: change to the other thing?
239
239
  window.location.href = signInLink;
240
240
  }
241
241
 
242
242
  const signout = () => {
243
- console.log('signing out!')
243
+ log('signing out!')
244
244
  setUser({})
245
245
  setIsSignedIn(false)
246
246
  setToken(null)
@@ -249,10 +249,10 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
249
249
  }
250
250
 
251
251
  const getToken = async (): Promise<string> => {
252
- console.log('getting token...')
252
+ log('getting token...')
253
253
 
254
254
  if (!token) {
255
- console.log('no token found')
255
+ log('no token found')
256
256
  throw new Error('no token found')
257
257
  }
258
258
 
@@ -260,7 +260,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
260
260
  const isExpired = decoded.exp && decoded.exp < Date.now() / 1000
261
261
 
262
262
  if (isExpired) {
263
- console.log('token is expired - refreshing ...')
263
+ log('token is expired - refreshing ...')
264
264
  const newToken = await fetchToken(token?.refresh)
265
265
  return newToken?.access_token || ''
266
266
  }
@@ -292,19 +292,21 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
292
292
  body: JSON.stringify({ code: code })
293
293
  })
294
294
  .then(response => response.json())
295
- .catch(error => console.error('Error:', error))
295
+ .catch(error => log('Error:', error))
296
296
 
297
297
  if (token.error) {
298
- console.log('error fetching token', token.error)
298
+ log('error fetching token', token.error)
299
299
  return
300
300
  } else {
301
- // console.log('token', token)
301
+ // log('token', token)
302
302
  setToken(token)
303
303
  }
304
304
  return token
305
305
  }
306
306
 
307
307
  useEffect(() => {
308
+ localStorage.setItem('basic_debug', debug ? 'true' : 'false')
309
+
308
310
  try {
309
311
  let cookie_token = getCookie('basic_token')
310
312
  if (cookie_token !== '') {
@@ -313,7 +315,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
313
315
 
314
316
  if (window.location.search.includes('code')) {
315
317
  let code = window.location?.search?.split('code=')[1].split('&')[0]
316
- // console.log('code found', code)
318
+ // log('code found', code)
317
319
 
318
320
  // todo: check state is valid
319
321
  setAuthCode(code) // remove this? dont need to store code?
@@ -325,7 +327,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
325
327
  setIsLoaded(true)
326
328
  }
327
329
  } catch (e) {
328
- console.log('error getting cookie', e)
330
+ log('error getting cookie', e)
329
331
  }
330
332
  }, [])
331
333
 
@@ -338,14 +340,14 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
338
340
  }
339
341
  })
340
342
  .then(response => response.json())
341
- .catch(error => console.error('Error:', error))
343
+ .catch(error => log('Error:', error))
342
344
 
343
345
  if (user.error) {
344
- console.log('error fetching user', user.error)
346
+ log('error fetching user', user.error)
345
347
  // refreshToken()
346
348
  return
347
349
  } else {
348
- // console.log('user', user)
350
+ // log('user', user)
349
351
  document.cookie = `basic_token=${JSON.stringify(token)}; Secure; SameSite=Strict`;
350
352
  setUser(user)
351
353
  setIsSignedIn(true)
@@ -355,7 +357,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
355
357
 
356
358
  async function checkToken() {
357
359
  if (!token) {
358
- console.log('error: no user token found')
360
+ log('error: no user token found')
359
361
  return
360
362
  }
361
363
 
@@ -363,7 +365,7 @@ export function BasicProvider({ children, project_id, schema }: { children: Reac
363
365
  const isExpired = decoded.exp && decoded.exp < Date.now() / 1000
364
366
 
365
367
  if (isExpired) {
366
- console.log('token is expired - refreshing ...')
368
+ log('token is expired - refreshing ...')
367
369
  const newToken = await fetchToken(token?.refresh)
368
370
  fetchUser(newToken.access_token)
369
371
  } else {
@@ -459,4 +461,4 @@ possible errors:
459
461
 
460
462
  export function useBasic() {
461
463
  return useContext(BasicContext);
462
- }
464
+ }
package/src/config.ts CHANGED
@@ -4,11 +4,27 @@ export const SERVER_URL = "https://api.basic.tech"
4
4
  // export const WS_URL = `${SERVER_URL}/ws`
5
5
 
6
6
  export const log = (...args: any[]) => {
7
- if (process.env.NODE_ENV === 'development') {
8
- console.log(...args)
9
- }
7
+ try {
8
+ if (localStorage.getItem('basic_debug') === 'true') {
9
+ console.log('[basic]', ...args)
10
+ }
11
+ } catch (e) {
12
+ // console.log('error logging', e)
13
+ }
10
14
  }
11
15
 
16
+ // export const log = (message: string, ...args: any[]) => {
17
+ // try {
18
+ // if (process.env.NODE_ENV === 'development') {
19
+ // const stack = new Error().stack;
20
+ // const caller = stack?.split('\n')[2]?.trim();
21
+ // console.log(`[basic] ${message}`, ...args);
22
+ // // console.log(`[stack] ${caller}`);
23
+ // }
24
+ // } catch (e) {
25
+ // console.error('Error in logWithStack:', e);
26
+ // }
27
+ // }
12
28
 
13
29
  const basicJsonSchema = {
14
30
  "$schema": "http://json-schema.org/draft-07/schema#",
package/src/sync/index.ts CHANGED
@@ -9,7 +9,7 @@ import 'dexie-syncable';
9
9
  import 'dexie-observable';
10
10
 
11
11
  import { syncProtocol } from './syncProtocol'
12
- import { SERVER_URL } from '../config'
12
+ import { SERVER_URL, log } from '../config'
13
13
  syncProtocol()
14
14
 
15
15
 
@@ -67,7 +67,7 @@ export class BasicSync extends Dexie {
67
67
 
68
68
  // Proceed with the WebSocket connection
69
69
 
70
- console.log('Starting connection...')
70
+ log('Starting connection...')
71
71
  return this.syncable.connect("websocket", WS_URL, { authToken: access_token });
72
72
  }
73
73
 
@@ -75,7 +75,7 @@ export class BasicSync extends Dexie {
75
75
  try {
76
76
  const syncNodes = await this.table('_syncNodes').toArray();
77
77
  const localSyncNodes = syncNodes.filter(node => node.type === 'local');
78
- console.log('Local sync nodes:', localSyncNodes);
78
+ log('Local sync nodes:', localSyncNodes);
79
79
 
80
80
  if (localSyncNodes.length > 1) {
81
81
 
@@ -84,19 +84,19 @@ export class BasicSync extends Dexie {
84
84
  // Check if the largest node is already the master
85
85
  const largestNode = localSyncNodes.find(node => node.id === largestNodeId);
86
86
  if (largestNode && largestNode.isMaster === 1) {
87
- console.log('Largest node is already the master. No changes needed.');
87
+ log('Largest node is already the master. No changes needed.');
88
88
  return; // Exit the function early as no changes are needed
89
89
  }
90
90
 
91
91
 
92
- console.log('Largest node id:', largestNodeId);
93
- console.error('HEISENBUG: More than one local sync node found.')
92
+ log('Largest node id:', largestNodeId);
93
+ log('HEISENBUG: More than one local sync node found.')
94
94
 
95
95
  for (const node of localSyncNodes) {
96
- console.log(`Local sync node keys:`, node.id, node.isMaster);
96
+ log(`Local sync node keys:`, node.id, node.isMaster);
97
97
  await this.table('_syncNodes').update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });
98
98
 
99
- console.log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? 'master' : '0'}`);
99
+ log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? 'master' : '0'}`);
100
100
  }
101
101
 
102
102
  // Add a 1 second delay before returning // i dont think this helps?
@@ -104,7 +104,7 @@ export class BasicSync extends Dexie {
104
104
 
105
105
  }
106
106
 
107
- console.log('Sync nodes updated');
107
+ log('Sync nodes updated');
108
108
  } catch (error) {
109
109
  console.error('Error updating _syncNodes table:', error);
110
110
  }
@@ -150,7 +150,7 @@ export class BasicSync extends Dexie {
150
150
 
151
151
  // --- WRITE ---- //
152
152
  add: (data: any) => {
153
- console.log("Adding data to", name, data)
153
+ log("Adding data to", name, data)
154
154
  return this.table(name).add({
155
155
  id: uuidv7(),
156
156
  ...data
@@ -1,8 +1,9 @@
1
1
  "use client"
2
2
  import { Dexie } from "dexie";
3
+ import { log } from "../config";
3
4
 
4
5
  export const syncProtocol = function () {
5
- console.log("Initializing syncProtocol");
6
+ log("Initializing syncProtocol");
6
7
  // Constants:
7
8
  var RECONNECT_DELAY = 5000; // Reconnect delay in case of errors such as network down.
8
9
 
@@ -31,7 +32,7 @@ export const syncProtocol = function () {
31
32
 
32
33
  // sendChanges() method:
33
34
  function sendChanges(changes, baseRevision, partial, onChangesAccepted) {
34
- console.log("sendChanges", changes.length, baseRevision);
35
+ log("sendChanges", changes.length, baseRevision);
35
36
  ++requestId;
36
37
  acceptCallbacks[requestId.toString()] = onChangesAccepted;
37
38
 
@@ -65,7 +66,7 @@ export const syncProtocol = function () {
65
66
  // Initiate this socket connection by sending our clientIdentity. If we dont have a clientIdentity yet,
66
67
  // server will call back with a new client identity that we should use in future WebSocket connections.
67
68
 
68
- console.log("Opening socket - sending clientIdentity", context.clientIdentity);
69
+ log("Opening socket - sending clientIdentity", context.clientIdentity);
69
70
  ws.send(
70
71
  JSON.stringify({
71
72
  type: "clientIdentity",
@@ -79,7 +80,7 @@ export const syncProtocol = function () {
79
80
  // If network down or other error, tell the framework to reconnect again in some time:
80
81
  ws.onerror = function (event) {
81
82
  ws.close();
82
- console.log("ws.onerror", event);
83
+ log("ws.onerror", event);
83
84
  onError(event?.message, RECONNECT_DELAY);
84
85
  };
85
86
 
@@ -109,7 +110,7 @@ export const syncProtocol = function () {
109
110
  // partial: true if server has additionalChanges to send. False if these changes were the last known. (applicable if type="changes")
110
111
  // }
111
112
  var requestFromServer = JSON.parse(event.data);
112
- console.log("requestFromServer", requestFromServer, { acceptCallback, isFirstRound });
113
+ log("requestFromServer", requestFromServer, { acceptCallback, isFirstRound });
113
114
 
114
115
  if (requestFromServer.type == "clientIdentity") {
115
116
  context.clientIdentity = requestFromServer.clientIdentity;
@@ -164,7 +165,7 @@ export const syncProtocol = function () {
164
165
  ws.close();
165
166
  onError(requestFromServer.message, Infinity); // Don't reconnect - an error in application level means we have done something wrong.
166
167
  } else {
167
- console.log("unknown message", requestFromServer);
168
+ log("unknown message", requestFromServer);
168
169
  ws.close();
169
170
  onError("unknown message", Infinity);
170
171
  }