@basictech/react 0.2.0-beta.4 → 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.
package/changelog.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # 1.3.4
2
2
 
3
+ ## 0.2.0-beta.6
4
+
5
+ ### Minor Changes
6
+
7
+ - add debug option
8
+
9
+ ## 0.2.0-beta.5
10
+
11
+ ### Minor Changes
12
+
13
+ - schema validation bugfix
14
+
3
15
  ## 0.2.0-beta.4
4
16
 
5
17
  ### Minor Changes
package/dist/index.d.mts CHANGED
@@ -19,10 +19,11 @@ type User = {
19
19
  };
20
20
  fullName?: string;
21
21
  };
22
- declare function BasicProvider({ children, project_id, schema }: {
22
+ declare function BasicProvider({ children, project_id, schema, debug }: {
23
23
  children: React.ReactNode;
24
24
  project_id: string;
25
25
  schema: any;
26
+ debug?: boolean;
26
27
  }): react_jsx_runtime.JSX.Element;
27
28
  declare function useBasic(): {
28
29
  unicorn: string;
package/dist/index.d.ts CHANGED
@@ -19,10 +19,11 @@ type User = {
19
19
  };
20
20
  fullName?: string;
21
21
  };
22
- declare function BasicProvider({ children, project_id, schema }: {
22
+ declare function BasicProvider({ children, project_id, schema, debug }: {
23
23
  children: React.ReactNode;
24
24
  project_id: string;
25
25
  schema: any;
26
+ debug?: boolean;
26
27
  }): react_jsx_runtime.JSX.Element;
27
28
  declare function useBasic(): {
28
29
  unicorn: string;
package/dist/index.js CHANGED
@@ -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
@@ -362,34 +372,6 @@ async function deleteRecord({ projectId, accountId, tableName, id, token }) {
362
372
 
363
373
  // src/AuthContext.tsx
364
374
  var import_jsx_runtime = require("react/jsx-runtime");
365
- var example = {
366
- project_id: "123",
367
- version: 0,
368
- tables: {
369
- example: {
370
- name: "example",
371
- type: "collection",
372
- fields: {
373
- id: {
374
- type: "uuid",
375
- primary: true
376
- },
377
- value: {
378
- type: "string",
379
- indexed: true
380
- }
381
- }
382
- },
383
- example2: {
384
- name: "example2",
385
- type: "collection",
386
- fields: {
387
- id: { type: "string", primary: true },
388
- id: { type: "string", primary: true }
389
- }
390
- }
391
- }
392
- };
393
375
  var BasicContext = (0, import_react.createContext)({
394
376
  unicorn: "\u{1F984}",
395
377
  isLoaded: false,
@@ -423,7 +405,7 @@ function getSyncStatus(statusCode) {
423
405
  return "UNKNOWN";
424
406
  }
425
407
  }
426
- function BasicProvider({ children, project_id, schema }) {
408
+ function BasicProvider({ children, project_id, schema, debug = false }) {
427
409
  const [isLoaded, setIsLoaded] = (0, import_react.useState)(false);
428
410
  const [isSignedIn, setIsSignedIn] = (0, import_react.useState)(false);
429
411
  const [token, setToken] = (0, import_react.useState)(null);
@@ -434,13 +416,12 @@ function BasicProvider({ children, project_id, schema }) {
434
416
  const [error, setError] = (0, import_react.useState)(null);
435
417
  (0, import_react.useEffect)(() => {
436
418
  function initDb() {
437
- if (!validator(example)) {
438
- console.error("Basic Schema is invalid!", validator.errors);
419
+ if (!validator(schema)) {
420
+ log("Basic Schema is invalid!", validator.errors);
439
421
  console.group("Schema Errors");
440
422
  let errorMessage = "";
441
423
  validator.errors.forEach((error2, index) => {
442
- console.log("error", error2);
443
- console.log(`${index + 1}:`, error2.message, ` - at ${error2.instancePath}`);
424
+ log(`${index + 1}:`, error2.message, ` - at ${error2.instancePath}`);
444
425
  errorMessage += `${index + 1}: ${error2.message} - at ${error2.instancePath}
445
426
  `;
446
427
  });
@@ -458,7 +439,7 @@ function BasicProvider({ children, project_id, schema }) {
458
439
  setDbStatus(getSyncStatus(status));
459
440
  });
460
441
  syncRef.current.syncable.getStatus().then((status) => {
461
- console.log("sync status", getSyncStatus(status));
442
+ log("sync status", getSyncStatus(status));
462
443
  });
463
444
  }
464
445
  }
@@ -466,9 +447,9 @@ function BasicProvider({ children, project_id, schema }) {
466
447
  }, []);
467
448
  const connectToDb = async () => {
468
449
  const tok = await getToken();
469
- console.log("connecting to db...", tok.substring(0, 10));
450
+ log("connecting to db...", tok.substring(0, 10));
470
451
  syncRef.current.connect({ access_token: tok }).catch((e) => {
471
- console.log("error connecting to db", e);
452
+ log("error connecting to db", e);
472
453
  });
473
454
  };
474
455
  (0, import_react.useEffect)(() => {
@@ -477,7 +458,7 @@ function BasicProvider({ children, project_id, schema }) {
477
458
  }
478
459
  }, [token]);
479
460
  const getSignInLink = () => {
480
- console.log("getting sign in link...");
461
+ log("getting sign in link...");
481
462
  const randomState = Math.random().toString(36).substring(7);
482
463
  let baseUrl2 = "https://api.basic.tech/auth/authorize";
483
464
  baseUrl2 += `?client_id=${project_id}`;
@@ -488,12 +469,12 @@ function BasicProvider({ children, project_id, schema }) {
488
469
  return baseUrl2;
489
470
  };
490
471
  const signin = () => {
491
- console.log("signing in: ", getSignInLink());
472
+ log("signing in: ", getSignInLink());
492
473
  const signInLink = getSignInLink();
493
474
  window.location.href = signInLink;
494
475
  };
495
476
  const signout = () => {
496
- console.log("signing out!");
477
+ log("signing out!");
497
478
  setUser({});
498
479
  setIsSignedIn(false);
499
480
  setToken(null);
@@ -501,15 +482,15 @@ function BasicProvider({ children, project_id, schema }) {
501
482
  document.cookie = `basic_token=; Secure; SameSite=Strict`;
502
483
  };
503
484
  const getToken = async () => {
504
- console.log("getting token...");
485
+ log("getting token...");
505
486
  if (!token) {
506
- console.log("no token found");
487
+ log("no token found");
507
488
  throw new Error("no token found");
508
489
  }
509
490
  const decoded = (0, import_jwt_decode.jwtDecode)(token?.access_token);
510
491
  const isExpired = decoded.exp && decoded.exp < Date.now() / 1e3;
511
492
  if (isExpired) {
512
- console.log("token is expired - refreshing ...");
493
+ log("token is expired - refreshing ...");
513
494
  const newToken = await fetchToken(token?.refresh);
514
495
  return newToken?.access_token || "";
515
496
  }
@@ -536,9 +517,9 @@ function BasicProvider({ children, project_id, schema }) {
536
517
  "Content-Type": "application/json"
537
518
  },
538
519
  body: JSON.stringify({ code })
539
- }).then((response) => response.json()).catch((error2) => console.error("Error:", error2));
520
+ }).then((response) => response.json()).catch((error2) => log("Error:", error2));
540
521
  if (token2.error) {
541
- console.log("error fetching token", token2.error);
522
+ log("error fetching token", token2.error);
542
523
  return;
543
524
  } else {
544
525
  setToken(token2);
@@ -546,6 +527,7 @@ function BasicProvider({ children, project_id, schema }) {
546
527
  return token2;
547
528
  };
548
529
  (0, import_react.useEffect)(() => {
530
+ localStorage.setItem("basic_debug", debug ? "true" : "false");
549
531
  try {
550
532
  let cookie_token = getCookie("basic_token");
551
533
  if (cookie_token !== "") {
@@ -560,7 +542,7 @@ function BasicProvider({ children, project_id, schema }) {
560
542
  setIsLoaded(true);
561
543
  }
562
544
  } catch (e) {
563
- console.log("error getting cookie", e);
545
+ log("error getting cookie", e);
564
546
  }
565
547
  }, []);
566
548
  (0, import_react.useEffect)(() => {
@@ -570,9 +552,9 @@ function BasicProvider({ children, project_id, schema }) {
570
552
  headers: {
571
553
  "Authorization": `Bearer ${acc_token}`
572
554
  }
573
- }).then((response) => response.json()).catch((error2) => console.error("Error:", error2));
555
+ }).then((response) => response.json()).catch((error2) => log("Error:", error2));
574
556
  if (user2.error) {
575
- console.log("error fetching user", user2.error);
557
+ log("error fetching user", user2.error);
576
558
  return;
577
559
  } else {
578
560
  document.cookie = `basic_token=${JSON.stringify(token)}; Secure; SameSite=Strict`;
@@ -583,13 +565,13 @@ function BasicProvider({ children, project_id, schema }) {
583
565
  }
584
566
  async function checkToken() {
585
567
  if (!token) {
586
- console.log("error: no user token found");
568
+ log("error: no user token found");
587
569
  return;
588
570
  }
589
571
  const decoded = (0, import_jwt_decode.jwtDecode)(token?.access_token);
590
572
  const isExpired = decoded.exp && decoded.exp < Date.now() / 1e3;
591
573
  if (isExpired) {
592
- console.log("token is expired - refreshing ...");
574
+ log("token is expired - refreshing ...");
593
575
  const newToken = await fetchToken(token?.refresh);
594
576
  fetchUser(newToken.access_token);
595
577
  } else {