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

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 CHANGED
@@ -1,5 +1,20 @@
1
1
  # 1.3.4
2
2
 
3
+ ## 0.2.0-beta.7
4
+
5
+ ### Minor Changes
6
+
7
+ - update useQuery hook
8
+
9
+ - no need to pass param as a function, can now enter query directly
10
+ - defaults to empty array when loading
11
+
12
+ ## 0.2.0-beta.6
13
+
14
+ ### Minor Changes
15
+
16
+ - add debug option
17
+
3
18
  ## 0.2.0-beta.5
4
19
 
5
20
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -1,6 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
- export { useLiveQuery as useQuery } from 'dexie-react-hooks';
4
3
 
5
4
  declare enum DBStatus {
6
5
  LOADING = "LOADING",
@@ -19,10 +18,11 @@ type User = {
19
18
  };
20
19
  fullName?: string;
21
20
  };
22
- declare function BasicProvider({ children, project_id, schema }: {
21
+ declare function BasicProvider({ children, project_id, schema, debug }: {
23
22
  children: React.ReactNode;
24
23
  project_id: string;
25
24
  schema: any;
25
+ debug?: boolean;
26
26
  }): react_jsx_runtime.JSX.Element;
27
27
  declare function useBasic(): {
28
28
  unicorn: string;
@@ -37,4 +37,6 @@ declare function useBasic(): {
37
37
  dbStatus: DBStatus;
38
38
  };
39
39
 
40
- export { BasicProvider, useBasic };
40
+ declare function useQuery(queryable: any): any;
41
+
42
+ export { BasicProvider, useBasic, useQuery };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,5 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
2
  import React from 'react';
3
- export { useLiveQuery as useQuery } from 'dexie-react-hooks';
4
3
 
5
4
  declare enum DBStatus {
6
5
  LOADING = "LOADING",
@@ -19,10 +18,11 @@ type User = {
19
18
  };
20
19
  fullName?: string;
21
20
  };
22
- declare function BasicProvider({ children, project_id, schema }: {
21
+ declare function BasicProvider({ children, project_id, schema, debug }: {
23
22
  children: React.ReactNode;
24
23
  project_id: string;
25
24
  schema: any;
25
+ debug?: boolean;
26
26
  }): react_jsx_runtime.JSX.Element;
27
27
  declare function useBasic(): {
28
28
  unicorn: string;
@@ -37,4 +37,6 @@ declare function useBasic(): {
37
37
  dbStatus: DBStatus;
38
38
  };
39
39
 
40
- export { BasicProvider, useBasic };
40
+ declare function useQuery(queryable: any): any;
41
+
42
+ export { BasicProvider, useBasic, useQuery };
package/dist/index.js CHANGED
@@ -32,7 +32,7 @@ var src_exports = {};
32
32
  __export(src_exports, {
33
33
  BasicProvider: () => BasicProvider,
34
34
  useBasic: () => useBasic,
35
- useQuery: () => import_dexie_react_hooks.useLiveQuery
35
+ useQuery: () => useQuery
36
36
  });
37
37
  module.exports = __toCommonJS(src_exports);
38
38
 
@@ -48,8 +48,81 @@ var import_dexie_observable = require("dexie-observable");
48
48
 
49
49
  // src/sync/syncProtocol.js
50
50
  var import_dexie = require("dexie");
51
+
52
+ // src/config.ts
53
+ var import_ajv = __toESM(require("ajv"));
54
+ var SERVER_URL = "https://api.basic.tech";
55
+ var log = (...args) => {
56
+ try {
57
+ if (localStorage.getItem("basic_debug") === "true") {
58
+ console.log("[basic]", ...args);
59
+ }
60
+ } catch (e) {
61
+ }
62
+ };
63
+ var basicJsonSchema = {
64
+ "$schema": "http://json-schema.org/draft-07/schema#",
65
+ "type": "object",
66
+ "properties": {
67
+ "project_id": {
68
+ "type": "string"
69
+ },
70
+ "namespace": {
71
+ "type": "string"
72
+ },
73
+ "version": {
74
+ "type": "integer",
75
+ "minimum": 0
76
+ },
77
+ "tables": {
78
+ "type": "object",
79
+ "patternProperties": {
80
+ "^[a-zA-Z0-9_]+$": {
81
+ "type": "object",
82
+ "properties": {
83
+ "name": {
84
+ "type": "string"
85
+ },
86
+ "type": {
87
+ "type": "string",
88
+ "enum": ["collection"]
89
+ },
90
+ "fields": {
91
+ "type": "object",
92
+ "patternProperties": {
93
+ "^[a-zA-Z0-9_]+$": {
94
+ "type": "object",
95
+ "properties": {
96
+ "type": {
97
+ "type": "string"
98
+ },
99
+ "primary": {
100
+ "type": "boolean"
101
+ },
102
+ "indexed": {
103
+ "type": "boolean"
104
+ }
105
+ },
106
+ "required": ["type"]
107
+ }
108
+ },
109
+ "additionalProperties": true
110
+ }
111
+ },
112
+ "required": ["fields"]
113
+ }
114
+ },
115
+ "additionalProperties": true
116
+ }
117
+ },
118
+ "required": ["project_id", "version", "tables"]
119
+ };
120
+ var ajv = new import_ajv.default();
121
+ var validator = ajv.compile(basicJsonSchema);
122
+
123
+ // src/sync/syncProtocol.js
51
124
  var syncProtocol = function() {
52
- console.log("Initializing syncProtocol");
125
+ log("Initializing syncProtocol");
53
126
  var RECONNECT_DELAY = 5e3;
54
127
  import_dexie.Dexie.Syncable.registerSyncProtocol("websocket", {
55
128
  sync: function(context, url, options, baseRevision, syncedRevision, changes, partial, applyRemoteChanges, onChangesAccepted, onSuccess, onError) {
@@ -57,7 +130,7 @@ var syncProtocol = function() {
57
130
  var acceptCallbacks = {};
58
131
  var ws = new WebSocket(url);
59
132
  function sendChanges(changes2, baseRevision2, partial2, onChangesAccepted2) {
60
- console.log("sendChanges", changes2.length, baseRevision2);
133
+ log("sendChanges", changes2.length, baseRevision2);
61
134
  ++requestId;
62
135
  acceptCallbacks[requestId.toString()] = onChangesAccepted2;
63
136
  ws.send(
@@ -71,7 +144,7 @@ var syncProtocol = function() {
71
144
  );
72
145
  }
73
146
  ws.onopen = function(event) {
74
- console.log("Opening socket - sending clientIdentity", context.clientIdentity);
147
+ log("Opening socket - sending clientIdentity", context.clientIdentity);
75
148
  ws.send(
76
149
  JSON.stringify({
77
150
  type: "clientIdentity",
@@ -82,7 +155,7 @@ var syncProtocol = function() {
82
155
  };
83
156
  ws.onerror = function(event) {
84
157
  ws.close();
85
- console.log("ws.onerror", event);
158
+ log("ws.onerror", event);
86
159
  onError(event?.message, RECONNECT_DELAY);
87
160
  };
88
161
  ws.onclose = function(event) {
@@ -92,7 +165,7 @@ var syncProtocol = function() {
92
165
  ws.onmessage = function(event) {
93
166
  try {
94
167
  var requestFromServer = JSON.parse(event.data);
95
- console.log("requestFromServer", requestFromServer, { acceptCallback, isFirstRound });
168
+ log("requestFromServer", requestFromServer, { acceptCallback, isFirstRound });
96
169
  if (requestFromServer.type == "clientIdentity") {
97
170
  context.clientIdentity = requestFromServer.clientIdentity;
98
171
  context.save();
@@ -138,7 +211,7 @@ var syncProtocol = function() {
138
211
  ws.close();
139
212
  onError(requestFromServer.message, Infinity);
140
213
  } else {
141
- console.log("unknown message", requestFromServer);
214
+ log("unknown message", requestFromServer);
142
215
  ws.close();
143
216
  onError("unknown message", Infinity);
144
217
  }
@@ -151,69 +224,6 @@ var syncProtocol = function() {
151
224
  });
152
225
  };
153
226
 
154
- // src/config.ts
155
- var import_ajv = __toESM(require("ajv"));
156
- var SERVER_URL = "https://api.basic.tech";
157
- var basicJsonSchema = {
158
- "$schema": "http://json-schema.org/draft-07/schema#",
159
- "type": "object",
160
- "properties": {
161
- "project_id": {
162
- "type": "string"
163
- },
164
- "namespace": {
165
- "type": "string"
166
- },
167
- "version": {
168
- "type": "integer",
169
- "minimum": 0
170
- },
171
- "tables": {
172
- "type": "object",
173
- "patternProperties": {
174
- "^[a-zA-Z0-9_]+$": {
175
- "type": "object",
176
- "properties": {
177
- "name": {
178
- "type": "string"
179
- },
180
- "type": {
181
- "type": "string",
182
- "enum": ["collection"]
183
- },
184
- "fields": {
185
- "type": "object",
186
- "patternProperties": {
187
- "^[a-zA-Z0-9_]+$": {
188
- "type": "object",
189
- "properties": {
190
- "type": {
191
- "type": "string"
192
- },
193
- "primary": {
194
- "type": "boolean"
195
- },
196
- "indexed": {
197
- "type": "boolean"
198
- }
199
- },
200
- "required": ["type"]
201
- }
202
- },
203
- "additionalProperties": true
204
- }
205
- },
206
- "required": ["fields"]
207
- }
208
- },
209
- "additionalProperties": true
210
- }
211
- },
212
- "required": ["project_id", "version", "tables"]
213
- };
214
- var ajv = new import_ajv.default();
215
- var validator = ajv.compile(basicJsonSchema);
216
-
217
227
  // src/sync/index.ts
218
228
  syncProtocol();
219
229
  var BasicSync = class extends import_dexie2.Dexie {
@@ -228,31 +238,31 @@ var BasicSync = class extends import_dexie2.Dexie {
228
238
  async connect({ access_token }) {
229
239
  const WS_URL = `${SERVER_URL}/ws`;
230
240
  await this.updateSyncNodes();
231
- console.log("Starting connection...");
241
+ log("Starting connection...");
232
242
  return this.syncable.connect("websocket", WS_URL, { authToken: access_token });
233
243
  }
234
244
  async updateSyncNodes() {
235
245
  try {
236
246
  const syncNodes = await this.table("_syncNodes").toArray();
237
247
  const localSyncNodes = syncNodes.filter((node) => node.type === "local");
238
- console.log("Local sync nodes:", localSyncNodes);
248
+ log("Local sync nodes:", localSyncNodes);
239
249
  if (localSyncNodes.length > 1) {
240
250
  const largestNodeId = Math.max(...localSyncNodes.map((node) => node.id));
241
251
  const largestNode = localSyncNodes.find((node) => node.id === largestNodeId);
242
252
  if (largestNode && largestNode.isMaster === 1) {
243
- console.log("Largest node is already the master. No changes needed.");
253
+ log("Largest node is already the master. No changes needed.");
244
254
  return;
245
255
  }
246
- console.log("Largest node id:", largestNodeId);
247
- console.error("HEISENBUG: More than one local sync node found.");
256
+ log("Largest node id:", largestNodeId);
257
+ log("HEISENBUG: More than one local sync node found.");
248
258
  for (const node of localSyncNodes) {
249
- console.log(`Local sync node keys:`, node.id, node.isMaster);
259
+ log(`Local sync node keys:`, node.id, node.isMaster);
250
260
  await this.table("_syncNodes").update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });
251
- console.log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? "master" : "0"}`);
261
+ log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? "master" : "0"}`);
252
262
  }
253
263
  await new Promise((resolve) => setTimeout(resolve, 2e3));
254
264
  }
255
- console.log("Sync nodes updated");
265
+ log("Sync nodes updated");
256
266
  } catch (error) {
257
267
  console.error("Error updating _syncNodes table:", error);
258
268
  }
@@ -281,7 +291,7 @@ var BasicSync = class extends import_dexie2.Dexie {
281
291
  ref: this.table(name),
282
292
  // --- WRITE ---- //
283
293
  add: (data) => {
284
- console.log("Adding data to", name, data);
294
+ log("Adding data to", name, data);
285
295
  return this.table(name).add({
286
296
  id: (0, import_uuid.v7)(),
287
297
  ...data
@@ -300,10 +310,10 @@ var BasicSync = class extends import_dexie2.Dexie {
300
310
  return this.table(name).delete(id);
301
311
  },
302
312
  // --- READ ---- //
303
- get: (id) => {
313
+ get: async (id) => {
304
314
  return this.table(name).get(id);
305
315
  },
306
- getAll: () => {
316
+ getAll: async () => {
307
317
  return this.table(name).toArray();
308
318
  },
309
319
  // --- QUERY ---- //
@@ -395,7 +405,7 @@ function getSyncStatus(statusCode) {
395
405
  return "UNKNOWN";
396
406
  }
397
407
  }
398
- function BasicProvider({ children, project_id, schema }) {
408
+ function BasicProvider({ children, project_id, schema, debug = false }) {
399
409
  const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
400
410
  const [isSignedIn, setIsSignedIn] = (0, import_react.useState)(false);
401
411
  const [token, setToken] = (0, import_react.useState)(null);
@@ -407,11 +417,11 @@ function BasicProvider({ children, project_id, schema }) {
407
417
  (0, import_react.useEffect)(() => {
408
418
  function initDb() {
409
419
  if (!validator(schema)) {
410
- console.error("Basic Schema is invalid!", validator.errors);
420
+ log("Basic Schema is invalid!", validator.errors);
411
421
  console.group("Schema Errors");
412
422
  let errorMessage = "";
413
423
  validator.errors.forEach((error2, index) => {
414
- console.log(`${index + 1}:`, error2.message, ` - at ${error2.instancePath}`);
424
+ log(`${index + 1}:`, error2.message, ` - at ${error2.instancePath}`);
415
425
  errorMessage += `${index + 1}: ${error2.message} - at ${error2.instancePath}
416
426
  `;
417
427
  });
@@ -429,7 +439,7 @@ function BasicProvider({ children, project_id, schema }) {
429
439
  setDbStatus(getSyncStatus(status));
430
440
  });
431
441
  syncRef.current.syncable.getStatus().then((status) => {
432
- console.log("sync status", getSyncStatus(status));
442
+ log("sync status", getSyncStatus(status));
433
443
  });
434
444
  }
435
445
  }
@@ -437,9 +447,9 @@ function BasicProvider({ children, project_id, schema }) {
437
447
  }, []);
438
448
  const connectToDb = async () => {
439
449
  const tok = await getToken();
440
- console.log("connecting to db...", tok.substring(0, 10));
450
+ log("connecting to db...", tok.substring(0, 10));
441
451
  syncRef.current.connect({ access_token: tok }).catch((e) => {
442
- console.log("error connecting to db", e);
452
+ log("error connecting to db", e);
443
453
  });
444
454
  };
445
455
  (0, import_react.useEffect)(() => {
@@ -448,7 +458,7 @@ function BasicProvider({ children, project_id, schema }) {
448
458
  }
449
459
  }, [token]);
450
460
  const getSignInLink = () => {
451
- console.log("getting sign in link...");
461
+ log("getting sign in link...");
452
462
  const randomState = Math.random().toString(36).substring(7);
453
463
  let baseUrl2 = "https://api.basic.tech/auth/authorize";
454
464
  baseUrl2 += `?client_id=${project_id}`;
@@ -459,12 +469,12 @@ function BasicProvider({ children, project_id, schema }) {
459
469
  return baseUrl2;
460
470
  };
461
471
  const signin = () => {
462
- console.log("signing in: ", getSignInLink());
472
+ log("signing in: ", getSignInLink());
463
473
  const signInLink = getSignInLink();
464
474
  window.location.href = signInLink;
465
475
  };
466
476
  const signout = () => {
467
- console.log("signing out!");
477
+ log("signing out!");
468
478
  setUser({});
469
479
  setIsSignedIn(false);
470
480
  setToken(null);
@@ -472,15 +482,15 @@ function BasicProvider({ children, project_id, schema }) {
472
482
  document.cookie = `basic_token=; Secure; SameSite=Strict`;
473
483
  };
474
484
  const getToken = async () => {
475
- console.log("getting token...");
485
+ log("getting token...");
476
486
  if (!token) {
477
- console.log("no token found");
487
+ log("no token found");
478
488
  throw new Error("no token found");
479
489
  }
480
490
  const decoded = (0, import_jwt_decode.jwtDecode)(token?.access_token);
481
491
  const isExpired = decoded.exp && decoded.exp < Date.now() / 1e3;
482
492
  if (isExpired) {
483
- console.log("token is expired - refreshing ...");
493
+ log("token is expired - refreshing ...");
484
494
  const newToken = await fetchToken(token?.refresh);
485
495
  return newToken?.access_token || "";
486
496
  }
@@ -507,9 +517,9 @@ function BasicProvider({ children, project_id, schema }) {
507
517
  "Content-Type": "application/json"
508
518
  },
509
519
  body: JSON.stringify({ code })
510
- }).then((response) => response.json()).catch((error2) => console.error("Error:", error2));
520
+ }).then((response) => response.json()).catch((error2) => log("Error:", error2));
511
521
  if (token2.error) {
512
- console.log("error fetching token", token2.error);
522
+ log("error fetching token", token2.error);
513
523
  return;
514
524
  } else {
515
525
  setToken(token2);
@@ -517,6 +527,7 @@ function BasicProvider({ children, project_id, schema }) {
517
527
  return token2;
518
528
  };
519
529
  (0, import_react.useEffect)(() => {
530
+ localStorage.setItem("basic_debug", debug ? "true" : "false");
520
531
  try {
521
532
  let cookie_token = getCookie("basic_token");
522
533
  if (cookie_token !== "") {
@@ -531,7 +542,7 @@ function BasicProvider({ children, project_id, schema }) {
531
542
  setIsLoaded(true);
532
543
  }
533
544
  } catch (e) {
534
- console.log("error getting cookie", e);
545
+ log("error getting cookie", e);
535
546
  }
536
547
  }, []);
537
548
  (0, import_react.useEffect)(() => {
@@ -541,9 +552,9 @@ function BasicProvider({ children, project_id, schema }) {
541
552
  headers: {
542
553
  "Authorization": `Bearer ${acc_token}`
543
554
  }
544
- }).then((response) => response.json()).catch((error2) => console.error("Error:", error2));
555
+ }).then((response) => response.json()).catch((error2) => log("Error:", error2));
545
556
  if (user2.error) {
546
- console.log("error fetching user", user2.error);
557
+ log("error fetching user", user2.error);
547
558
  return;
548
559
  } else {
549
560
  document.cookie = `basic_token=${JSON.stringify(token)}; Secure; SameSite=Strict`;
@@ -554,13 +565,13 @@ function BasicProvider({ children, project_id, schema }) {
554
565
  }
555
566
  async function checkToken() {
556
567
  if (!token) {
557
- console.log("error: no user token found");
568
+ log("error: no user token found");
558
569
  return;
559
570
  }
560
571
  const decoded = (0, import_jwt_decode.jwtDecode)(token?.access_token);
561
572
  const isExpired = decoded.exp && decoded.exp < Date.now() / 1e3;
562
573
  if (isExpired) {
563
- console.log("token is expired - refreshing ...");
574
+ log("token is expired - refreshing ...");
564
575
  const newToken = await fetchToken(token?.refresh);
565
576
  fetchUser(newToken.access_token);
566
577
  } else {
@@ -646,6 +657,14 @@ function useBasic() {
646
657
 
647
658
  // src/index.ts
648
659
  var import_dexie_react_hooks = require("dexie-react-hooks");
660
+ function useQuery(queryable) {
661
+ return (0, import_dexie_react_hooks.useLiveQuery)(() => {
662
+ if (typeof queryable === "function") {
663
+ return queryable();
664
+ }
665
+ return queryable;
666
+ }, [queryable], []);
667
+ }
649
668
  // Annotate the CommonJS export names for ESM import in node:
650
669
  0 && (module.exports = {
651
670
  BasicProvider,