@basictech/react 0.8.0-beta.1 → 0.8.0-beta.2
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/.turbo/turbo-build.log +10 -10
- package/changelog.md +6 -0
- package/dist/index.d.mts +59 -43
- package/dist/index.d.ts +59 -43
- package/dist/index.js +928 -161
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +919 -154
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -1
- package/readme.md +33 -0
- package/src/AuthContext.tsx +153 -177
- package/src/context.tsx +104 -0
- package/src/dev/BasicDevToolbar.tsx +665 -0
- package/src/index.ts +3 -2
- package/src/utils/network.ts +68 -15
package/dist/index.mjs
CHANGED
|
@@ -216,8 +216,809 @@ var init_syncProtocol = __esm({
|
|
|
216
216
|
}
|
|
217
217
|
});
|
|
218
218
|
|
|
219
|
+
// package.json
|
|
220
|
+
var version;
|
|
221
|
+
var init_package = __esm({
|
|
222
|
+
"package.json"() {
|
|
223
|
+
version = "0.8.0-beta.2";
|
|
224
|
+
}
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
// src/utils/network.ts
|
|
228
|
+
import semver from "semver";
|
|
229
|
+
function isDevelopment(debug) {
|
|
230
|
+
if (debug === true) return true;
|
|
231
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV === "development") return true;
|
|
232
|
+
if (typeof window === "undefined" || !window.location) return false;
|
|
233
|
+
const host = window.location.hostname;
|
|
234
|
+
return host === "localhost" || host === "127.0.0.1" || host.includes("localhost") || host.includes("127.0.0.1") || host.includes(".local");
|
|
235
|
+
}
|
|
236
|
+
function normalizeVersion(v) {
|
|
237
|
+
if (v == null) return null;
|
|
238
|
+
const t = String(v).trim();
|
|
239
|
+
return t.length ? t : null;
|
|
240
|
+
}
|
|
241
|
+
function versionsMatch(a, b) {
|
|
242
|
+
const na = a.trim();
|
|
243
|
+
const nb = b.trim();
|
|
244
|
+
if (na === nb) return true;
|
|
245
|
+
const va = semver.valid(na);
|
|
246
|
+
const vb = semver.valid(nb);
|
|
247
|
+
if (va && vb) return semver.eq(va, vb);
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
function usesBetaDistTag(version2) {
|
|
251
|
+
const pre = semver.prerelease(version2);
|
|
252
|
+
const id = pre?.[0];
|
|
253
|
+
return typeof id === "string" && id.toLowerCase() === "beta";
|
|
254
|
+
}
|
|
255
|
+
async function checkForNewVersion() {
|
|
256
|
+
try {
|
|
257
|
+
const currentVersion = normalizeVersion(version);
|
|
258
|
+
if (!currentVersion) {
|
|
259
|
+
return { hasNewVersion: false, latestVersion: null, currentVersion: null };
|
|
260
|
+
}
|
|
261
|
+
const response = await fetch("https://registry.npmjs.org/@basictech/react", {
|
|
262
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" }
|
|
263
|
+
});
|
|
264
|
+
if (!response.ok) {
|
|
265
|
+
throw new Error("Failed to fetch version from npm");
|
|
266
|
+
}
|
|
267
|
+
const data = await response.json();
|
|
268
|
+
const distTags = data["dist-tags"] ?? {};
|
|
269
|
+
const rawRegistry = usesBetaDistTag(currentVersion) ? distTags.beta ?? distTags.latest : distTags.latest;
|
|
270
|
+
const latestVersion = normalizeVersion(rawRegistry ?? null);
|
|
271
|
+
if (!latestVersion) {
|
|
272
|
+
throw new Error("Missing dist-tags from npm registry");
|
|
273
|
+
}
|
|
274
|
+
const same = versionsMatch(currentVersion, latestVersion);
|
|
275
|
+
if (!same && isDevelopment()) {
|
|
276
|
+
log("[basic] version check mismatch:", {
|
|
277
|
+
currentVersion,
|
|
278
|
+
registryVersion: latestVersion,
|
|
279
|
+
channel: usesBetaDistTag(currentVersion) ? "beta" : "latest"
|
|
280
|
+
});
|
|
281
|
+
}
|
|
282
|
+
if (!same) {
|
|
283
|
+
console.warn("[basic] New version available:", latestVersion, `
|
|
284
|
+
run "npm install @basictech/react@${latestVersion}" to update`);
|
|
285
|
+
}
|
|
286
|
+
if (usesBetaDistTag(currentVersion)) {
|
|
287
|
+
log("thank you for being on basictech/react beta :)");
|
|
288
|
+
}
|
|
289
|
+
return {
|
|
290
|
+
hasNewVersion: !same,
|
|
291
|
+
latestVersion,
|
|
292
|
+
currentVersion
|
|
293
|
+
};
|
|
294
|
+
} catch (error) {
|
|
295
|
+
log("Error checking for new version:", error);
|
|
296
|
+
return {
|
|
297
|
+
hasNewVersion: false,
|
|
298
|
+
latestVersion: null,
|
|
299
|
+
currentVersion: null
|
|
300
|
+
};
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
function cleanOAuthParamsFromUrl() {
|
|
304
|
+
if (window.location.search.includes("code") || window.location.search.includes("state")) {
|
|
305
|
+
const url = new URL(window.location.href);
|
|
306
|
+
url.searchParams.delete("code");
|
|
307
|
+
url.searchParams.delete("state");
|
|
308
|
+
window.history.pushState({}, document.title, url.pathname + url.search);
|
|
309
|
+
log("Cleaned OAuth parameters from URL");
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
function getSyncStatus(statusCode) {
|
|
313
|
+
switch (statusCode) {
|
|
314
|
+
case -1:
|
|
315
|
+
return "ERROR";
|
|
316
|
+
case 0:
|
|
317
|
+
return "OFFLINE";
|
|
318
|
+
case 1:
|
|
319
|
+
return "CONNECTING";
|
|
320
|
+
case 2:
|
|
321
|
+
return "ONLINE";
|
|
322
|
+
case 3:
|
|
323
|
+
return "SYNCING";
|
|
324
|
+
case 4:
|
|
325
|
+
return "ERROR_WILL_RETRY";
|
|
326
|
+
default:
|
|
327
|
+
return "UNKNOWN";
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
var init_network = __esm({
|
|
331
|
+
"src/utils/network.ts"() {
|
|
332
|
+
"use strict";
|
|
333
|
+
init_config();
|
|
334
|
+
init_package();
|
|
335
|
+
}
|
|
336
|
+
});
|
|
337
|
+
|
|
338
|
+
// src/context.tsx
|
|
339
|
+
import { createContext, useContext } from "react";
|
|
340
|
+
function useBasic() {
|
|
341
|
+
return useContext(BasicContext);
|
|
342
|
+
}
|
|
343
|
+
var DBStatus, noDb, BasicContext;
|
|
344
|
+
var init_context = __esm({
|
|
345
|
+
"src/context.tsx"() {
|
|
346
|
+
"use strict";
|
|
347
|
+
DBStatus = /* @__PURE__ */ ((DBStatus2) => {
|
|
348
|
+
DBStatus2["LOADING"] = "LOADING";
|
|
349
|
+
DBStatus2["OFFLINE"] = "OFFLINE";
|
|
350
|
+
DBStatus2["CONNECTING"] = "CONNECTING";
|
|
351
|
+
DBStatus2["ONLINE"] = "ONLINE";
|
|
352
|
+
DBStatus2["SYNCING"] = "SYNCING";
|
|
353
|
+
DBStatus2["ERROR"] = "ERROR";
|
|
354
|
+
DBStatus2["ERROR_WILL_RETRY"] = "ERROR_WILL_RETRY";
|
|
355
|
+
DBStatus2["ERROR_TOKEN_EXPIRED"] = "ERROR_TOKEN_EXPIRED";
|
|
356
|
+
return DBStatus2;
|
|
357
|
+
})(DBStatus || {});
|
|
358
|
+
noDb = {
|
|
359
|
+
collection: () => {
|
|
360
|
+
throw new Error("no basicdb found - initialization failed. double check your schema.");
|
|
361
|
+
}
|
|
362
|
+
};
|
|
363
|
+
BasicContext = createContext({
|
|
364
|
+
isReady: false,
|
|
365
|
+
isSignedIn: false,
|
|
366
|
+
user: null,
|
|
367
|
+
did: null,
|
|
368
|
+
scope: null,
|
|
369
|
+
hasScope: () => false,
|
|
370
|
+
missingScopes: () => [],
|
|
371
|
+
signIn: () => Promise.resolve(),
|
|
372
|
+
signInWithHandle: () => Promise.resolve(),
|
|
373
|
+
signOut: () => Promise.resolve(),
|
|
374
|
+
signInWithCode: () => Promise.resolve({ success: false }),
|
|
375
|
+
getToken: (_options) => Promise.reject(new Error("no token")),
|
|
376
|
+
getSignInUrl: () => Promise.resolve(""),
|
|
377
|
+
db: noDb,
|
|
378
|
+
dbStatus: "LOADING" /* LOADING */,
|
|
379
|
+
dbMode: "sync",
|
|
380
|
+
devInfo: null,
|
|
381
|
+
refreshSchemaStatus: async () => {
|
|
382
|
+
},
|
|
383
|
+
isAuthReady: false,
|
|
384
|
+
signin: () => Promise.resolve(),
|
|
385
|
+
signout: () => Promise.resolve(),
|
|
386
|
+
signinWithCode: () => Promise.resolve({ success: false }),
|
|
387
|
+
getSignInLink: () => Promise.resolve("")
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
});
|
|
391
|
+
|
|
392
|
+
// src/dev/BasicDevToolbar.tsx
|
|
393
|
+
var BasicDevToolbar_exports = {};
|
|
394
|
+
__export(BasicDevToolbar_exports, {
|
|
395
|
+
BasicDevToolbar: () => BasicDevToolbar
|
|
396
|
+
});
|
|
397
|
+
import { useCallback, useMemo, useState } from "react";
|
|
398
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
399
|
+
function toneForAuth(isReady, isSignedIn) {
|
|
400
|
+
if (!isReady) return "muted";
|
|
401
|
+
if (isSignedIn) return "ok";
|
|
402
|
+
return "warn";
|
|
403
|
+
}
|
|
404
|
+
function toneForDb(dbMode, dbStatus) {
|
|
405
|
+
if (dbMode === "remote") return dbStatus === "ONLINE" /* ONLINE */ ? "ok" : "warn";
|
|
406
|
+
if (dbStatus === "ONLINE" /* ONLINE */ || dbStatus === "SYNCING" /* SYNCING */) return "ok";
|
|
407
|
+
if (dbStatus === "CONNECTING" /* CONNECTING */ || dbStatus === "LOADING" /* LOADING */) return "warn";
|
|
408
|
+
if (dbStatus === "OFFLINE" /* OFFLINE */) return "muted";
|
|
409
|
+
return "bad";
|
|
410
|
+
}
|
|
411
|
+
function toneForSchema(info) {
|
|
412
|
+
if (!info) return "muted";
|
|
413
|
+
if (info.valid && info.status === "current") return "ok";
|
|
414
|
+
if (info.status === "unpublished") return "warn";
|
|
415
|
+
if (info.status === "no_schema") return "muted";
|
|
416
|
+
return "bad";
|
|
417
|
+
}
|
|
418
|
+
function dbStatusLabel(status) {
|
|
419
|
+
switch (status) {
|
|
420
|
+
case "LOADING" /* LOADING */:
|
|
421
|
+
return "Initializing";
|
|
422
|
+
case "OFFLINE" /* OFFLINE */:
|
|
423
|
+
return "Offline";
|
|
424
|
+
case "CONNECTING" /* CONNECTING */:
|
|
425
|
+
return "Connecting";
|
|
426
|
+
case "ONLINE" /* ONLINE */:
|
|
427
|
+
return "Connected";
|
|
428
|
+
case "SYNCING" /* SYNCING */:
|
|
429
|
+
return "Syncing";
|
|
430
|
+
case "ERROR" /* ERROR */:
|
|
431
|
+
return "Error";
|
|
432
|
+
case "ERROR_WILL_RETRY" /* ERROR_WILL_RETRY */:
|
|
433
|
+
return "Retrying";
|
|
434
|
+
case "ERROR_TOKEN_EXPIRED" /* ERROR_TOKEN_EXPIRED */:
|
|
435
|
+
return "Token refresh";
|
|
436
|
+
default:
|
|
437
|
+
return String(status);
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
function chipColor(tone) {
|
|
441
|
+
switch (tone) {
|
|
442
|
+
case "ok":
|
|
443
|
+
return "#22c55e";
|
|
444
|
+
case "warn":
|
|
445
|
+
return "#eab308";
|
|
446
|
+
case "bad":
|
|
447
|
+
return "#ef4444";
|
|
448
|
+
default:
|
|
449
|
+
return "#71717a";
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
function displayDid(did) {
|
|
453
|
+
return did || "\u2014";
|
|
454
|
+
}
|
|
455
|
+
function displayUserLine(user) {
|
|
456
|
+
const parts = [];
|
|
457
|
+
if (user.sub) parts.push(`sub: ${user.sub}`);
|
|
458
|
+
if (user.email) parts.push(`email: ${user.email}`);
|
|
459
|
+
if (user.name) parts.push(`name: ${user.name}`);
|
|
460
|
+
return parts.length ? parts.join(" \xB7 ") : "\u2014";
|
|
461
|
+
}
|
|
462
|
+
function ClipboardIcon() {
|
|
463
|
+
return /* @__PURE__ */ jsxs(
|
|
464
|
+
"svg",
|
|
465
|
+
{
|
|
466
|
+
width: "14",
|
|
467
|
+
height: "14",
|
|
468
|
+
viewBox: "0 0 24 24",
|
|
469
|
+
fill: "none",
|
|
470
|
+
stroke: "currentColor",
|
|
471
|
+
strokeWidth: "2",
|
|
472
|
+
strokeLinecap: "round",
|
|
473
|
+
strokeLinejoin: "round",
|
|
474
|
+
"aria-hidden": true,
|
|
475
|
+
children: [
|
|
476
|
+
/* @__PURE__ */ jsx("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
|
|
477
|
+
/* @__PURE__ */ jsx("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
478
|
+
]
|
|
479
|
+
}
|
|
480
|
+
);
|
|
481
|
+
}
|
|
482
|
+
function SectionHeader({ children }) {
|
|
483
|
+
return /* @__PURE__ */ jsx(
|
|
484
|
+
"div",
|
|
485
|
+
{
|
|
486
|
+
style: {
|
|
487
|
+
fontSize: 10,
|
|
488
|
+
fontWeight: 700,
|
|
489
|
+
color: "#e4e4e7",
|
|
490
|
+
letterSpacing: "0.07em",
|
|
491
|
+
textTransform: "uppercase",
|
|
492
|
+
marginBottom: 8
|
|
493
|
+
},
|
|
494
|
+
children
|
|
495
|
+
}
|
|
496
|
+
);
|
|
497
|
+
}
|
|
498
|
+
function SectionRule() {
|
|
499
|
+
const bleed = PANEL_PAD_X;
|
|
500
|
+
return /* @__PURE__ */ jsx(
|
|
501
|
+
"div",
|
|
502
|
+
{
|
|
503
|
+
role: "separator",
|
|
504
|
+
style: {
|
|
505
|
+
height: 1,
|
|
506
|
+
background: "rgba(255, 255, 255, 0.055)",
|
|
507
|
+
marginLeft: -bleed,
|
|
508
|
+
marginRight: -bleed,
|
|
509
|
+
marginTop: 14,
|
|
510
|
+
marginBottom: 10,
|
|
511
|
+
width: `calc(100% + ${bleed * 2}px)`
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
function CopyableRow({
|
|
517
|
+
rowKey,
|
|
518
|
+
label,
|
|
519
|
+
copyText,
|
|
520
|
+
copiedKey,
|
|
521
|
+
onCopied,
|
|
522
|
+
children
|
|
523
|
+
}) {
|
|
524
|
+
const [hover, setHover] = useState(false);
|
|
525
|
+
const canCopy = copyText.length > 0;
|
|
526
|
+
const handleClick = useCallback(
|
|
527
|
+
(e) => {
|
|
528
|
+
e.stopPropagation();
|
|
529
|
+
if (!canCopy) return;
|
|
530
|
+
void navigator.clipboard.writeText(copyText).then(() => onCopied(rowKey));
|
|
531
|
+
},
|
|
532
|
+
[canCopy, copyText, onCopied, rowKey]
|
|
533
|
+
);
|
|
534
|
+
return /* @__PURE__ */ jsxs(
|
|
535
|
+
"div",
|
|
536
|
+
{
|
|
537
|
+
role: canCopy ? "button" : void 0,
|
|
538
|
+
tabIndex: canCopy ? 0 : void 0,
|
|
539
|
+
onClick: canCopy ? handleClick : void 0,
|
|
540
|
+
onKeyDown: canCopy ? (e) => {
|
|
541
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
542
|
+
e.preventDefault();
|
|
543
|
+
handleClick(e);
|
|
544
|
+
}
|
|
545
|
+
} : void 0,
|
|
546
|
+
onMouseEnter: () => setHover(true),
|
|
547
|
+
onMouseLeave: () => setHover(false),
|
|
548
|
+
style: {
|
|
549
|
+
display: "flex",
|
|
550
|
+
gap: 8,
|
|
551
|
+
marginBottom: 6,
|
|
552
|
+
alignItems: "flex-start",
|
|
553
|
+
borderRadius: 6,
|
|
554
|
+
padding: "4px 6px",
|
|
555
|
+
marginLeft: -6,
|
|
556
|
+
marginRight: -6,
|
|
557
|
+
cursor: canCopy ? "pointer" : "default",
|
|
558
|
+
background: hover && canCopy ? "rgba(255,255,255,0.06)" : "transparent",
|
|
559
|
+
transition: "background 0.12s ease"
|
|
560
|
+
},
|
|
561
|
+
children: [
|
|
562
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#a1a1aa", minWidth: 88, flexShrink: 0, paddingTop: 2 }, children: label }),
|
|
563
|
+
/* @__PURE__ */ jsx(
|
|
564
|
+
"span",
|
|
565
|
+
{
|
|
566
|
+
style: {
|
|
567
|
+
flex: 1,
|
|
568
|
+
minWidth: 0,
|
|
569
|
+
wordBreak: "break-all",
|
|
570
|
+
paddingTop: 2,
|
|
571
|
+
lineHeight: 1.35
|
|
572
|
+
},
|
|
573
|
+
children
|
|
574
|
+
}
|
|
575
|
+
),
|
|
576
|
+
canCopy && /* @__PURE__ */ jsx(
|
|
577
|
+
"span",
|
|
578
|
+
{
|
|
579
|
+
style: {
|
|
580
|
+
flexShrink: 0,
|
|
581
|
+
color: copiedKey === rowKey ? "#22c55e" : "#71717a",
|
|
582
|
+
opacity: hover || copiedKey === rowKey ? 1 : 0,
|
|
583
|
+
transition: "opacity 0.12s ease, color 0.12s ease",
|
|
584
|
+
paddingTop: 2,
|
|
585
|
+
display: "flex",
|
|
586
|
+
alignItems: "flex-start"
|
|
587
|
+
},
|
|
588
|
+
title: "Copy value",
|
|
589
|
+
children: copiedKey === rowKey ? /* @__PURE__ */ jsx("span", { style: { fontSize: 10 }, children: "\u2713" }) : /* @__PURE__ */ jsx(ClipboardIcon, {})
|
|
590
|
+
}
|
|
591
|
+
)
|
|
592
|
+
]
|
|
593
|
+
}
|
|
594
|
+
);
|
|
595
|
+
}
|
|
596
|
+
function BasicDevToolbar({ enabled = true, debug }) {
|
|
597
|
+
const {
|
|
598
|
+
isReady,
|
|
599
|
+
isSignedIn,
|
|
600
|
+
user,
|
|
601
|
+
did,
|
|
602
|
+
scope,
|
|
603
|
+
missingScopes,
|
|
604
|
+
dbMode,
|
|
605
|
+
dbStatus,
|
|
606
|
+
devInfo,
|
|
607
|
+
refreshSchemaStatus
|
|
608
|
+
} = useBasic();
|
|
609
|
+
const [open, setOpen] = useState(false);
|
|
610
|
+
const [refreshing, setRefreshing] = useState(false);
|
|
611
|
+
const [copied, setCopied] = useState(false);
|
|
612
|
+
const [rowCopied, setRowCopied] = useState(null);
|
|
613
|
+
const show = enabled && typeof window !== "undefined" && isDevelopment(debug);
|
|
614
|
+
const authTone = toneForAuth(isReady, isSignedIn);
|
|
615
|
+
const dbTone = toneForDb(dbMode, dbStatus);
|
|
616
|
+
const schemaTone = toneForSchema(devInfo);
|
|
617
|
+
const syncTone = dbMode === "remote" ? "muted" : dbTone === "ok" || dbStatus === "SYNCING" /* SYNCING */ ? "ok" : dbTone === "warn" ? "warn" : dbTone === "bad" ? "bad" : "muted";
|
|
618
|
+
const handleRefreshSchema = useCallback(async () => {
|
|
619
|
+
setRefreshing(true);
|
|
620
|
+
try {
|
|
621
|
+
await refreshSchemaStatus();
|
|
622
|
+
} finally {
|
|
623
|
+
setRefreshing(false);
|
|
624
|
+
}
|
|
625
|
+
}, [refreshSchemaStatus]);
|
|
626
|
+
const missingList = missingScopes();
|
|
627
|
+
const debugPayload = useMemo(() => {
|
|
628
|
+
return {
|
|
629
|
+
sdkVersion: version,
|
|
630
|
+
isReady,
|
|
631
|
+
isSignedIn,
|
|
632
|
+
did: did ?? null,
|
|
633
|
+
user: user ? {
|
|
634
|
+
sub: user.sub,
|
|
635
|
+
email: user.email,
|
|
636
|
+
name: user.name,
|
|
637
|
+
picture: user.picture
|
|
638
|
+
} : null,
|
|
639
|
+
scope,
|
|
640
|
+
missingScopes: missingList,
|
|
641
|
+
dbMode,
|
|
642
|
+
dbStatus,
|
|
643
|
+
indexedDbName: dbMode === "sync" ? INDEXED_DB_NAME : null,
|
|
644
|
+
schema: devInfo
|
|
645
|
+
};
|
|
646
|
+
}, [isReady, isSignedIn, did, user, scope, dbMode, dbStatus, devInfo, missingList]);
|
|
647
|
+
const handleCopy = useCallback(async () => {
|
|
648
|
+
try {
|
|
649
|
+
await navigator.clipboard.writeText(JSON.stringify(debugPayload, null, 2));
|
|
650
|
+
setCopied(true);
|
|
651
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
652
|
+
} catch {
|
|
653
|
+
}
|
|
654
|
+
}, [debugPayload]);
|
|
655
|
+
const onRowCopied = useCallback((key) => {
|
|
656
|
+
setRowCopied(key);
|
|
657
|
+
setTimeout(() => setRowCopied((k) => k === key ? null : k), 1500);
|
|
658
|
+
}, []);
|
|
659
|
+
if (!show) return null;
|
|
660
|
+
const shell = {
|
|
661
|
+
position: "fixed",
|
|
662
|
+
bottom: 12,
|
|
663
|
+
left: "50%",
|
|
664
|
+
transform: "translateX(-50%)",
|
|
665
|
+
zIndex: 99999,
|
|
666
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
667
|
+
fontSize: 11,
|
|
668
|
+
color: "#e4e4e7",
|
|
669
|
+
pointerEvents: "auto"
|
|
670
|
+
};
|
|
671
|
+
const bar = {
|
|
672
|
+
display: "flex",
|
|
673
|
+
alignItems: "center",
|
|
674
|
+
gap: 8,
|
|
675
|
+
padding: "8px 12px",
|
|
676
|
+
borderRadius: 999,
|
|
677
|
+
background: "rgba(24, 24, 27, 0.92)",
|
|
678
|
+
border: "1px solid rgba(63, 63, 70, 0.9)",
|
|
679
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.35)",
|
|
680
|
+
cursor: "pointer",
|
|
681
|
+
userSelect: "none"
|
|
682
|
+
};
|
|
683
|
+
const dot = (tone) => /* @__PURE__ */ jsx(
|
|
684
|
+
"span",
|
|
685
|
+
{
|
|
686
|
+
style: {
|
|
687
|
+
display: "block",
|
|
688
|
+
boxSizing: "border-box",
|
|
689
|
+
width: 6,
|
|
690
|
+
height: 6,
|
|
691
|
+
minWidth: 6,
|
|
692
|
+
minHeight: 6,
|
|
693
|
+
maxWidth: 6,
|
|
694
|
+
maxHeight: 6,
|
|
695
|
+
borderRadius: "50%",
|
|
696
|
+
background: chipColor(tone),
|
|
697
|
+
flexShrink: 0
|
|
698
|
+
}
|
|
699
|
+
}
|
|
700
|
+
);
|
|
701
|
+
const dotSlot = (title, tone) => /* @__PURE__ */ jsx(
|
|
702
|
+
"span",
|
|
703
|
+
{
|
|
704
|
+
title,
|
|
705
|
+
style: {
|
|
706
|
+
display: "inline-flex",
|
|
707
|
+
alignItems: "center",
|
|
708
|
+
justifyContent: "center",
|
|
709
|
+
width: 6,
|
|
710
|
+
height: 6,
|
|
711
|
+
flexShrink: 0,
|
|
712
|
+
lineHeight: 0
|
|
713
|
+
},
|
|
714
|
+
children: dot(tone)
|
|
715
|
+
}
|
|
716
|
+
);
|
|
717
|
+
const panel = {
|
|
718
|
+
marginBottom: 8,
|
|
719
|
+
maxHeight: "50vh",
|
|
720
|
+
overflow: "auto",
|
|
721
|
+
padding: PANEL_PAD_X,
|
|
722
|
+
borderRadius: 10,
|
|
723
|
+
background: "rgba(24, 24, 27, 0.96)",
|
|
724
|
+
border: "1px solid rgba(63, 63, 70, 0.9)",
|
|
725
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.35)",
|
|
726
|
+
minWidth: 300,
|
|
727
|
+
maxWidth: "min(560px, calc(100vw - 24px))"
|
|
728
|
+
};
|
|
729
|
+
const syncStatusText = dbStatusLabel(dbStatus);
|
|
730
|
+
return /* @__PURE__ */ jsxs("div", { style: shell, children: [
|
|
731
|
+
open && /* @__PURE__ */ jsxs("div", { style: panel, children: [
|
|
732
|
+
/* @__PURE__ */ jsxs("div", { style: { marginBottom: 12 }, children: [
|
|
733
|
+
/* @__PURE__ */ jsx("div", { style: { fontWeight: 600, fontSize: 12 }, children: "Basic SDK" }),
|
|
734
|
+
/* @__PURE__ */ jsxs("div", { style: { color: "#71717a", fontSize: 10, marginTop: 2 }, children: [
|
|
735
|
+
"v",
|
|
736
|
+
version
|
|
737
|
+
] })
|
|
738
|
+
] }),
|
|
739
|
+
/* @__PURE__ */ jsx(SectionHeader, { children: "Auth" }),
|
|
740
|
+
/* @__PURE__ */ jsx(
|
|
741
|
+
CopyableRow,
|
|
742
|
+
{
|
|
743
|
+
rowKey: "ready",
|
|
744
|
+
label: "Ready",
|
|
745
|
+
copyText: String(isReady),
|
|
746
|
+
copiedKey: rowCopied,
|
|
747
|
+
onCopied: onRowCopied,
|
|
748
|
+
children: String(isReady)
|
|
749
|
+
}
|
|
750
|
+
),
|
|
751
|
+
/* @__PURE__ */ jsx(
|
|
752
|
+
CopyableRow,
|
|
753
|
+
{
|
|
754
|
+
rowKey: "signedIn",
|
|
755
|
+
label: "Signed in",
|
|
756
|
+
copyText: String(isSignedIn),
|
|
757
|
+
copiedKey: rowCopied,
|
|
758
|
+
onCopied: onRowCopied,
|
|
759
|
+
children: String(isSignedIn)
|
|
760
|
+
}
|
|
761
|
+
),
|
|
762
|
+
/* @__PURE__ */ jsx(
|
|
763
|
+
CopyableRow,
|
|
764
|
+
{
|
|
765
|
+
rowKey: "did",
|
|
766
|
+
label: "DID",
|
|
767
|
+
copyText: did || "",
|
|
768
|
+
copiedKey: rowCopied,
|
|
769
|
+
onCopied: onRowCopied,
|
|
770
|
+
children: displayDid(did)
|
|
771
|
+
}
|
|
772
|
+
),
|
|
773
|
+
/* @__PURE__ */ jsx(
|
|
774
|
+
CopyableRow,
|
|
775
|
+
{
|
|
776
|
+
rowKey: "user",
|
|
777
|
+
label: "User",
|
|
778
|
+
copyText: user ? displayUserLine(user) : "",
|
|
779
|
+
copiedKey: rowCopied,
|
|
780
|
+
onCopied: onRowCopied,
|
|
781
|
+
children: user ? displayUserLine(user) : "\u2014"
|
|
782
|
+
}
|
|
783
|
+
),
|
|
784
|
+
/* @__PURE__ */ jsx(
|
|
785
|
+
CopyableRow,
|
|
786
|
+
{
|
|
787
|
+
rowKey: "scopes",
|
|
788
|
+
label: "Scopes",
|
|
789
|
+
copyText: scope || "",
|
|
790
|
+
copiedKey: rowCopied,
|
|
791
|
+
onCopied: onRowCopied,
|
|
792
|
+
children: scope || "\u2014"
|
|
793
|
+
}
|
|
794
|
+
),
|
|
795
|
+
/* @__PURE__ */ jsx(
|
|
796
|
+
CopyableRow,
|
|
797
|
+
{
|
|
798
|
+
rowKey: "missingScopes",
|
|
799
|
+
label: "Missing scopes",
|
|
800
|
+
copyText: missingList.length ? missingList.join(", ") : "",
|
|
801
|
+
copiedKey: rowCopied,
|
|
802
|
+
onCopied: onRowCopied,
|
|
803
|
+
children: missingList.length ? missingList.join(", ") : "\u2014"
|
|
804
|
+
}
|
|
805
|
+
),
|
|
806
|
+
/* @__PURE__ */ jsx(SectionRule, {}),
|
|
807
|
+
/* @__PURE__ */ jsx(SectionHeader, { children: "Database" }),
|
|
808
|
+
/* @__PURE__ */ jsx(
|
|
809
|
+
CopyableRow,
|
|
810
|
+
{
|
|
811
|
+
rowKey: "dbMode",
|
|
812
|
+
label: "Mode",
|
|
813
|
+
copyText: dbMode,
|
|
814
|
+
copiedKey: rowCopied,
|
|
815
|
+
onCopied: onRowCopied,
|
|
816
|
+
children: dbMode
|
|
817
|
+
}
|
|
818
|
+
),
|
|
819
|
+
/* @__PURE__ */ jsx(
|
|
820
|
+
CopyableRow,
|
|
821
|
+
{
|
|
822
|
+
rowKey: "indexedDb",
|
|
823
|
+
label: "IndexedDB",
|
|
824
|
+
copyText: dbMode === "sync" ? INDEXED_DB_NAME : "",
|
|
825
|
+
copiedKey: rowCopied,
|
|
826
|
+
onCopied: onRowCopied,
|
|
827
|
+
children: dbMode === "sync" ? INDEXED_DB_NAME : "\u2014"
|
|
828
|
+
}
|
|
829
|
+
),
|
|
830
|
+
/* @__PURE__ */ jsx(
|
|
831
|
+
CopyableRow,
|
|
832
|
+
{
|
|
833
|
+
rowKey: "syncStatus",
|
|
834
|
+
label: "Sync / status",
|
|
835
|
+
copyText: syncStatusText,
|
|
836
|
+
copiedKey: rowCopied,
|
|
837
|
+
onCopied: onRowCopied,
|
|
838
|
+
children: syncStatusText
|
|
839
|
+
}
|
|
840
|
+
),
|
|
841
|
+
/* @__PURE__ */ jsx(SectionRule, {}),
|
|
842
|
+
/* @__PURE__ */ jsx(SectionHeader, { children: "Schema" }),
|
|
843
|
+
devInfo ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
844
|
+
/* @__PURE__ */ jsx(
|
|
845
|
+
CopyableRow,
|
|
846
|
+
{
|
|
847
|
+
rowKey: "schemaProject",
|
|
848
|
+
label: "Project",
|
|
849
|
+
copyText: devInfo.projectId ?? "",
|
|
850
|
+
copiedKey: rowCopied,
|
|
851
|
+
onCopied: onRowCopied,
|
|
852
|
+
children: devInfo.projectId ?? "\u2014"
|
|
853
|
+
}
|
|
854
|
+
),
|
|
855
|
+
/* @__PURE__ */ jsx(
|
|
856
|
+
CopyableRow,
|
|
857
|
+
{
|
|
858
|
+
rowKey: "schemaLocalVer",
|
|
859
|
+
label: "Local version",
|
|
860
|
+
copyText: devInfo.localVersion !== void 0 && devInfo.localVersion !== null ? String(devInfo.localVersion) : "",
|
|
861
|
+
copiedKey: rowCopied,
|
|
862
|
+
onCopied: onRowCopied,
|
|
863
|
+
children: devInfo.localVersion ?? "\u2014"
|
|
864
|
+
}
|
|
865
|
+
),
|
|
866
|
+
/* @__PURE__ */ jsx(
|
|
867
|
+
CopyableRow,
|
|
868
|
+
{
|
|
869
|
+
rowKey: "schemaRemote",
|
|
870
|
+
label: "Remote check",
|
|
871
|
+
copyText: devInfo.status,
|
|
872
|
+
copiedKey: rowCopied,
|
|
873
|
+
onCopied: onRowCopied,
|
|
874
|
+
children: devInfo.status
|
|
875
|
+
}
|
|
876
|
+
),
|
|
877
|
+
/* @__PURE__ */ jsx(
|
|
878
|
+
CopyableRow,
|
|
879
|
+
{
|
|
880
|
+
rowKey: "schemaValid",
|
|
881
|
+
label: "Valid",
|
|
882
|
+
copyText: String(devInfo.valid),
|
|
883
|
+
copiedKey: rowCopied,
|
|
884
|
+
onCopied: onRowCopied,
|
|
885
|
+
children: String(devInfo.valid)
|
|
886
|
+
}
|
|
887
|
+
),
|
|
888
|
+
/* @__PURE__ */ jsx(
|
|
889
|
+
CopyableRow,
|
|
890
|
+
{
|
|
891
|
+
rowKey: "schemaChecked",
|
|
892
|
+
label: "Checked",
|
|
893
|
+
copyText: devInfo.lastCheckedAt ? new Date(devInfo.lastCheckedAt).toISOString() : "",
|
|
894
|
+
copiedKey: rowCopied,
|
|
895
|
+
onCopied: onRowCopied,
|
|
896
|
+
children: devInfo.lastCheckedAt ? new Date(devInfo.lastCheckedAt).toLocaleString() : "\u2014"
|
|
897
|
+
}
|
|
898
|
+
),
|
|
899
|
+
devInfo.error ? /* @__PURE__ */ jsx(
|
|
900
|
+
CopyableRow,
|
|
901
|
+
{
|
|
902
|
+
rowKey: "schemaError",
|
|
903
|
+
label: "Error",
|
|
904
|
+
copyText: devInfo.error,
|
|
905
|
+
copiedKey: rowCopied,
|
|
906
|
+
onCopied: onRowCopied,
|
|
907
|
+
children: devInfo.error
|
|
908
|
+
}
|
|
909
|
+
) : null
|
|
910
|
+
] }) : /* @__PURE__ */ jsx(
|
|
911
|
+
CopyableRow,
|
|
912
|
+
{
|
|
913
|
+
rowKey: "schemaStatus",
|
|
914
|
+
label: "Status",
|
|
915
|
+
copyText: "No schema on provider",
|
|
916
|
+
copiedKey: rowCopied,
|
|
917
|
+
onCopied: onRowCopied,
|
|
918
|
+
children: "No schema on provider"
|
|
919
|
+
}
|
|
920
|
+
),
|
|
921
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }, children: [
|
|
922
|
+
/* @__PURE__ */ jsx(
|
|
923
|
+
"button",
|
|
924
|
+
{
|
|
925
|
+
type: "button",
|
|
926
|
+
onClick: (e) => {
|
|
927
|
+
e.stopPropagation();
|
|
928
|
+
void handleRefreshSchema();
|
|
929
|
+
},
|
|
930
|
+
disabled: refreshing,
|
|
931
|
+
style: {
|
|
932
|
+
padding: "6px 10px",
|
|
933
|
+
borderRadius: 6,
|
|
934
|
+
border: "1px solid #3f3f46",
|
|
935
|
+
background: "#27272a",
|
|
936
|
+
color: "#e4e4e7",
|
|
937
|
+
cursor: refreshing ? "wait" : "pointer",
|
|
938
|
+
fontSize: 11,
|
|
939
|
+
fontFamily: "inherit"
|
|
940
|
+
},
|
|
941
|
+
children: refreshing ? "Refreshing\u2026" : "Refresh schema"
|
|
942
|
+
}
|
|
943
|
+
),
|
|
944
|
+
/* @__PURE__ */ jsx(
|
|
945
|
+
"button",
|
|
946
|
+
{
|
|
947
|
+
type: "button",
|
|
948
|
+
onClick: (e) => {
|
|
949
|
+
e.stopPropagation();
|
|
950
|
+
void handleCopy();
|
|
951
|
+
},
|
|
952
|
+
style: {
|
|
953
|
+
padding: "6px 10px",
|
|
954
|
+
borderRadius: 6,
|
|
955
|
+
border: "1px solid #3f3f46",
|
|
956
|
+
background: "#27272a",
|
|
957
|
+
color: "#e4e4e7",
|
|
958
|
+
cursor: "pointer",
|
|
959
|
+
fontSize: 11,
|
|
960
|
+
fontFamily: "inherit"
|
|
961
|
+
},
|
|
962
|
+
children: copied ? "Copied" : "Copy debug info"
|
|
963
|
+
}
|
|
964
|
+
)
|
|
965
|
+
] })
|
|
966
|
+
] }),
|
|
967
|
+
/* @__PURE__ */ jsxs(
|
|
968
|
+
"button",
|
|
969
|
+
{
|
|
970
|
+
type: "button",
|
|
971
|
+
"aria-expanded": open,
|
|
972
|
+
onClick: () => setOpen((o) => !o),
|
|
973
|
+
style: {
|
|
974
|
+
...bar,
|
|
975
|
+
border: "none",
|
|
976
|
+
width: "100%",
|
|
977
|
+
cursor: "pointer"
|
|
978
|
+
},
|
|
979
|
+
children: [
|
|
980
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600, letterSpacing: 0.02 }, children: "Basic" }),
|
|
981
|
+
/* @__PURE__ */ jsxs(
|
|
982
|
+
"span",
|
|
983
|
+
{
|
|
984
|
+
style: {
|
|
985
|
+
display: "inline-flex",
|
|
986
|
+
alignItems: "center",
|
|
987
|
+
gap: 6,
|
|
988
|
+
marginLeft: 8,
|
|
989
|
+
height: 6,
|
|
990
|
+
flexShrink: 0,
|
|
991
|
+
lineHeight: 0
|
|
992
|
+
},
|
|
993
|
+
children: [
|
|
994
|
+
dotSlot("Auth", authTone),
|
|
995
|
+
dotSlot("DB", dbTone),
|
|
996
|
+
dotSlot("Sync", syncTone),
|
|
997
|
+
dotSlot("Schema", schemaTone)
|
|
998
|
+
]
|
|
999
|
+
}
|
|
1000
|
+
),
|
|
1001
|
+
/* @__PURE__ */ jsx("span", { style: { color: "#71717a", marginLeft: 4 }, children: open ? "\u25BE" : "\u25B4" })
|
|
1002
|
+
]
|
|
1003
|
+
}
|
|
1004
|
+
)
|
|
1005
|
+
] });
|
|
1006
|
+
}
|
|
1007
|
+
var INDEXED_DB_NAME, PANEL_PAD_X;
|
|
1008
|
+
var init_BasicDevToolbar = __esm({
|
|
1009
|
+
"src/dev/BasicDevToolbar.tsx"() {
|
|
1010
|
+
"use strict";
|
|
1011
|
+
"use client";
|
|
1012
|
+
init_context();
|
|
1013
|
+
init_package();
|
|
1014
|
+
init_network();
|
|
1015
|
+
INDEXED_DB_NAME = "basicdb";
|
|
1016
|
+
PANEL_PAD_X = 12;
|
|
1017
|
+
}
|
|
1018
|
+
});
|
|
1019
|
+
|
|
219
1020
|
// src/AuthContext.tsx
|
|
220
|
-
import {
|
|
1021
|
+
import { useCallback as useCallback2, useEffect, useRef, useState as useState2, Suspense, lazy } from "react";
|
|
221
1022
|
|
|
222
1023
|
// src/sync/index.ts
|
|
223
1024
|
init_config();
|
|
@@ -808,75 +1609,8 @@ async function resolveHandle(handle) {
|
|
|
808
1609
|
return resolved;
|
|
809
1610
|
}
|
|
810
1611
|
|
|
811
|
-
// src/utils/network.ts
|
|
812
|
-
init_config();
|
|
813
|
-
|
|
814
|
-
// package.json
|
|
815
|
-
var version = "0.8.0-beta.1";
|
|
816
|
-
|
|
817
|
-
// src/utils/network.ts
|
|
818
|
-
function isDevelopment(debug) {
|
|
819
|
-
return window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1" || window.location.hostname.includes("localhost") || window.location.hostname.includes("127.0.0.1") || window.location.hostname.includes(".local") || process.env.NODE_ENV === "development" || debug === true;
|
|
820
|
-
}
|
|
821
|
-
async function checkForNewVersion() {
|
|
822
|
-
try {
|
|
823
|
-
const isBeta = version.includes("beta");
|
|
824
|
-
const response = await fetch(`https://registry.npmjs.org/@basictech/react/${isBeta ? "beta" : "latest"}`);
|
|
825
|
-
if (!response.ok) {
|
|
826
|
-
throw new Error("Failed to fetch version from npm");
|
|
827
|
-
}
|
|
828
|
-
const data = await response.json();
|
|
829
|
-
const latestVersion = data.version;
|
|
830
|
-
if (latestVersion !== version) {
|
|
831
|
-
console.warn("[basic] New version available:", latestVersion, `
|
|
832
|
-
run "npm install @basictech/react@${latestVersion}" to update`);
|
|
833
|
-
}
|
|
834
|
-
if (isBeta) {
|
|
835
|
-
log("thank you for being on basictech/react beta :)");
|
|
836
|
-
}
|
|
837
|
-
return {
|
|
838
|
-
hasNewVersion: version !== latestVersion,
|
|
839
|
-
latestVersion,
|
|
840
|
-
currentVersion: version
|
|
841
|
-
};
|
|
842
|
-
} catch (error) {
|
|
843
|
-
log("Error checking for new version:", error);
|
|
844
|
-
return {
|
|
845
|
-
hasNewVersion: false,
|
|
846
|
-
latestVersion: null,
|
|
847
|
-
currentVersion: null
|
|
848
|
-
};
|
|
849
|
-
}
|
|
850
|
-
}
|
|
851
|
-
function cleanOAuthParamsFromUrl() {
|
|
852
|
-
if (window.location.search.includes("code") || window.location.search.includes("state")) {
|
|
853
|
-
const url = new URL(window.location.href);
|
|
854
|
-
url.searchParams.delete("code");
|
|
855
|
-
url.searchParams.delete("state");
|
|
856
|
-
window.history.pushState({}, document.title, url.pathname + url.search);
|
|
857
|
-
log("Cleaned OAuth parameters from URL");
|
|
858
|
-
}
|
|
859
|
-
}
|
|
860
|
-
function getSyncStatus(statusCode) {
|
|
861
|
-
switch (statusCode) {
|
|
862
|
-
case -1:
|
|
863
|
-
return "ERROR";
|
|
864
|
-
case 0:
|
|
865
|
-
return "OFFLINE";
|
|
866
|
-
case 1:
|
|
867
|
-
return "CONNECTING";
|
|
868
|
-
case 2:
|
|
869
|
-
return "ONLINE";
|
|
870
|
-
case 3:
|
|
871
|
-
return "SYNCING";
|
|
872
|
-
case 4:
|
|
873
|
-
return "ERROR_WILL_RETRY";
|
|
874
|
-
default:
|
|
875
|
-
return "UNKNOWN";
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
|
|
879
1612
|
// src/core/auth/AuthManager.ts
|
|
1613
|
+
init_network();
|
|
880
1614
|
init_config();
|
|
881
1615
|
function generateCodeVerifier() {
|
|
882
1616
|
const array = new Uint8Array(32);
|
|
@@ -1577,6 +2311,7 @@ var AuthManager = class {
|
|
|
1577
2311
|
|
|
1578
2312
|
// src/AuthContext.tsx
|
|
1579
2313
|
init_config();
|
|
2314
|
+
init_package();
|
|
1580
2315
|
|
|
1581
2316
|
// src/updater/versionUpdater.ts
|
|
1582
2317
|
init_config();
|
|
@@ -1701,6 +2436,9 @@ function getMigrations() {
|
|
|
1701
2436
|
];
|
|
1702
2437
|
}
|
|
1703
2438
|
|
|
2439
|
+
// src/AuthContext.tsx
|
|
2440
|
+
init_network();
|
|
2441
|
+
|
|
1704
2442
|
// src/utils/schema.ts
|
|
1705
2443
|
init_config();
|
|
1706
2444
|
import { validateSchema, compareSchemas } from "@basictech/schema";
|
|
@@ -1800,57 +2538,18 @@ async function validateAndCheckSchema(schema) {
|
|
|
1800
2538
|
}
|
|
1801
2539
|
|
|
1802
2540
|
// src/AuthContext.tsx
|
|
1803
|
-
|
|
2541
|
+
init_context();
|
|
2542
|
+
init_context();
|
|
2543
|
+
import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
2544
|
+
var BasicDevToolbar2 = lazy(
|
|
2545
|
+
() => Promise.resolve().then(() => (init_BasicDevToolbar(), BasicDevToolbar_exports)).then((m) => ({ default: m.BasicDevToolbar }))
|
|
2546
|
+
);
|
|
1804
2547
|
var DEFAULT_AUTH_CONFIG = {
|
|
1805
2548
|
scopes: "profile,email,app:admin",
|
|
1806
2549
|
pds_url: "https://pds.basic.id",
|
|
1807
2550
|
admin_url: "https://api.basic.tech",
|
|
1808
2551
|
ws_url: "wss://pds.basic.id/ws"
|
|
1809
2552
|
};
|
|
1810
|
-
var DBStatus = /* @__PURE__ */ ((DBStatus2) => {
|
|
1811
|
-
DBStatus2["LOADING"] = "LOADING";
|
|
1812
|
-
DBStatus2["OFFLINE"] = "OFFLINE";
|
|
1813
|
-
DBStatus2["CONNECTING"] = "CONNECTING";
|
|
1814
|
-
DBStatus2["ONLINE"] = "ONLINE";
|
|
1815
|
-
DBStatus2["SYNCING"] = "SYNCING";
|
|
1816
|
-
DBStatus2["ERROR"] = "ERROR";
|
|
1817
|
-
DBStatus2["ERROR_WILL_RETRY"] = "ERROR_WILL_RETRY";
|
|
1818
|
-
DBStatus2["ERROR_TOKEN_EXPIRED"] = "ERROR_TOKEN_EXPIRED";
|
|
1819
|
-
return DBStatus2;
|
|
1820
|
-
})(DBStatus || {});
|
|
1821
|
-
var noDb = {
|
|
1822
|
-
collection: () => {
|
|
1823
|
-
throw new Error("no basicdb found - initialization failed. double check your schema.");
|
|
1824
|
-
}
|
|
1825
|
-
};
|
|
1826
|
-
var BasicContext = createContext({
|
|
1827
|
-
// Auth state
|
|
1828
|
-
isReady: false,
|
|
1829
|
-
isSignedIn: false,
|
|
1830
|
-
user: null,
|
|
1831
|
-
did: null,
|
|
1832
|
-
scope: null,
|
|
1833
|
-
hasScope: () => false,
|
|
1834
|
-
missingScopes: () => [],
|
|
1835
|
-
// Auth actions
|
|
1836
|
-
signIn: () => Promise.resolve(),
|
|
1837
|
-
signInWithHandle: () => Promise.resolve(),
|
|
1838
|
-
signOut: () => Promise.resolve(),
|
|
1839
|
-
signInWithCode: () => Promise.resolve({ success: false }),
|
|
1840
|
-
// Token management
|
|
1841
|
-
getToken: (_options) => Promise.reject(new Error("no token")),
|
|
1842
|
-
getSignInUrl: () => Promise.resolve(""),
|
|
1843
|
-
// DB access
|
|
1844
|
-
db: noDb,
|
|
1845
|
-
dbStatus: "LOADING" /* LOADING */,
|
|
1846
|
-
dbMode: "sync",
|
|
1847
|
-
// Legacy aliases
|
|
1848
|
-
isAuthReady: false,
|
|
1849
|
-
signin: () => Promise.resolve(),
|
|
1850
|
-
signout: () => Promise.resolve(),
|
|
1851
|
-
signinWithCode: () => Promise.resolve({ success: false }),
|
|
1852
|
-
getSignInLink: () => Promise.resolve("")
|
|
1853
|
-
});
|
|
1854
2553
|
function snapshotAuth(mgr) {
|
|
1855
2554
|
return {
|
|
1856
2555
|
isSignedIn: mgr.isSignedIn,
|
|
@@ -1868,7 +2567,8 @@ function BasicProvider({
|
|
|
1868
2567
|
debug = false,
|
|
1869
2568
|
storage,
|
|
1870
2569
|
auth,
|
|
1871
|
-
dbMode = "sync"
|
|
2570
|
+
dbMode = "sync",
|
|
2571
|
+
devToolbar = false
|
|
1872
2572
|
}) {
|
|
1873
2573
|
const project_id = schema?.project_id || project_id_prop;
|
|
1874
2574
|
if (auth?.server_url && !auth?.pds_url) {
|
|
@@ -1883,7 +2583,9 @@ function BasicProvider({
|
|
|
1883
2583
|
const scopesString = Array.isArray(authConfig.scopes) ? authConfig.scopes.join(" ") : authConfig.scopes;
|
|
1884
2584
|
const storageRef = useRef(storage || new LocalStorageAdapter());
|
|
1885
2585
|
const storageAdapter = storageRef.current;
|
|
1886
|
-
const
|
|
2586
|
+
const schemaRef = useRef(schema);
|
|
2587
|
+
schemaRef.current = schema;
|
|
2588
|
+
const [authState, setAuthState] = useState2({
|
|
1887
2589
|
isSignedIn: false,
|
|
1888
2590
|
hasToken: false,
|
|
1889
2591
|
isAuthReady: false,
|
|
@@ -1907,11 +2609,47 @@ function BasicProvider({
|
|
|
1907
2609
|
}
|
|
1908
2610
|
const syncRef = useRef(null);
|
|
1909
2611
|
const remoteDbRef = useRef(null);
|
|
1910
|
-
const [shouldConnect, setShouldConnect] =
|
|
1911
|
-
const [dbStatus, setDbStatus] =
|
|
1912
|
-
const [isReady, setIsReady] =
|
|
1913
|
-
const [error, setError] =
|
|
2612
|
+
const [shouldConnect, setShouldConnect] = useState2(false);
|
|
2613
|
+
const [dbStatus, setDbStatus] = useState2("OFFLINE" /* OFFLINE */);
|
|
2614
|
+
const [isReady, setIsReady] = useState2(false);
|
|
2615
|
+
const [error, setError] = useState2(null);
|
|
2616
|
+
const [schemaDevInfo, setSchemaDevInfo] = useState2(null);
|
|
1914
2617
|
const isDevMode = () => isDevelopment(debug);
|
|
2618
|
+
const refreshSchemaStatus = useCallback2(async () => {
|
|
2619
|
+
const s = schemaRef.current;
|
|
2620
|
+
if (!s) {
|
|
2621
|
+
setSchemaDevInfo(
|
|
2622
|
+
project_id ? {
|
|
2623
|
+
projectId: project_id,
|
|
2624
|
+
localVersion: void 0,
|
|
2625
|
+
status: "no_schema",
|
|
2626
|
+
valid: false,
|
|
2627
|
+
lastCheckedAt: Date.now()
|
|
2628
|
+
} : null
|
|
2629
|
+
);
|
|
2630
|
+
return;
|
|
2631
|
+
}
|
|
2632
|
+
const result = await validateAndCheckSchema(s);
|
|
2633
|
+
if (!result.isValid) {
|
|
2634
|
+
const errText = result.errors?.map((e) => e.message || "").join("; ") || "invalid";
|
|
2635
|
+
setSchemaDevInfo({
|
|
2636
|
+
projectId: s.project_id ?? null,
|
|
2637
|
+
localVersion: s.version,
|
|
2638
|
+
status: "invalid",
|
|
2639
|
+
valid: false,
|
|
2640
|
+
lastCheckedAt: Date.now(),
|
|
2641
|
+
error: errText
|
|
2642
|
+
});
|
|
2643
|
+
return;
|
|
2644
|
+
}
|
|
2645
|
+
setSchemaDevInfo({
|
|
2646
|
+
projectId: s.project_id ?? null,
|
|
2647
|
+
localVersion: s.version,
|
|
2648
|
+
status: result.schemaStatus.status ?? "unknown",
|
|
2649
|
+
valid: result.schemaStatus.valid,
|
|
2650
|
+
lastCheckedAt: Date.now()
|
|
2651
|
+
});
|
|
2652
|
+
}, [project_id]);
|
|
1915
2653
|
useEffect(() => {
|
|
1916
2654
|
const runVersionUpdater = async () => {
|
|
1917
2655
|
try {
|
|
@@ -1985,11 +2723,19 @@ function BasicProvider({
|
|
|
1985
2723
|
if (!result.isValid) {
|
|
1986
2724
|
let errorMessage = "";
|
|
1987
2725
|
if (result.errors) {
|
|
1988
|
-
result.errors.forEach((
|
|
1989
|
-
errorMessage += `${index + 1}: ${
|
|
2726
|
+
result.errors.forEach((err, index) => {
|
|
2727
|
+
errorMessage += `${index + 1}: ${err.message} - at ${err.instancePath}
|
|
1990
2728
|
`;
|
|
1991
2729
|
});
|
|
1992
2730
|
}
|
|
2731
|
+
setSchemaDevInfo({
|
|
2732
|
+
projectId: schema?.project_id ?? null,
|
|
2733
|
+
localVersion: schema?.version,
|
|
2734
|
+
status: "invalid",
|
|
2735
|
+
valid: false,
|
|
2736
|
+
lastCheckedAt: Date.now(),
|
|
2737
|
+
error: errorMessage.trim() || void 0
|
|
2738
|
+
});
|
|
1993
2739
|
setError({
|
|
1994
2740
|
code: "schema_invalid",
|
|
1995
2741
|
title: "Basic Schema is invalid!",
|
|
@@ -1998,6 +2744,13 @@ function BasicProvider({
|
|
|
1998
2744
|
setIsReady(true);
|
|
1999
2745
|
return null;
|
|
2000
2746
|
}
|
|
2747
|
+
setSchemaDevInfo({
|
|
2748
|
+
projectId: schema?.project_id ?? null,
|
|
2749
|
+
localVersion: schema?.version,
|
|
2750
|
+
status: result.schemaStatus.status ?? "unknown",
|
|
2751
|
+
valid: result.schemaStatus.valid,
|
|
2752
|
+
lastCheckedAt: Date.now()
|
|
2753
|
+
});
|
|
2001
2754
|
if (dbMode === "remote") {
|
|
2002
2755
|
initRemoteDb();
|
|
2003
2756
|
} else {
|
|
@@ -2017,6 +2770,15 @@ function BasicProvider({
|
|
|
2017
2770
|
if (schema) {
|
|
2018
2771
|
checkSchema();
|
|
2019
2772
|
} else {
|
|
2773
|
+
setSchemaDevInfo(
|
|
2774
|
+
project_id ? {
|
|
2775
|
+
projectId: project_id,
|
|
2776
|
+
localVersion: void 0,
|
|
2777
|
+
status: "no_schema",
|
|
2778
|
+
valid: false,
|
|
2779
|
+
lastCheckedAt: Date.now()
|
|
2780
|
+
} : null
|
|
2781
|
+
);
|
|
2020
2782
|
if (dbMode === "remote" && project_id) {
|
|
2021
2783
|
initRemoteDb();
|
|
2022
2784
|
} else {
|
|
@@ -2083,68 +2845,71 @@ function BasicProvider({
|
|
|
2083
2845
|
return syncRef.current || noDb;
|
|
2084
2846
|
};
|
|
2085
2847
|
const contextValue = {
|
|
2086
|
-
// Auth state
|
|
2087
2848
|
isReady: authState.isAuthReady,
|
|
2088
2849
|
isSignedIn: authState.isSignedIn,
|
|
2089
2850
|
user: authState.user,
|
|
2090
2851
|
did: authState.did,
|
|
2091
2852
|
scope: authState.tokenScope,
|
|
2092
|
-
hasScope: (
|
|
2853
|
+
hasScope: (s) => authRef.current.hasScope(s),
|
|
2093
2854
|
missingScopes: () => authRef.current.missingScopes(),
|
|
2094
|
-
// Auth actions
|
|
2095
2855
|
signIn: handleSignIn,
|
|
2096
2856
|
signInWithHandle: handleSignInWithHandle,
|
|
2097
2857
|
signOut: handleSignOut,
|
|
2098
2858
|
signInWithCode: (code, state) => authRef.current.signInWithCode(code, state),
|
|
2099
|
-
// Token management
|
|
2100
2859
|
getToken: (opts) => authRef.current.getToken(opts),
|
|
2101
2860
|
getSignInUrl: (redirectUri) => authRef.current.getSignInUrl(redirectUri),
|
|
2102
|
-
// DB access
|
|
2103
2861
|
db: getCurrentDb(),
|
|
2104
2862
|
dbStatus,
|
|
2105
2863
|
dbMode,
|
|
2106
|
-
|
|
2864
|
+
devInfo: schemaDevInfo,
|
|
2865
|
+
refreshSchemaStatus,
|
|
2107
2866
|
isAuthReady: authState.isAuthReady,
|
|
2108
2867
|
signin: handleSignIn,
|
|
2109
2868
|
signout: handleSignOut,
|
|
2110
2869
|
signinWithCode: (code, state) => authRef.current.signInWithCode(code, state),
|
|
2111
2870
|
getSignInLink: (redirectUri) => authRef.current.getSignInUrl(redirectUri)
|
|
2112
2871
|
};
|
|
2113
|
-
return /* @__PURE__ */
|
|
2114
|
-
error && isDevMode() && /* @__PURE__ */
|
|
2872
|
+
return /* @__PURE__ */ jsxs2(BasicContext.Provider, { value: contextValue, children: [
|
|
2873
|
+
error && isDevMode() && /* @__PURE__ */ jsx2(ErrorDisplay, { error }),
|
|
2874
|
+
devToolbar && isDevMode() && /* @__PURE__ */ jsx2(Suspense, { fallback: null, children: /* @__PURE__ */ jsx2(BasicDevToolbar2, { debug }) }),
|
|
2115
2875
|
isReady && children
|
|
2116
2876
|
] });
|
|
2117
2877
|
}
|
|
2118
2878
|
function ErrorDisplay({ error }) {
|
|
2119
|
-
return /* @__PURE__ */
|
|
2120
|
-
|
|
2121
|
-
|
|
2122
|
-
|
|
2123
|
-
|
|
2124
|
-
|
|
2125
|
-
|
|
2126
|
-
|
|
2127
|
-
|
|
2128
|
-
|
|
2129
|
-
|
|
2130
|
-
|
|
2131
|
-
|
|
2132
|
-
|
|
2133
|
-
|
|
2134
|
-
|
|
2135
|
-
|
|
2136
|
-
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
|
|
2140
|
-
}
|
|
2141
|
-
|
|
2142
|
-
|
|
2879
|
+
return /* @__PURE__ */ jsxs2(
|
|
2880
|
+
"div",
|
|
2881
|
+
{
|
|
2882
|
+
style: {
|
|
2883
|
+
position: "absolute",
|
|
2884
|
+
top: 20,
|
|
2885
|
+
left: 20,
|
|
2886
|
+
color: "black",
|
|
2887
|
+
backgroundColor: "#f8d7da",
|
|
2888
|
+
border: "1px solid #f5c6cb",
|
|
2889
|
+
borderRadius: "4px",
|
|
2890
|
+
padding: "20px",
|
|
2891
|
+
maxWidth: "400px",
|
|
2892
|
+
margin: "20px auto",
|
|
2893
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
|
|
2894
|
+
fontFamily: "monospace"
|
|
2895
|
+
},
|
|
2896
|
+
children: [
|
|
2897
|
+
/* @__PURE__ */ jsxs2("h3", { style: { fontSize: "0.8rem", opacity: 0.8 }, children: [
|
|
2898
|
+
"code: ",
|
|
2899
|
+
error.code
|
|
2900
|
+
] }),
|
|
2901
|
+
/* @__PURE__ */ jsx2("h1", { style: { fontSize: "1.2rem", lineHeight: 1.5 }, children: error.title }),
|
|
2902
|
+
/* @__PURE__ */ jsx2("p", { children: error.message })
|
|
2903
|
+
]
|
|
2904
|
+
}
|
|
2905
|
+
);
|
|
2143
2906
|
}
|
|
2144
2907
|
|
|
2145
2908
|
// src/index.ts
|
|
2909
|
+
init_BasicDevToolbar();
|
|
2146
2910
|
import { useLiveQuery as useQuery } from "dexie-react-hooks";
|
|
2147
2911
|
export {
|
|
2912
|
+
BasicDevToolbar,
|
|
2148
2913
|
BasicProvider,
|
|
2149
2914
|
DBStatus,
|
|
2150
2915
|
NotAuthenticatedError,
|