@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.
package/changelog.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # 1.3.4
2
2
 
3
+ ## 0.2.0-beta.6
4
+
5
+ ### Minor Changes
6
+
7
+ - add debug option
8
+
3
9
  ## 0.2.0-beta.5
4
10
 
5
11
  ### 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
@@ -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 {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/AuthContext.tsx","../src/sync/index.ts","../src/sync/syncProtocol.js","../src/config.ts","../src/db.ts"],"sourcesContent":["import { useBasic, BasicProvider } from \"./AuthContext\";\nimport { useLiveQuery as useQuery } from \"dexie-react-hooks\";\n\nexport {\n useBasic, BasicProvider, useQuery\n}","// @ts-nocheck\n\nimport React, { createContext, useContext, useEffect, useState, useRef } from 'react'\nimport { jwtDecode } from 'jwt-decode'\n\nimport { BasicSync } from './sync'\nimport { get, add, update, deleteRecord } from './db'\n\nimport { validator, log } from './config'\n\n/*\nschema todo:\n field types\n array types\n relations\n*/\n\n\n// const example = {\n// project_id: '123',\n// version: 0,\n// tables: {\n// example: {\n// name: 'example',\n// type: 'collection',\n// fields: {\n// id: {\n// type: 'uuid',\n// primary: true,\n// },\n// value: {\n// type: 'string',\n// indexed: true,\n// },\n// }\n// }\n// }\n// }\n\n\ntype BasicSyncType = {\n basic_schema: any;\n connect: (options: { access_token: string }) => void;\n debugeroo: () => void;\n collection: (name: string) => {\n ref: {\n toArray: () => Promise<any[]>;\n count: () => Promise<number>;\n };\n };\n [key: string]: any; // For other potential methods and properties\n};\n\n\nenum DBStatus {\n LOADING = \"LOADING\",\n OFFLINE = \"OFFLINE\",\n CONNECTING = \"CONNECTING\",\n ONLINE = \"ONLINE\",\n SYNCING = \"SYNCING\",\n ERROR = \"ERROR\"\n}\n\ntype User = {\n name?: string,\n email?: string,\n id?: string,\n primaryEmailAddress?: {\n emailAddress: string\n },\n fullName?: string\n}\ntype Token = {\n access_token: string,\n token_type: string,\n expires_in: number,\n refresh: string,\n}\n\nexport const BasicContext = createContext<{\n unicorn: string,\n isLoaded: boolean,\n isSignedIn: boolean,\n user: User | null,\n signout: () => void,\n signin: () => void,\n getToken: () => Promise<string>,\n getSignInLink: () => string,\n db: any,\n dbStatus: DBStatus\n}>({\n unicorn: \"🦄\",\n isLoaded: false,\n isSignedIn: false,\n user: null,\n signout: () => { },\n signin: () => { },\n getToken: () => new Promise(() => { }),\n getSignInLink: () => \"\",\n db: {},\n dbStatus: DBStatus.OFFLINE\n});\n\nconst EmptyDB: BasicSyncType = {\n isOpen: false,\n collection: () => {\n return {\n ref: {\n toArray: () => [],\n count: () => 0\n }\n }\n }\n}\n\n\nfunction getSyncStatus(statusCode: number): string {\n switch (statusCode) {\n case -1:\n return \"ERROR\";\n case 0:\n return \"OFFLINE\";\n case 1:\n return \"CONNECTING\";\n case 2:\n return \"ONLINE\";\n case 3:\n return \"SYNCING\";\n case 4:\n return \"ERROR_WILL_RETRY\";\n default:\n return \"UNKNOWN\";\n }\n}\n\ntype ErrorObject = {\n code: string;\n title: string;\n message: string;\n}\n\nexport function BasicProvider({ children, project_id, schema }: { children: React.ReactNode, project_id: string, schema: any }) {\n const [isLoaded, setIsLoaded] = useState(false)\n const [isSignedIn, setIsSignedIn] = useState(false)\n const [token, setToken] = useState<Token | null>(null)\n const [authCode, setAuthCode] = useState<string | null>(null)\n const [user, setUser] = useState<User>({})\n\n const [dbStatus, setDbStatus] = useState<DBStatus>(DBStatus.LOADING)\n\n const syncRef = useRef<BasicSync | null>(null);\n\n const [error, setError] = useState<ErrorObject | null>(null)\n\n useEffect(() => {\n function initDb() {\n if (!validator(schema)) {\n console.error('Basic Schema is invalid!', validator.errors)\n console.group('Schema Errors')\n let errorMessage = ''\n validator.errors.forEach((error, index) => {\n console.log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`)\n errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}\\n`\n })\n console.groupEnd('Schema Errors')\n setError({\n code: 'schema_invalid',\n title: 'Basic Schema is invalid!',\n message: errorMessage\n })\n return null\n }\n\n\n if (!syncRef.current) {\n syncRef.current = new BasicSync('basicdb', { schema: schema });\n\n // console.log('db is open', syncRef.current.isOpen())\n // syncRef.current.open()\n // .then(() => {\n // console.log(\"is open now:\", syncRef.current.isOpen())\n // })\n\n syncRef.current.handleStatusChange((status: number, url: string) => {\n setDbStatus(getSyncStatus(status))\n })\n\n syncRef.current.syncable.getStatus().then((status) => {\n console.log('sync status', getSyncStatus(status))\n })\n }\n\n }\n\n initDb()\n }, []);\n\n\n //todo: \n //add random state to signin link & verify random state\n\n const connectToDb = async () => {\n\n const tok = await getToken()\n\n console.log('connecting to db...', tok.substring(0, 10))\n\n syncRef.current.connect({ access_token: tok })\n .catch((e) => {\n console.log('error connecting to db', e)\n })\n }\n\n useEffect(() => {\n if (token && syncRef.current) {\n connectToDb()\n }\n }, [token])\n\n const getSignInLink = () => {\n console.log('getting sign in link...')\n\n const randomState = Math.random().toString(36).substring(7);\n\n let baseUrl = \"https://api.basic.tech/auth/authorize\"\n baseUrl += `?client_id=${project_id}`\n baseUrl += `&redirect_uri=${encodeURIComponent(window.location.href)}`\n baseUrl += `&response_type=code`\n baseUrl += `&scope=openid`\n baseUrl += `&state=1234zyx`\n\n return baseUrl;\n }\n\n const signin = () => {\n console.log('signing in: ', getSignInLink())\n const signInLink = getSignInLink()\n //todo: change to the other thing?\n window.location.href = signInLink;\n }\n\n const signout = () => {\n console.log('signing out!')\n setUser({})\n setIsSignedIn(false)\n setToken(null)\n setAuthCode(null)\n document.cookie = `basic_token=; Secure; SameSite=Strict`;\n }\n\n const getToken = async (): Promise<string> => {\n console.log('getting token...')\n\n if (!token) {\n console.log('no token found')\n throw new Error('no token found')\n }\n\n const decoded = jwtDecode(token?.access_token)\n const isExpired = decoded.exp && decoded.exp < Date.now() / 1000\n\n if (isExpired) {\n console.log('token is expired - refreshing ...')\n const newToken = await fetchToken(token?.refresh)\n return newToken?.access_token || ''\n }\n\n return token?.access_token || ''\n }\n\n function getCookie(name: string) {\n let cookieValue = '';\n if (document.cookie && document.cookie !== '') {\n const cookies = document.cookie.split(';');\n for (let i = 0; i < cookies.length; i++) {\n const cookie = cookies[i].trim();\n if (cookie.substring(0, name.length + 1) === (name + '=')) {\n cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\n break;\n }\n }\n }\n return cookieValue;\n }\n\n const fetchToken = async (code: string) => {\n const token = await fetch('https://api.basic.tech/auth/token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ code: code })\n })\n .then(response => response.json())\n .catch(error => console.error('Error:', error))\n\n if (token.error) {\n console.log('error fetching token', token.error)\n return\n } else {\n // console.log('token', token)\n setToken(token)\n }\n return token\n }\n\n useEffect(() => {\n try {\n let cookie_token = getCookie('basic_token')\n if (cookie_token !== '') {\n setToken(JSON.parse(cookie_token))\n }\n\n if (window.location.search.includes('code')) {\n let code = window.location?.search?.split('code=')[1].split('&')[0]\n // console.log('code found', code)\n\n // todo: check state is valid\n setAuthCode(code) // remove this? dont need to store code?\n fetchToken(code)\n\n window.history.pushState({}, document.title, \"/\");\n\n } else {\n setIsLoaded(true)\n }\n } catch (e) {\n console.log('error getting cookie', e)\n }\n }, [])\n\n useEffect(() => {\n async function fetchUser(acc_token: string) {\n const user = await fetch('https://api.basic.tech/auth/userInfo', {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${acc_token}`\n }\n })\n .then(response => response.json())\n .catch(error => console.error('Error:', error))\n\n if (user.error) {\n console.log('error fetching user', user.error)\n // refreshToken()\n return\n } else {\n // console.log('user', user)\n document.cookie = `basic_token=${JSON.stringify(token)}; Secure; SameSite=Strict`;\n setUser(user)\n setIsSignedIn(true)\n setIsLoaded(true)\n }\n }\n\n async function checkToken() {\n if (!token) {\n console.log('error: no user token found')\n return\n }\n\n const decoded = jwtDecode(token?.access_token)\n const isExpired = decoded.exp && decoded.exp < Date.now() / 1000\n\n if (isExpired) {\n console.log('token is expired - refreshing ...')\n const newToken = await fetchToken(token?.refresh)\n fetchUser(newToken.access_token)\n } else {\n fetchUser(token.access_token)\n }\n }\n\n if (token) {\n checkToken()\n setIsLoaded(true)\n }\n }, [token])\n\n\n const db_ = (tableName: string) => {\n const checkSignIn = () => {\n if (!isSignedIn) {\n throw new Error('cannot use db. user not logged in.')\n }\n }\n\n return {\n get: async () => {\n checkSignIn()\n const tok = await getToken()\n return get({ projectId: project_id, accountId: user.id, tableName: tableName, token: tok })\n },\n add: async (value: any) => {\n checkSignIn()\n const tok = await getToken()\n return add({ projectId: project_id, accountId: user.id, tableName: tableName, value: value, token: tok })\n },\n update: async (id: string, value: any) => {\n checkSignIn()\n const tok = await getToken()\n return update({ projectId: project_id, accountId: user.id, tableName: tableName, id: id, value: value, token: tok })\n },\n delete: async (id: string) => {\n checkSignIn()\n const tok = await getToken()\n return deleteRecord({ projectId: project_id, accountId: user.id, tableName: tableName, id: id, token: tok })\n }\n\n }\n\n }\n\n return (\n <BasicContext.Provider value={{\n unicorn: \"🦄\",\n isLoaded,\n isSignedIn,\n user,\n signout,\n signin,\n getToken,\n getSignInLink,\n db: syncRef.current,\n dbStatus\n }}>\n {error && <ErrorDisplay error={error} />}\n {syncRef.current ? children : null}\n </BasicContext.Provider>\n )\n}\n\nfunction ErrorDisplay({ error }: { error: ErrorObject }) {\n return <div style={{ \n position: 'absolute',\n top: 20, \n left: 20,\n color: 'black',\n backgroundColor: '#f8d7da',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n padding: '20px',\n maxWidth: '400px',\n margin: '20px auto',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',\n fontFamily: 'monospace', \n }}>\n <h3 style={{fontSize: '0.8rem', opacity: 0.8}}>code: {error.code}</h3>\n <h1 style={{fontSize: '1.2rem', lineHeight: '1.5'}}>{error.title}</h1>\n <p>{error.message}</p>\n </div>\n}\n\n/*\npossible errors: \n- projectid missing / invalid\n- schema missing / invalid\n*/\n\nexport function useBasic() {\n return useContext(BasicContext);\n}","\"use client\"\n\nimport { v7 as uuidv7 } from 'uuid';\nimport { Dexie, PromiseExtended } from 'dexie';\n// if (typeof window !== 'undefined') {\n// import('dexie-observable');\n// }\nimport 'dexie-syncable';\nimport 'dexie-observable';\n\nimport { syncProtocol } from './syncProtocol'\nimport { SERVER_URL } from '../config'\nsyncProtocol()\n\n\n// const DexieSyncStatus = {\n// \"-1\": \"ERROR\",\n// \"0\": \"OFFLINE\",\n// \"1\": \"CONNECTING\",\n// \"2\": \"ONLINE\",\n// \"3\": \"SYNCING\",\n// \"4\": \"ERROR_WILL_RETRY\"\n// }\n\n\n\n\n\nexport class BasicSync extends Dexie {\n basic_schema: any\n\n constructor(name: string, options: any) {\n super(name, options);\n\n // --- INIT SCHEMA --- // \n\n //todo: handle versions?\n\n // TODO: validate schema\n this.basic_schema = options.schema\n this.version(1).stores(this._convertSchemaToDxSchema(this.basic_schema))\n\n this.version(2).stores({})\n // this.verssion\n\n\n // create an alias for toArray\n // @ts-ignore\n this.Collection.prototype.get = this.Collection.prototype.toArray\n\n\n // --- SYNC --- // \n\n // this.syncable.on(\"statusChanged\", (status, url) => { \n // console.log(\"statusChanged\", status, url)\n // })\n\n }\n\n async connect({ access_token }: { access_token: string }) {\n // const WS_URL = \"ws://localhost:3003/ws\"\n const WS_URL = `${SERVER_URL}/ws`\n\n \n // Update sync nodes\n await this.updateSyncNodes();\n \n // Proceed with the WebSocket connection\n \n console.log('Starting connection...')\n return this.syncable.connect(\"websocket\", WS_URL, { authToken: access_token });\n }\n\n private async updateSyncNodes() {\n try {\n const syncNodes = await this.table('_syncNodes').toArray();\n const localSyncNodes = syncNodes.filter(node => node.type === 'local');\n console.log('Local sync nodes:', localSyncNodes);\n\n if (localSyncNodes.length > 1) {\n\n \n const largestNodeId = Math.max(...localSyncNodes.map(node => node.id));\n // Check if the largest node is already the master\n const largestNode = localSyncNodes.find(node => node.id === largestNodeId);\n if (largestNode && largestNode.isMaster === 1) {\n console.log('Largest node is already the master. No changes needed.');\n return; // Exit the function early as no changes are needed\n }\n\n\n console.log('Largest node id:', largestNodeId);\n console.error('HEISENBUG: More than one local sync node found.')\n\n for (const node of localSyncNodes) {\n console.log(`Local sync node keys:`, node.id, node.isMaster);\n await this.table('_syncNodes').update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });\n\n console.log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? 'master' : '0'}`);\n }\n\n // Add a 1 second delay before returning // i dont think this helps?\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n }\n\n console.log('Sync nodes updated');\n } catch (error) {\n console.error('Error updating _syncNodes table:', error);\n }\n }\n\n handleStatusChange(fn: any) {\n this.syncable.on(\"statusChanged\", fn)\n }\n\n\n _convertSchemaToDxSchema(schema: any) {\n const stores = Object.entries(schema.tables).map(([key, table]: any) => {\n\n const indexedFields = Object.entries(table.fields).filter(([key, field]: any) => field.indexed).map(([key, field]: any) => `,${key}`).join('')\n return {\n [key]: 'id' + indexedFields\n }\n })\n\n return Object.assign({}, ...stores)\n }\n\n debugeroo() {\n // console.log(\"debugeroo\", this.syncable)\n\n // this.syncable.list().then(x => console.log(x))\n\n // this.syncable\n return this.syncable\n }\n\n\n collection(name: string) {\n // TODO: check against schema\n\n return {\n\n /**\n * Returns the underlying Dexie table\n * @type {Dexie.Table}\n */\n ref: this.table(name),\n\n // --- WRITE ---- // \n add: (data: any) => {\n console.log(\"Adding data to\", name, data)\n return this.table(name).add({\n id: uuidv7(),\n ...data\n })\n },\n\n put: (data: any) => {\n return this.table(name).put({\n id: uuidv7(),\n ...data\n })\n },\n\n update: (id: string, data: any) => {\n return this.table(name).update(id, data)\n },\n\n delete: (id: string) => {\n return this.table(name).delete(id)\n },\n\n\n // --- READ ---- // \n\n get: (id: string) => {\n return this.table(name).get(id)\n },\n\n getAll: () => {\n return this.table(name).toArray()\n },\n\n // --- QUERY ---- // \n // TODO: lots to do here. simplifing creating querie, filtering/ordering/limit, and execute\n\n query: () => this.table(name),\n\n filter: (fn: any) => this.table(name).filter(fn).toArray(),\n\n }\n }\n}\n","\"use client\"\nimport { Dexie } from \"dexie\";\n\nexport const syncProtocol = function () {\n console.log(\"Initializing syncProtocol\");\n // Constants:\n var RECONNECT_DELAY = 5000; // Reconnect delay in case of errors such as network down.\n\n Dexie.Syncable.registerSyncProtocol(\"websocket\", {\n sync: function (\n context,\n url,\n options,\n baseRevision,\n syncedRevision,\n changes,\n partial,\n applyRemoteChanges,\n onChangesAccepted,\n onSuccess,\n onError,\n ) {\n // The following vars are needed because we must know which callback to ack when server sends it's ack to us.\n var requestId = 0;\n var acceptCallbacks = {};\n\n // Connect the WebSocket to given url:\n var ws = new WebSocket(url);\n\n // console.log(\"ws OPTIONS\", options);\n\n // sendChanges() method:\n function sendChanges(changes, baseRevision, partial, onChangesAccepted) {\n console.log(\"sendChanges\", changes.length, baseRevision);\n ++requestId;\n acceptCallbacks[requestId.toString()] = onChangesAccepted;\n\n // In this example, the server expects the following JSON format of the request:\n // {\n // type: \"changes\"\n // baseRevision: baseRevision,\n // changes: changes,\n // partial: partial,\n // requestId: id\n // }\n // To make the sample simplified, we assume the server has the exact same specification of how changes are structured.\n // In real world, you would have to pre-process the changes array to fit the server specification.\n // However, this example shows how to deal with the WebSocket to fullfill the API.\n\n ws.send(\n JSON.stringify({\n type: \"changes\",\n changes: changes,\n partial: partial,\n baseRevision: baseRevision,\n requestId: requestId,\n }),\n );\n }\n\n\n\n // When WebSocket opens, send our changes to the server.\n ws.onopen = function (event) {\n // Initiate this socket connection by sending our clientIdentity. If we dont have a clientIdentity yet,\n // server will call back with a new client identity that we should use in future WebSocket connections.\n \n console.log(\"Opening socket - sending clientIdentity\", context.clientIdentity);\n ws.send(\n JSON.stringify({\n type: \"clientIdentity\",\n clientIdentity: context.clientIdentity || null,\n authToken: options.authToken\n }),\n );\n\n };\n\n // If network down or other error, tell the framework to reconnect again in some time:\n ws.onerror = function (event) {\n ws.close();\n console.log(\"ws.onerror\", event);\n onError(event?.message, RECONNECT_DELAY);\n };\n\n // If socket is closed (network disconnected), inform framework and make it reconnect\n ws.onclose = function (event) {\n onError(\"Socket closed: \" + event.reason, RECONNECT_DELAY);\n };\n\n // isFirstRound: Will need to call onSuccess() only when we are in sync the first time.\n // onSuccess() will unblock Dexie to be used by application code.\n // If for example app code writes: db.friends.where('shoeSize').above(40).toArray(callback), the execution of that query\n // will not run until we have called onSuccess(). This is because we want application code to get results that are as\n // accurate as possible. Specifically when connected the first time and the entire DB is being synced down to the browser,\n // it is important that queries starts running first when db is in sync.\n var isFirstRound = true;\n // When message arrive from the server, deal with the message accordingly:\n ws.onmessage = function (event) {\n try {\n // Assume we have a server that should send JSON messages of the following format:\n // {\n // type: \"clientIdentity\", \"changes\", \"ack\" or \"error\"\n // clientIdentity: unique value for our database client node to persist in the context. (Only applicable if type=\"clientIdentity\")\n // message: Error message (Only applicable if type=\"error\")\n // requestId: ID of change request that is acked by the server (Only applicable if type=\"ack\" or \"error\")\n // changes: changes from server (Only applicable if type=\"changes\")\n // lastRevision: last revision of changes sent (applicable if type=\"changes\")\n // partial: true if server has additionalChanges to send. False if these changes were the last known. (applicable if type=\"changes\")\n // }\n var requestFromServer = JSON.parse(event.data);\n console.log(\"requestFromServer\", requestFromServer, { acceptCallback, isFirstRound });\n\n if (requestFromServer.type == \"clientIdentity\") {\n context.clientIdentity = requestFromServer.clientIdentity;\n context.save();\n\n sendChanges(changes, baseRevision, partial, onChangesAccepted);\n\n ws.send(\n JSON.stringify({\n type: \"subscribe\",\n syncedRevision: syncedRevision,\n }),\n );\n } else if (requestFromServer.type == \"error\") {\n } else if (requestFromServer.type == \"changes\") {\n applyRemoteChanges(\n requestFromServer.changes,\n requestFromServer.currentRevision,\n requestFromServer.partial,\n );\n if (isFirstRound && !requestFromServer.partial) {\n // Since this is the first sync round and server sais we've got all changes - now is the time to call onsuccess()\n onSuccess({\n // Specify a react function that will react on additional client changes\n react: function (\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n ) {\n sendChanges(\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n );\n },\n // Specify a disconnect function that will close our socket so that we dont continue to monitor changes.\n disconnect: function () {\n ws.close();\n },\n });\n isFirstRound = false;\n }\n } else if (requestFromServer.type == \"ack\") {\n var requestId = requestFromServer.requestId;\n var acceptCallback = acceptCallbacks[requestId.toString()];\n acceptCallback(); // Tell framework that server has acknowledged the changes sent.\n delete acceptCallbacks[requestId.toString()];\n } else if (requestFromServer.type == \"error\") {\n var requestId = requestFromServer.requestId;\n ws.close();\n onError(requestFromServer.message, Infinity); // Don't reconnect - an error in application level means we have done something wrong.\n } else {\n console.log(\"unknown message\", requestFromServer);\n ws.close();\n onError(\"unknown message\", Infinity);\n }\n } catch (e) {\n ws.close();\n onError(e, Infinity); // Something went crazy. Server sends invalid format or our code is buggy. Dont reconnect - it would continue failing.\n }\n };\n },\n });\n};\n","import Ajv from 'ajv'\n\nexport const SERVER_URL = \"https://api.basic.tech\"\n// export const WS_URL = `${SERVER_URL}/ws`\n\nexport const log = (...args: any[]) => {\n if (process.env.NODE_ENV === 'development') {\n console.log(...args)\n }\n}\n\n\nconst basicJsonSchema = {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"type\": \"object\",\n \"properties\": {\n \"project_id\": {\n \"type\": \"string\"\n },\n \"namespace\": {\n \"type\": \"string\",\n },\n \"version\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"tables\": {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"fields\": {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\"\n },\n \"primary\": {\n \"type\": \"boolean\"\n },\n \"indexed\": {\n \"type\": \"boolean\"\n }\n },\n \"required\": [\"type\"]\n }\n },\n \"additionalProperties\": true\n }\n },\n \"required\": [\"fields\"]\n }\n },\n \"additionalProperties\": true\n }\n },\n \"required\": [\"project_id\", \"version\", \"tables\"]\n}\n\n\nconst ajv = new Ajv()\nexport const validator = ajv.compile(basicJsonSchema)\n","//@ts-nocheck\n\nconst baseUrl = 'https://api.basic.tech';\n// const baseUrl = 'http://localhost:3000';\n\n\nasync function get({ projectId, accountId, tableName, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}`;\n const response = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${token}`\n }\n });\n return response.json();\n}\n\nasync function add({ projectId, accountId, tableName, value, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n },\n body: JSON.stringify({\"value\": value})\n });\n return response.json();\n}\n\nasync function update({ projectId, accountId, tableName, id, value, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}/${id}`;\n const response = await fetch(url, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n },\n body: JSON.stringify({id: id, value: value})\n });\n return response.json();\n}\n\nasync function deleteRecord({ projectId, accountId, tableName, id, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}/${id}`;\n const response = await fetch(url, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${token}`\n }\n });\n return response.json();\n}\n\nexport { get, add, update, deleteRecord };\n\n"],"mappings":"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","names":["useQuery","import_dexie","changes","baseRevision","partial","onChangesAccepted","requestId","Ajv","key","uuidv7","error","baseUrl","token","user"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/AuthContext.tsx","../src/sync/index.ts","../src/sync/syncProtocol.js","../src/config.ts","../src/db.ts"],"sourcesContent":["import { useBasic, BasicProvider } from \"./AuthContext\";\nimport { useLiveQuery as useQuery } from \"dexie-react-hooks\";\n\nexport {\n useBasic, BasicProvider, useQuery\n}","// @ts-nocheck\n\nimport React, { createContext, useContext, useEffect, useState, useRef } from 'react'\nimport { jwtDecode } from 'jwt-decode'\n\nimport { BasicSync } from './sync'\nimport { get, add, update, deleteRecord } from './db'\n\nimport { validator, log } from './config'\n\n/*\nschema todo:\n field types\n array types\n relations\n*/\n\n\n// const example = {\n// project_id: '123',\n// version: 0,\n// tables: {\n// example: {\n// name: 'example',\n// type: 'collection',\n// fields: {\n// id: {\n// type: 'uuid',\n// primary: true,\n// },\n// value: {\n// type: 'string',\n// indexed: true,\n// },\n// }\n// }\n// }\n// }\n\n\ntype BasicSyncType = {\n basic_schema: any;\n connect: (options: { access_token: string }) => void;\n debugeroo: () => void;\n collection: (name: string) => {\n ref: {\n toArray: () => Promise<any[]>;\n count: () => Promise<number>;\n };\n };\n [key: string]: any; // For other potential methods and properties\n};\n\n\nenum DBStatus {\n LOADING = \"LOADING\",\n OFFLINE = \"OFFLINE\",\n CONNECTING = \"CONNECTING\",\n ONLINE = \"ONLINE\",\n SYNCING = \"SYNCING\",\n ERROR = \"ERROR\"\n}\n\ntype User = {\n name?: string,\n email?: string,\n id?: string,\n primaryEmailAddress?: {\n emailAddress: string\n },\n fullName?: string\n}\ntype Token = {\n access_token: string,\n token_type: string,\n expires_in: number,\n refresh: string,\n}\n\nexport const BasicContext = createContext<{\n unicorn: string,\n isLoaded: boolean,\n isSignedIn: boolean,\n user: User | null,\n signout: () => void,\n signin: () => void,\n getToken: () => Promise<string>,\n getSignInLink: () => string,\n db: any,\n dbStatus: DBStatus\n}>({\n unicorn: \"🦄\",\n isLoaded: false,\n isSignedIn: false,\n user: null,\n signout: () => { },\n signin: () => { },\n getToken: () => new Promise(() => { }),\n getSignInLink: () => \"\",\n db: {},\n dbStatus: DBStatus.OFFLINE\n});\n\nconst EmptyDB: BasicSyncType = {\n isOpen: false,\n collection: () => {\n return {\n ref: {\n toArray: () => [],\n count: () => 0\n }\n }\n }\n}\n\n\nfunction getSyncStatus(statusCode: number): string {\n switch (statusCode) {\n case -1:\n return \"ERROR\";\n case 0:\n return \"OFFLINE\";\n case 1:\n return \"CONNECTING\";\n case 2:\n return \"ONLINE\";\n case 3:\n return \"SYNCING\";\n case 4:\n return \"ERROR_WILL_RETRY\";\n default:\n return \"UNKNOWN\";\n }\n}\n\ntype ErrorObject = {\n code: string;\n title: string;\n message: string;\n}\n\nexport function BasicProvider({ children, project_id, schema, debug = false }: { children: React.ReactNode, project_id: string, schema: any, debug?: boolean }) {\n const [isLoaded, setIsLoaded] = useState(false)\n const [isSignedIn, setIsSignedIn] = useState(false)\n const [token, setToken] = useState<Token | null>(null)\n const [authCode, setAuthCode] = useState<string | null>(null)\n const [user, setUser] = useState<User>({})\n\n const [dbStatus, setDbStatus] = useState<DBStatus>(DBStatus.LOADING)\n\n const syncRef = useRef<BasicSync | null>(null);\n\n const [error, setError] = useState<ErrorObject | null>(null)\n\n useEffect(() => {\n function initDb() {\n if (!validator(schema)) {\n log('Basic Schema is invalid!', validator.errors)\n console.group('Schema Errors')\n let errorMessage = ''\n validator.errors.forEach((error, index) => {\n log(`${index + 1}:`, error.message, ` - at ${error.instancePath}`)\n errorMessage += `${index + 1}: ${error.message} - at ${error.instancePath}\\n`\n })\n console.groupEnd('Schema Errors')\n setError({\n code: 'schema_invalid',\n title: 'Basic Schema is invalid!',\n message: errorMessage\n })\n return null\n }\n\n\n if (!syncRef.current) {\n syncRef.current = new BasicSync('basicdb', { schema: schema });\n\n // log('db is open', syncRef.current.isOpen())\n // syncRef.current.open()\n // .then(() => {\n // log(\"is open now:\", syncRef.current.isOpen())\n // })\n\n syncRef.current.handleStatusChange((status: number, url: string) => {\n setDbStatus(getSyncStatus(status))\n })\n\n syncRef.current.syncable.getStatus().then((status) => {\n log('sync status', getSyncStatus(status))\n })\n }\n\n }\n\n initDb()\n }, []);\n\n\n //todo: \n //add random state to signin link & verify random state\n\n const connectToDb = async () => {\n\n const tok = await getToken()\n\n log('connecting to db...', tok.substring(0, 10))\n\n syncRef.current.connect({ access_token: tok })\n .catch((e) => {\n log('error connecting to db', e)\n })\n }\n\n useEffect(() => {\n if (token && syncRef.current) {\n connectToDb()\n }\n }, [token])\n\n const getSignInLink = () => {\n log('getting sign in link...')\n\n const randomState = Math.random().toString(36).substring(7);\n\n let baseUrl = \"https://api.basic.tech/auth/authorize\"\n baseUrl += `?client_id=${project_id}`\n baseUrl += `&redirect_uri=${encodeURIComponent(window.location.href)}`\n baseUrl += `&response_type=code`\n baseUrl += `&scope=openid`\n baseUrl += `&state=1234zyx`\n\n return baseUrl;\n }\n\n const signin = () => {\n log('signing in: ', getSignInLink())\n const signInLink = getSignInLink()\n //todo: change to the other thing?\n window.location.href = signInLink;\n }\n\n const signout = () => {\n log('signing out!')\n setUser({})\n setIsSignedIn(false)\n setToken(null)\n setAuthCode(null)\n document.cookie = `basic_token=; Secure; SameSite=Strict`;\n }\n\n const getToken = async (): Promise<string> => {\n log('getting token...')\n\n if (!token) {\n log('no token found')\n throw new Error('no token found')\n }\n\n const decoded = jwtDecode(token?.access_token)\n const isExpired = decoded.exp && decoded.exp < Date.now() / 1000\n\n if (isExpired) {\n log('token is expired - refreshing ...')\n const newToken = await fetchToken(token?.refresh)\n return newToken?.access_token || ''\n }\n\n return token?.access_token || ''\n }\n\n function getCookie(name: string) {\n let cookieValue = '';\n if (document.cookie && document.cookie !== '') {\n const cookies = document.cookie.split(';');\n for (let i = 0; i < cookies.length; i++) {\n const cookie = cookies[i].trim();\n if (cookie.substring(0, name.length + 1) === (name + '=')) {\n cookieValue = decodeURIComponent(cookie.substring(name.length + 1));\n break;\n }\n }\n }\n return cookieValue;\n }\n\n const fetchToken = async (code: string) => {\n const token = await fetch('https://api.basic.tech/auth/token', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify({ code: code })\n })\n .then(response => response.json())\n .catch(error => log('Error:', error))\n\n if (token.error) {\n log('error fetching token', token.error)\n return\n } else {\n // log('token', token)\n setToken(token)\n }\n return token\n }\n\n useEffect(() => {\n localStorage.setItem('basic_debug', debug ? 'true' : 'false')\n\n try {\n let cookie_token = getCookie('basic_token')\n if (cookie_token !== '') {\n setToken(JSON.parse(cookie_token))\n }\n\n if (window.location.search.includes('code')) {\n let code = window.location?.search?.split('code=')[1].split('&')[0]\n // log('code found', code)\n\n // todo: check state is valid\n setAuthCode(code) // remove this? dont need to store code?\n fetchToken(code)\n\n window.history.pushState({}, document.title, \"/\");\n\n } else {\n setIsLoaded(true)\n }\n } catch (e) {\n log('error getting cookie', e)\n }\n }, [])\n\n useEffect(() => {\n async function fetchUser(acc_token: string) {\n const user = await fetch('https://api.basic.tech/auth/userInfo', {\n method: 'GET',\n headers: {\n 'Authorization': `Bearer ${acc_token}`\n }\n })\n .then(response => response.json())\n .catch(error => log('Error:', error))\n\n if (user.error) {\n log('error fetching user', user.error)\n // refreshToken()\n return\n } else {\n // log('user', user)\n document.cookie = `basic_token=${JSON.stringify(token)}; Secure; SameSite=Strict`;\n setUser(user)\n setIsSignedIn(true)\n setIsLoaded(true)\n }\n }\n\n async function checkToken() {\n if (!token) {\n log('error: no user token found')\n return\n }\n\n const decoded = jwtDecode(token?.access_token)\n const isExpired = decoded.exp && decoded.exp < Date.now() / 1000\n\n if (isExpired) {\n log('token is expired - refreshing ...')\n const newToken = await fetchToken(token?.refresh)\n fetchUser(newToken.access_token)\n } else {\n fetchUser(token.access_token)\n }\n }\n\n if (token) {\n checkToken()\n setIsLoaded(true)\n }\n }, [token])\n\n\n const db_ = (tableName: string) => {\n const checkSignIn = () => {\n if (!isSignedIn) {\n throw new Error('cannot use db. user not logged in.')\n }\n }\n\n return {\n get: async () => {\n checkSignIn()\n const tok = await getToken()\n return get({ projectId: project_id, accountId: user.id, tableName: tableName, token: tok })\n },\n add: async (value: any) => {\n checkSignIn()\n const tok = await getToken()\n return add({ projectId: project_id, accountId: user.id, tableName: tableName, value: value, token: tok })\n },\n update: async (id: string, value: any) => {\n checkSignIn()\n const tok = await getToken()\n return update({ projectId: project_id, accountId: user.id, tableName: tableName, id: id, value: value, token: tok })\n },\n delete: async (id: string) => {\n checkSignIn()\n const tok = await getToken()\n return deleteRecord({ projectId: project_id, accountId: user.id, tableName: tableName, id: id, token: tok })\n }\n\n }\n\n }\n\n return (\n <BasicContext.Provider value={{\n unicorn: \"🦄\",\n isLoaded,\n isSignedIn,\n user,\n signout,\n signin,\n getToken,\n getSignInLink,\n db: syncRef.current,\n dbStatus\n }}>\n {error && <ErrorDisplay error={error} />}\n {syncRef.current ? children : null}\n </BasicContext.Provider>\n )\n}\n\nfunction ErrorDisplay({ error }: { error: ErrorObject }) {\n return <div style={{ \n position: 'absolute',\n top: 20, \n left: 20,\n color: 'black',\n backgroundColor: '#f8d7da',\n border: '1px solid #f5c6cb',\n borderRadius: '4px',\n padding: '20px',\n maxWidth: '400px',\n margin: '20px auto',\n boxShadow: '0 2px 4px rgba(0, 0, 0, 0.1)',\n fontFamily: 'monospace', \n }}>\n <h3 style={{fontSize: '0.8rem', opacity: 0.8}}>code: {error.code}</h3>\n <h1 style={{fontSize: '1.2rem', lineHeight: '1.5'}}>{error.title}</h1>\n <p>{error.message}</p>\n </div>\n}\n\n/*\npossible errors: \n- projectid missing / invalid\n- schema missing / invalid\n*/\n\nexport function useBasic() {\n return useContext(BasicContext);\n}\n","\"use client\"\n\nimport { v7 as uuidv7 } from 'uuid';\nimport { Dexie, PromiseExtended } from 'dexie';\n// if (typeof window !== 'undefined') {\n// import('dexie-observable');\n// }\nimport 'dexie-syncable';\nimport 'dexie-observable';\n\nimport { syncProtocol } from './syncProtocol'\nimport { SERVER_URL, log } from '../config'\nsyncProtocol()\n\n\n// const DexieSyncStatus = {\n// \"-1\": \"ERROR\",\n// \"0\": \"OFFLINE\",\n// \"1\": \"CONNECTING\",\n// \"2\": \"ONLINE\",\n// \"3\": \"SYNCING\",\n// \"4\": \"ERROR_WILL_RETRY\"\n// }\n\n\n\n\n\nexport class BasicSync extends Dexie {\n basic_schema: any\n\n constructor(name: string, options: any) {\n super(name, options);\n\n // --- INIT SCHEMA --- // \n\n //todo: handle versions?\n\n // TODO: validate schema\n this.basic_schema = options.schema\n this.version(1).stores(this._convertSchemaToDxSchema(this.basic_schema))\n\n this.version(2).stores({})\n // this.verssion\n\n\n // create an alias for toArray\n // @ts-ignore\n this.Collection.prototype.get = this.Collection.prototype.toArray\n\n\n // --- SYNC --- // \n\n // this.syncable.on(\"statusChanged\", (status, url) => { \n // console.log(\"statusChanged\", status, url)\n // })\n\n }\n\n async connect({ access_token }: { access_token: string }) {\n // const WS_URL = \"ws://localhost:3003/ws\"\n const WS_URL = `${SERVER_URL}/ws`\n\n \n // Update sync nodes\n await this.updateSyncNodes();\n \n // Proceed with the WebSocket connection\n \n log('Starting connection...')\n return this.syncable.connect(\"websocket\", WS_URL, { authToken: access_token });\n }\n\n private async updateSyncNodes() {\n try {\n const syncNodes = await this.table('_syncNodes').toArray();\n const localSyncNodes = syncNodes.filter(node => node.type === 'local');\n log('Local sync nodes:', localSyncNodes);\n\n if (localSyncNodes.length > 1) {\n\n \n const largestNodeId = Math.max(...localSyncNodes.map(node => node.id));\n // Check if the largest node is already the master\n const largestNode = localSyncNodes.find(node => node.id === largestNodeId);\n if (largestNode && largestNode.isMaster === 1) {\n log('Largest node is already the master. No changes needed.');\n return; // Exit the function early as no changes are needed\n }\n\n\n log('Largest node id:', largestNodeId);\n log('HEISENBUG: More than one local sync node found.')\n\n for (const node of localSyncNodes) {\n log(`Local sync node keys:`, node.id, node.isMaster);\n await this.table('_syncNodes').update(node.id, { isMaster: node.id === largestNodeId ? 1 : 0 });\n\n log(`HEISENBUG: Setting ${node.id} to ${node.id === largestNodeId ? 'master' : '0'}`);\n }\n\n // Add a 1 second delay before returning // i dont think this helps?\n await new Promise(resolve => setTimeout(resolve, 2000));\n\n }\n\n log('Sync nodes updated');\n } catch (error) {\n console.error('Error updating _syncNodes table:', error);\n }\n }\n\n handleStatusChange(fn: any) {\n this.syncable.on(\"statusChanged\", fn)\n }\n\n\n _convertSchemaToDxSchema(schema: any) {\n const stores = Object.entries(schema.tables).map(([key, table]: any) => {\n\n const indexedFields = Object.entries(table.fields).filter(([key, field]: any) => field.indexed).map(([key, field]: any) => `,${key}`).join('')\n return {\n [key]: 'id' + indexedFields\n }\n })\n\n return Object.assign({}, ...stores)\n }\n\n debugeroo() {\n // console.log(\"debugeroo\", this.syncable)\n\n // this.syncable.list().then(x => console.log(x))\n\n // this.syncable\n return this.syncable\n }\n\n\n collection(name: string) {\n // TODO: check against schema\n\n return {\n\n /**\n * Returns the underlying Dexie table\n * @type {Dexie.Table}\n */\n ref: this.table(name),\n\n // --- WRITE ---- // \n add: (data: any) => {\n log(\"Adding data to\", name, data)\n return this.table(name).add({\n id: uuidv7(),\n ...data\n })\n },\n\n put: (data: any) => {\n return this.table(name).put({\n id: uuidv7(),\n ...data\n })\n },\n\n update: (id: string, data: any) => {\n return this.table(name).update(id, data)\n },\n\n delete: (id: string) => {\n return this.table(name).delete(id)\n },\n\n\n // --- READ ---- // \n\n get: (id: string) => {\n return this.table(name).get(id)\n },\n\n getAll: () => {\n return this.table(name).toArray()\n },\n\n // --- QUERY ---- // \n // TODO: lots to do here. simplifing creating querie, filtering/ordering/limit, and execute\n\n query: () => this.table(name),\n\n filter: (fn: any) => this.table(name).filter(fn).toArray(),\n\n }\n }\n}\n","\"use client\"\nimport { Dexie } from \"dexie\";\nimport { log } from \"../config\";\n\nexport const syncProtocol = function () {\n log(\"Initializing syncProtocol\");\n // Constants:\n var RECONNECT_DELAY = 5000; // Reconnect delay in case of errors such as network down.\n\n Dexie.Syncable.registerSyncProtocol(\"websocket\", {\n sync: function (\n context,\n url,\n options,\n baseRevision,\n syncedRevision,\n changes,\n partial,\n applyRemoteChanges,\n onChangesAccepted,\n onSuccess,\n onError,\n ) {\n // The following vars are needed because we must know which callback to ack when server sends it's ack to us.\n var requestId = 0;\n var acceptCallbacks = {};\n\n // Connect the WebSocket to given url:\n var ws = new WebSocket(url);\n\n // console.log(\"ws OPTIONS\", options);\n\n // sendChanges() method:\n function sendChanges(changes, baseRevision, partial, onChangesAccepted) {\n log(\"sendChanges\", changes.length, baseRevision);\n ++requestId;\n acceptCallbacks[requestId.toString()] = onChangesAccepted;\n\n // In this example, the server expects the following JSON format of the request:\n // {\n // type: \"changes\"\n // baseRevision: baseRevision,\n // changes: changes,\n // partial: partial,\n // requestId: id\n // }\n // To make the sample simplified, we assume the server has the exact same specification of how changes are structured.\n // In real world, you would have to pre-process the changes array to fit the server specification.\n // However, this example shows how to deal with the WebSocket to fullfill the API.\n\n ws.send(\n JSON.stringify({\n type: \"changes\",\n changes: changes,\n partial: partial,\n baseRevision: baseRevision,\n requestId: requestId,\n }),\n );\n }\n\n\n\n // When WebSocket opens, send our changes to the server.\n ws.onopen = function (event) {\n // Initiate this socket connection by sending our clientIdentity. If we dont have a clientIdentity yet,\n // server will call back with a new client identity that we should use in future WebSocket connections.\n \n log(\"Opening socket - sending clientIdentity\", context.clientIdentity);\n ws.send(\n JSON.stringify({\n type: \"clientIdentity\",\n clientIdentity: context.clientIdentity || null,\n authToken: options.authToken\n }),\n );\n\n };\n\n // If network down or other error, tell the framework to reconnect again in some time:\n ws.onerror = function (event) {\n ws.close();\n log(\"ws.onerror\", event);\n onError(event?.message, RECONNECT_DELAY);\n };\n\n // If socket is closed (network disconnected), inform framework and make it reconnect\n ws.onclose = function (event) {\n onError(\"Socket closed: \" + event.reason, RECONNECT_DELAY);\n };\n\n // isFirstRound: Will need to call onSuccess() only when we are in sync the first time.\n // onSuccess() will unblock Dexie to be used by application code.\n // If for example app code writes: db.friends.where('shoeSize').above(40).toArray(callback), the execution of that query\n // will not run until we have called onSuccess(). This is because we want application code to get results that are as\n // accurate as possible. Specifically when connected the first time and the entire DB is being synced down to the browser,\n // it is important that queries starts running first when db is in sync.\n var isFirstRound = true;\n // When message arrive from the server, deal with the message accordingly:\n ws.onmessage = function (event) {\n try {\n // Assume we have a server that should send JSON messages of the following format:\n // {\n // type: \"clientIdentity\", \"changes\", \"ack\" or \"error\"\n // clientIdentity: unique value for our database client node to persist in the context. (Only applicable if type=\"clientIdentity\")\n // message: Error message (Only applicable if type=\"error\")\n // requestId: ID of change request that is acked by the server (Only applicable if type=\"ack\" or \"error\")\n // changes: changes from server (Only applicable if type=\"changes\")\n // lastRevision: last revision of changes sent (applicable if type=\"changes\")\n // partial: true if server has additionalChanges to send. False if these changes were the last known. (applicable if type=\"changes\")\n // }\n var requestFromServer = JSON.parse(event.data);\n log(\"requestFromServer\", requestFromServer, { acceptCallback, isFirstRound });\n\n if (requestFromServer.type == \"clientIdentity\") {\n context.clientIdentity = requestFromServer.clientIdentity;\n context.save();\n\n sendChanges(changes, baseRevision, partial, onChangesAccepted);\n\n ws.send(\n JSON.stringify({\n type: \"subscribe\",\n syncedRevision: syncedRevision,\n }),\n );\n } else if (requestFromServer.type == \"error\") {\n } else if (requestFromServer.type == \"changes\") {\n applyRemoteChanges(\n requestFromServer.changes,\n requestFromServer.currentRevision,\n requestFromServer.partial,\n );\n if (isFirstRound && !requestFromServer.partial) {\n // Since this is the first sync round and server sais we've got all changes - now is the time to call onsuccess()\n onSuccess({\n // Specify a react function that will react on additional client changes\n react: function (\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n ) {\n sendChanges(\n changes,\n baseRevision,\n partial,\n onChangesAccepted,\n );\n },\n // Specify a disconnect function that will close our socket so that we dont continue to monitor changes.\n disconnect: function () {\n ws.close();\n },\n });\n isFirstRound = false;\n }\n } else if (requestFromServer.type == \"ack\") {\n var requestId = requestFromServer.requestId;\n var acceptCallback = acceptCallbacks[requestId.toString()];\n acceptCallback(); // Tell framework that server has acknowledged the changes sent.\n delete acceptCallbacks[requestId.toString()];\n } else if (requestFromServer.type == \"error\") {\n var requestId = requestFromServer.requestId;\n ws.close();\n onError(requestFromServer.message, Infinity); // Don't reconnect - an error in application level means we have done something wrong.\n } else {\n log(\"unknown message\", requestFromServer);\n ws.close();\n onError(\"unknown message\", Infinity);\n }\n } catch (e) {\n ws.close();\n onError(e, Infinity); // Something went crazy. Server sends invalid format or our code is buggy. Dont reconnect - it would continue failing.\n }\n };\n },\n });\n};\n","import Ajv from 'ajv'\n\nexport const SERVER_URL = \"https://api.basic.tech\"\n// export const WS_URL = `${SERVER_URL}/ws`\n\nexport const log = (...args: any[]) => {\n try { \n if (localStorage.getItem('basic_debug') === 'true') {\n console.log('[basic]', ...args)\n }\n } catch (e) {\n // console.log('error logging', e)\n }\n}\n\n// export const log = (message: string, ...args: any[]) => {\n// try {\n// if (process.env.NODE_ENV === 'development') {\n// const stack = new Error().stack;\n// const caller = stack?.split('\\n')[2]?.trim();\n// console.log(`[basic] ${message}`, ...args);\n// // console.log(`[stack] ${caller}`);\n// }\n// } catch (e) {\n// console.error('Error in logWithStack:', e);\n// }\n// }\n\nconst basicJsonSchema = {\n \"$schema\": \"http://json-schema.org/draft-07/schema#\",\n \"type\": \"object\",\n \"properties\": {\n \"project_id\": {\n \"type\": \"string\"\n },\n \"namespace\": {\n \"type\": \"string\",\n },\n \"version\": {\n \"type\": \"integer\",\n \"minimum\": 0\n },\n \"tables\": {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"properties\": {\n \"name\": {\n \"type\": \"string\"\n },\n \"type\": {\n \"type\": \"string\",\n \"enum\": [\"collection\"]\n },\n \"fields\": {\n \"type\": \"object\",\n \"patternProperties\": {\n \"^[a-zA-Z0-9_]+$\": {\n \"type\": \"object\",\n \"properties\": {\n \"type\": {\n \"type\": \"string\"\n },\n \"primary\": {\n \"type\": \"boolean\"\n },\n \"indexed\": {\n \"type\": \"boolean\"\n }\n },\n \"required\": [\"type\"]\n }\n },\n \"additionalProperties\": true\n }\n },\n \"required\": [\"fields\"]\n }\n },\n \"additionalProperties\": true\n }\n },\n \"required\": [\"project_id\", \"version\", \"tables\"]\n}\n\n\nconst ajv = new Ajv()\nexport const validator = ajv.compile(basicJsonSchema)\n","//@ts-nocheck\n\nconst baseUrl = 'https://api.basic.tech';\n// const baseUrl = 'http://localhost:3000';\n\n\nasync function get({ projectId, accountId, tableName, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}`;\n const response = await fetch(url, {\n headers: {\n 'Authorization': `Bearer ${token}`\n }\n });\n return response.json();\n}\n\nasync function add({ projectId, accountId, tableName, value, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}`;\n const response = await fetch(url, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n },\n body: JSON.stringify({\"value\": value})\n });\n return response.json();\n}\n\nasync function update({ projectId, accountId, tableName, id, value, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}/${id}`;\n const response = await fetch(url, {\n method: 'PATCH',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${token}`\n },\n body: JSON.stringify({id: id, value: value})\n });\n return response.json();\n}\n\nasync function deleteRecord({ projectId, accountId, tableName, id, token }) {\n const url = `${baseUrl}/project/${projectId}/db/${accountId}/${tableName}/${id}`;\n const response = await fetch(url, {\n method: 'DELETE',\n headers: {\n 'Authorization': `Bearer ${token}`\n }\n });\n return response.json();\n}\n\nexport { get, add, update, deleteRecord };\n\n"],"mappings":"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","names":["useQuery","import_dexie","Ajv","changes","baseRevision","partial","onChangesAccepted","requestId","key","uuidv7","error","baseUrl","token","user"]}