@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.js
CHANGED
|
@@ -238,9 +238,812 @@ var init_syncProtocol = __esm({
|
|
|
238
238
|
}
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
+
// package.json
|
|
242
|
+
var version;
|
|
243
|
+
var init_package = __esm({
|
|
244
|
+
"package.json"() {
|
|
245
|
+
version = "0.8.0-beta.2";
|
|
246
|
+
}
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
// src/utils/network.ts
|
|
250
|
+
function isDevelopment(debug) {
|
|
251
|
+
if (debug === true) return true;
|
|
252
|
+
if (typeof process !== "undefined" && process.env.NODE_ENV === "development") return true;
|
|
253
|
+
if (typeof window === "undefined" || !window.location) return false;
|
|
254
|
+
const host = window.location.hostname;
|
|
255
|
+
return host === "localhost" || host === "127.0.0.1" || host.includes("localhost") || host.includes("127.0.0.1") || host.includes(".local");
|
|
256
|
+
}
|
|
257
|
+
function normalizeVersion(v) {
|
|
258
|
+
if (v == null) return null;
|
|
259
|
+
const t = String(v).trim();
|
|
260
|
+
return t.length ? t : null;
|
|
261
|
+
}
|
|
262
|
+
function versionsMatch(a, b) {
|
|
263
|
+
const na = a.trim();
|
|
264
|
+
const nb = b.trim();
|
|
265
|
+
if (na === nb) return true;
|
|
266
|
+
const va = import_semver.default.valid(na);
|
|
267
|
+
const vb = import_semver.default.valid(nb);
|
|
268
|
+
if (va && vb) return import_semver.default.eq(va, vb);
|
|
269
|
+
return false;
|
|
270
|
+
}
|
|
271
|
+
function usesBetaDistTag(version2) {
|
|
272
|
+
const pre = import_semver.default.prerelease(version2);
|
|
273
|
+
const id = pre?.[0];
|
|
274
|
+
return typeof id === "string" && id.toLowerCase() === "beta";
|
|
275
|
+
}
|
|
276
|
+
async function checkForNewVersion() {
|
|
277
|
+
try {
|
|
278
|
+
const currentVersion = normalizeVersion(version);
|
|
279
|
+
if (!currentVersion) {
|
|
280
|
+
return { hasNewVersion: false, latestVersion: null, currentVersion: null };
|
|
281
|
+
}
|
|
282
|
+
const response = await fetch("https://registry.npmjs.org/@basictech/react", {
|
|
283
|
+
headers: { Accept: "application/vnd.npm.install-v1+json" }
|
|
284
|
+
});
|
|
285
|
+
if (!response.ok) {
|
|
286
|
+
throw new Error("Failed to fetch version from npm");
|
|
287
|
+
}
|
|
288
|
+
const data = await response.json();
|
|
289
|
+
const distTags = data["dist-tags"] ?? {};
|
|
290
|
+
const rawRegistry = usesBetaDistTag(currentVersion) ? distTags.beta ?? distTags.latest : distTags.latest;
|
|
291
|
+
const latestVersion = normalizeVersion(rawRegistry ?? null);
|
|
292
|
+
if (!latestVersion) {
|
|
293
|
+
throw new Error("Missing dist-tags from npm registry");
|
|
294
|
+
}
|
|
295
|
+
const same = versionsMatch(currentVersion, latestVersion);
|
|
296
|
+
if (!same && isDevelopment()) {
|
|
297
|
+
log("[basic] version check mismatch:", {
|
|
298
|
+
currentVersion,
|
|
299
|
+
registryVersion: latestVersion,
|
|
300
|
+
channel: usesBetaDistTag(currentVersion) ? "beta" : "latest"
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
if (!same) {
|
|
304
|
+
console.warn("[basic] New version available:", latestVersion, `
|
|
305
|
+
run "npm install @basictech/react@${latestVersion}" to update`);
|
|
306
|
+
}
|
|
307
|
+
if (usesBetaDistTag(currentVersion)) {
|
|
308
|
+
log("thank you for being on basictech/react beta :)");
|
|
309
|
+
}
|
|
310
|
+
return {
|
|
311
|
+
hasNewVersion: !same,
|
|
312
|
+
latestVersion,
|
|
313
|
+
currentVersion
|
|
314
|
+
};
|
|
315
|
+
} catch (error) {
|
|
316
|
+
log("Error checking for new version:", error);
|
|
317
|
+
return {
|
|
318
|
+
hasNewVersion: false,
|
|
319
|
+
latestVersion: null,
|
|
320
|
+
currentVersion: null
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
function cleanOAuthParamsFromUrl() {
|
|
325
|
+
if (window.location.search.includes("code") || window.location.search.includes("state")) {
|
|
326
|
+
const url = new URL(window.location.href);
|
|
327
|
+
url.searchParams.delete("code");
|
|
328
|
+
url.searchParams.delete("state");
|
|
329
|
+
window.history.pushState({}, document.title, url.pathname + url.search);
|
|
330
|
+
log("Cleaned OAuth parameters from URL");
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
function getSyncStatus(statusCode) {
|
|
334
|
+
switch (statusCode) {
|
|
335
|
+
case -1:
|
|
336
|
+
return "ERROR";
|
|
337
|
+
case 0:
|
|
338
|
+
return "OFFLINE";
|
|
339
|
+
case 1:
|
|
340
|
+
return "CONNECTING";
|
|
341
|
+
case 2:
|
|
342
|
+
return "ONLINE";
|
|
343
|
+
case 3:
|
|
344
|
+
return "SYNCING";
|
|
345
|
+
case 4:
|
|
346
|
+
return "ERROR_WILL_RETRY";
|
|
347
|
+
default:
|
|
348
|
+
return "UNKNOWN";
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
var import_semver;
|
|
352
|
+
var init_network = __esm({
|
|
353
|
+
"src/utils/network.ts"() {
|
|
354
|
+
"use strict";
|
|
355
|
+
import_semver = __toESM(require("semver"));
|
|
356
|
+
init_config();
|
|
357
|
+
init_package();
|
|
358
|
+
}
|
|
359
|
+
});
|
|
360
|
+
|
|
361
|
+
// src/context.tsx
|
|
362
|
+
function useBasic() {
|
|
363
|
+
return (0, import_react.useContext)(BasicContext);
|
|
364
|
+
}
|
|
365
|
+
var import_react, DBStatus, noDb, BasicContext;
|
|
366
|
+
var init_context = __esm({
|
|
367
|
+
"src/context.tsx"() {
|
|
368
|
+
"use strict";
|
|
369
|
+
import_react = require("react");
|
|
370
|
+
DBStatus = /* @__PURE__ */ ((DBStatus2) => {
|
|
371
|
+
DBStatus2["LOADING"] = "LOADING";
|
|
372
|
+
DBStatus2["OFFLINE"] = "OFFLINE";
|
|
373
|
+
DBStatus2["CONNECTING"] = "CONNECTING";
|
|
374
|
+
DBStatus2["ONLINE"] = "ONLINE";
|
|
375
|
+
DBStatus2["SYNCING"] = "SYNCING";
|
|
376
|
+
DBStatus2["ERROR"] = "ERROR";
|
|
377
|
+
DBStatus2["ERROR_WILL_RETRY"] = "ERROR_WILL_RETRY";
|
|
378
|
+
DBStatus2["ERROR_TOKEN_EXPIRED"] = "ERROR_TOKEN_EXPIRED";
|
|
379
|
+
return DBStatus2;
|
|
380
|
+
})(DBStatus || {});
|
|
381
|
+
noDb = {
|
|
382
|
+
collection: () => {
|
|
383
|
+
throw new Error("no basicdb found - initialization failed. double check your schema.");
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
BasicContext = (0, import_react.createContext)({
|
|
387
|
+
isReady: false,
|
|
388
|
+
isSignedIn: false,
|
|
389
|
+
user: null,
|
|
390
|
+
did: null,
|
|
391
|
+
scope: null,
|
|
392
|
+
hasScope: () => false,
|
|
393
|
+
missingScopes: () => [],
|
|
394
|
+
signIn: () => Promise.resolve(),
|
|
395
|
+
signInWithHandle: () => Promise.resolve(),
|
|
396
|
+
signOut: () => Promise.resolve(),
|
|
397
|
+
signInWithCode: () => Promise.resolve({ success: false }),
|
|
398
|
+
getToken: (_options) => Promise.reject(new Error("no token")),
|
|
399
|
+
getSignInUrl: () => Promise.resolve(""),
|
|
400
|
+
db: noDb,
|
|
401
|
+
dbStatus: "LOADING" /* LOADING */,
|
|
402
|
+
dbMode: "sync",
|
|
403
|
+
devInfo: null,
|
|
404
|
+
refreshSchemaStatus: async () => {
|
|
405
|
+
},
|
|
406
|
+
isAuthReady: false,
|
|
407
|
+
signin: () => Promise.resolve(),
|
|
408
|
+
signout: () => Promise.resolve(),
|
|
409
|
+
signinWithCode: () => Promise.resolve({ success: false }),
|
|
410
|
+
getSignInLink: () => Promise.resolve("")
|
|
411
|
+
});
|
|
412
|
+
}
|
|
413
|
+
});
|
|
414
|
+
|
|
415
|
+
// src/dev/BasicDevToolbar.tsx
|
|
416
|
+
var BasicDevToolbar_exports = {};
|
|
417
|
+
__export(BasicDevToolbar_exports, {
|
|
418
|
+
BasicDevToolbar: () => BasicDevToolbar
|
|
419
|
+
});
|
|
420
|
+
function toneForAuth(isReady, isSignedIn) {
|
|
421
|
+
if (!isReady) return "muted";
|
|
422
|
+
if (isSignedIn) return "ok";
|
|
423
|
+
return "warn";
|
|
424
|
+
}
|
|
425
|
+
function toneForDb(dbMode, dbStatus) {
|
|
426
|
+
if (dbMode === "remote") return dbStatus === "ONLINE" /* ONLINE */ ? "ok" : "warn";
|
|
427
|
+
if (dbStatus === "ONLINE" /* ONLINE */ || dbStatus === "SYNCING" /* SYNCING */) return "ok";
|
|
428
|
+
if (dbStatus === "CONNECTING" /* CONNECTING */ || dbStatus === "LOADING" /* LOADING */) return "warn";
|
|
429
|
+
if (dbStatus === "OFFLINE" /* OFFLINE */) return "muted";
|
|
430
|
+
return "bad";
|
|
431
|
+
}
|
|
432
|
+
function toneForSchema(info) {
|
|
433
|
+
if (!info) return "muted";
|
|
434
|
+
if (info.valid && info.status === "current") return "ok";
|
|
435
|
+
if (info.status === "unpublished") return "warn";
|
|
436
|
+
if (info.status === "no_schema") return "muted";
|
|
437
|
+
return "bad";
|
|
438
|
+
}
|
|
439
|
+
function dbStatusLabel(status) {
|
|
440
|
+
switch (status) {
|
|
441
|
+
case "LOADING" /* LOADING */:
|
|
442
|
+
return "Initializing";
|
|
443
|
+
case "OFFLINE" /* OFFLINE */:
|
|
444
|
+
return "Offline";
|
|
445
|
+
case "CONNECTING" /* CONNECTING */:
|
|
446
|
+
return "Connecting";
|
|
447
|
+
case "ONLINE" /* ONLINE */:
|
|
448
|
+
return "Connected";
|
|
449
|
+
case "SYNCING" /* SYNCING */:
|
|
450
|
+
return "Syncing";
|
|
451
|
+
case "ERROR" /* ERROR */:
|
|
452
|
+
return "Error";
|
|
453
|
+
case "ERROR_WILL_RETRY" /* ERROR_WILL_RETRY */:
|
|
454
|
+
return "Retrying";
|
|
455
|
+
case "ERROR_TOKEN_EXPIRED" /* ERROR_TOKEN_EXPIRED */:
|
|
456
|
+
return "Token refresh";
|
|
457
|
+
default:
|
|
458
|
+
return String(status);
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
function chipColor(tone) {
|
|
462
|
+
switch (tone) {
|
|
463
|
+
case "ok":
|
|
464
|
+
return "#22c55e";
|
|
465
|
+
case "warn":
|
|
466
|
+
return "#eab308";
|
|
467
|
+
case "bad":
|
|
468
|
+
return "#ef4444";
|
|
469
|
+
default:
|
|
470
|
+
return "#71717a";
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
function displayDid(did) {
|
|
474
|
+
return did || "\u2014";
|
|
475
|
+
}
|
|
476
|
+
function displayUserLine(user) {
|
|
477
|
+
const parts = [];
|
|
478
|
+
if (user.sub) parts.push(`sub: ${user.sub}`);
|
|
479
|
+
if (user.email) parts.push(`email: ${user.email}`);
|
|
480
|
+
if (user.name) parts.push(`name: ${user.name}`);
|
|
481
|
+
return parts.length ? parts.join(" \xB7 ") : "\u2014";
|
|
482
|
+
}
|
|
483
|
+
function ClipboardIcon() {
|
|
484
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
485
|
+
"svg",
|
|
486
|
+
{
|
|
487
|
+
width: "14",
|
|
488
|
+
height: "14",
|
|
489
|
+
viewBox: "0 0 24 24",
|
|
490
|
+
fill: "none",
|
|
491
|
+
stroke: "currentColor",
|
|
492
|
+
strokeWidth: "2",
|
|
493
|
+
strokeLinecap: "round",
|
|
494
|
+
strokeLinejoin: "round",
|
|
495
|
+
"aria-hidden": true,
|
|
496
|
+
children: [
|
|
497
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
|
|
498
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
|
|
499
|
+
]
|
|
500
|
+
}
|
|
501
|
+
);
|
|
502
|
+
}
|
|
503
|
+
function SectionHeader({ children }) {
|
|
504
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
505
|
+
"div",
|
|
506
|
+
{
|
|
507
|
+
style: {
|
|
508
|
+
fontSize: 10,
|
|
509
|
+
fontWeight: 700,
|
|
510
|
+
color: "#e4e4e7",
|
|
511
|
+
letterSpacing: "0.07em",
|
|
512
|
+
textTransform: "uppercase",
|
|
513
|
+
marginBottom: 8
|
|
514
|
+
},
|
|
515
|
+
children
|
|
516
|
+
}
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
function SectionRule() {
|
|
520
|
+
const bleed = PANEL_PAD_X;
|
|
521
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
522
|
+
"div",
|
|
523
|
+
{
|
|
524
|
+
role: "separator",
|
|
525
|
+
style: {
|
|
526
|
+
height: 1,
|
|
527
|
+
background: "rgba(255, 255, 255, 0.055)",
|
|
528
|
+
marginLeft: -bleed,
|
|
529
|
+
marginRight: -bleed,
|
|
530
|
+
marginTop: 14,
|
|
531
|
+
marginBottom: 10,
|
|
532
|
+
width: `calc(100% + ${bleed * 2}px)`
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
);
|
|
536
|
+
}
|
|
537
|
+
function CopyableRow({
|
|
538
|
+
rowKey,
|
|
539
|
+
label,
|
|
540
|
+
copyText,
|
|
541
|
+
copiedKey,
|
|
542
|
+
onCopied,
|
|
543
|
+
children
|
|
544
|
+
}) {
|
|
545
|
+
const [hover, setHover] = (0, import_react2.useState)(false);
|
|
546
|
+
const canCopy = copyText.length > 0;
|
|
547
|
+
const handleClick = (0, import_react2.useCallback)(
|
|
548
|
+
(e) => {
|
|
549
|
+
e.stopPropagation();
|
|
550
|
+
if (!canCopy) return;
|
|
551
|
+
void navigator.clipboard.writeText(copyText).then(() => onCopied(rowKey));
|
|
552
|
+
},
|
|
553
|
+
[canCopy, copyText, onCopied, rowKey]
|
|
554
|
+
);
|
|
555
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
556
|
+
"div",
|
|
557
|
+
{
|
|
558
|
+
role: canCopy ? "button" : void 0,
|
|
559
|
+
tabIndex: canCopy ? 0 : void 0,
|
|
560
|
+
onClick: canCopy ? handleClick : void 0,
|
|
561
|
+
onKeyDown: canCopy ? (e) => {
|
|
562
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
563
|
+
e.preventDefault();
|
|
564
|
+
handleClick(e);
|
|
565
|
+
}
|
|
566
|
+
} : void 0,
|
|
567
|
+
onMouseEnter: () => setHover(true),
|
|
568
|
+
onMouseLeave: () => setHover(false),
|
|
569
|
+
style: {
|
|
570
|
+
display: "flex",
|
|
571
|
+
gap: 8,
|
|
572
|
+
marginBottom: 6,
|
|
573
|
+
alignItems: "flex-start",
|
|
574
|
+
borderRadius: 6,
|
|
575
|
+
padding: "4px 6px",
|
|
576
|
+
marginLeft: -6,
|
|
577
|
+
marginRight: -6,
|
|
578
|
+
cursor: canCopy ? "pointer" : "default",
|
|
579
|
+
background: hover && canCopy ? "rgba(255,255,255,0.06)" : "transparent",
|
|
580
|
+
transition: "background 0.12s ease"
|
|
581
|
+
},
|
|
582
|
+
children: [
|
|
583
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#a1a1aa", minWidth: 88, flexShrink: 0, paddingTop: 2 }, children: label }),
|
|
584
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
585
|
+
"span",
|
|
586
|
+
{
|
|
587
|
+
style: {
|
|
588
|
+
flex: 1,
|
|
589
|
+
minWidth: 0,
|
|
590
|
+
wordBreak: "break-all",
|
|
591
|
+
paddingTop: 2,
|
|
592
|
+
lineHeight: 1.35
|
|
593
|
+
},
|
|
594
|
+
children
|
|
595
|
+
}
|
|
596
|
+
),
|
|
597
|
+
canCopy && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
598
|
+
"span",
|
|
599
|
+
{
|
|
600
|
+
style: {
|
|
601
|
+
flexShrink: 0,
|
|
602
|
+
color: copiedKey === rowKey ? "#22c55e" : "#71717a",
|
|
603
|
+
opacity: hover || copiedKey === rowKey ? 1 : 0,
|
|
604
|
+
transition: "opacity 0.12s ease, color 0.12s ease",
|
|
605
|
+
paddingTop: 2,
|
|
606
|
+
display: "flex",
|
|
607
|
+
alignItems: "flex-start"
|
|
608
|
+
},
|
|
609
|
+
title: "Copy value",
|
|
610
|
+
children: copiedKey === rowKey ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontSize: 10 }, children: "\u2713" }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClipboardIcon, {})
|
|
611
|
+
}
|
|
612
|
+
)
|
|
613
|
+
]
|
|
614
|
+
}
|
|
615
|
+
);
|
|
616
|
+
}
|
|
617
|
+
function BasicDevToolbar({ enabled = true, debug }) {
|
|
618
|
+
const {
|
|
619
|
+
isReady,
|
|
620
|
+
isSignedIn,
|
|
621
|
+
user,
|
|
622
|
+
did,
|
|
623
|
+
scope,
|
|
624
|
+
missingScopes,
|
|
625
|
+
dbMode,
|
|
626
|
+
dbStatus,
|
|
627
|
+
devInfo,
|
|
628
|
+
refreshSchemaStatus
|
|
629
|
+
} = useBasic();
|
|
630
|
+
const [open, setOpen] = (0, import_react2.useState)(false);
|
|
631
|
+
const [refreshing, setRefreshing] = (0, import_react2.useState)(false);
|
|
632
|
+
const [copied, setCopied] = (0, import_react2.useState)(false);
|
|
633
|
+
const [rowCopied, setRowCopied] = (0, import_react2.useState)(null);
|
|
634
|
+
const show = enabled && typeof window !== "undefined" && isDevelopment(debug);
|
|
635
|
+
const authTone = toneForAuth(isReady, isSignedIn);
|
|
636
|
+
const dbTone = toneForDb(dbMode, dbStatus);
|
|
637
|
+
const schemaTone = toneForSchema(devInfo);
|
|
638
|
+
const syncTone = dbMode === "remote" ? "muted" : dbTone === "ok" || dbStatus === "SYNCING" /* SYNCING */ ? "ok" : dbTone === "warn" ? "warn" : dbTone === "bad" ? "bad" : "muted";
|
|
639
|
+
const handleRefreshSchema = (0, import_react2.useCallback)(async () => {
|
|
640
|
+
setRefreshing(true);
|
|
641
|
+
try {
|
|
642
|
+
await refreshSchemaStatus();
|
|
643
|
+
} finally {
|
|
644
|
+
setRefreshing(false);
|
|
645
|
+
}
|
|
646
|
+
}, [refreshSchemaStatus]);
|
|
647
|
+
const missingList = missingScopes();
|
|
648
|
+
const debugPayload = (0, import_react2.useMemo)(() => {
|
|
649
|
+
return {
|
|
650
|
+
sdkVersion: version,
|
|
651
|
+
isReady,
|
|
652
|
+
isSignedIn,
|
|
653
|
+
did: did ?? null,
|
|
654
|
+
user: user ? {
|
|
655
|
+
sub: user.sub,
|
|
656
|
+
email: user.email,
|
|
657
|
+
name: user.name,
|
|
658
|
+
picture: user.picture
|
|
659
|
+
} : null,
|
|
660
|
+
scope,
|
|
661
|
+
missingScopes: missingList,
|
|
662
|
+
dbMode,
|
|
663
|
+
dbStatus,
|
|
664
|
+
indexedDbName: dbMode === "sync" ? INDEXED_DB_NAME : null,
|
|
665
|
+
schema: devInfo
|
|
666
|
+
};
|
|
667
|
+
}, [isReady, isSignedIn, did, user, scope, dbMode, dbStatus, devInfo, missingList]);
|
|
668
|
+
const handleCopy = (0, import_react2.useCallback)(async () => {
|
|
669
|
+
try {
|
|
670
|
+
await navigator.clipboard.writeText(JSON.stringify(debugPayload, null, 2));
|
|
671
|
+
setCopied(true);
|
|
672
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
673
|
+
} catch {
|
|
674
|
+
}
|
|
675
|
+
}, [debugPayload]);
|
|
676
|
+
const onRowCopied = (0, import_react2.useCallback)((key) => {
|
|
677
|
+
setRowCopied(key);
|
|
678
|
+
setTimeout(() => setRowCopied((k) => k === key ? null : k), 1500);
|
|
679
|
+
}, []);
|
|
680
|
+
if (!show) return null;
|
|
681
|
+
const shell = {
|
|
682
|
+
position: "fixed",
|
|
683
|
+
bottom: 12,
|
|
684
|
+
left: "50%",
|
|
685
|
+
transform: "translateX(-50%)",
|
|
686
|
+
zIndex: 99999,
|
|
687
|
+
fontFamily: 'ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace',
|
|
688
|
+
fontSize: 11,
|
|
689
|
+
color: "#e4e4e7",
|
|
690
|
+
pointerEvents: "auto"
|
|
691
|
+
};
|
|
692
|
+
const bar = {
|
|
693
|
+
display: "flex",
|
|
694
|
+
alignItems: "center",
|
|
695
|
+
gap: 8,
|
|
696
|
+
padding: "8px 12px",
|
|
697
|
+
borderRadius: 999,
|
|
698
|
+
background: "rgba(24, 24, 27, 0.92)",
|
|
699
|
+
border: "1px solid rgba(63, 63, 70, 0.9)",
|
|
700
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.35)",
|
|
701
|
+
cursor: "pointer",
|
|
702
|
+
userSelect: "none"
|
|
703
|
+
};
|
|
704
|
+
const dot = (tone) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
705
|
+
"span",
|
|
706
|
+
{
|
|
707
|
+
style: {
|
|
708
|
+
display: "block",
|
|
709
|
+
boxSizing: "border-box",
|
|
710
|
+
width: 6,
|
|
711
|
+
height: 6,
|
|
712
|
+
minWidth: 6,
|
|
713
|
+
minHeight: 6,
|
|
714
|
+
maxWidth: 6,
|
|
715
|
+
maxHeight: 6,
|
|
716
|
+
borderRadius: "50%",
|
|
717
|
+
background: chipColor(tone),
|
|
718
|
+
flexShrink: 0
|
|
719
|
+
}
|
|
720
|
+
}
|
|
721
|
+
);
|
|
722
|
+
const dotSlot = (title, tone) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
723
|
+
"span",
|
|
724
|
+
{
|
|
725
|
+
title,
|
|
726
|
+
style: {
|
|
727
|
+
display: "inline-flex",
|
|
728
|
+
alignItems: "center",
|
|
729
|
+
justifyContent: "center",
|
|
730
|
+
width: 6,
|
|
731
|
+
height: 6,
|
|
732
|
+
flexShrink: 0,
|
|
733
|
+
lineHeight: 0
|
|
734
|
+
},
|
|
735
|
+
children: dot(tone)
|
|
736
|
+
}
|
|
737
|
+
);
|
|
738
|
+
const panel = {
|
|
739
|
+
marginBottom: 8,
|
|
740
|
+
maxHeight: "50vh",
|
|
741
|
+
overflow: "auto",
|
|
742
|
+
padding: PANEL_PAD_X,
|
|
743
|
+
borderRadius: 10,
|
|
744
|
+
background: "rgba(24, 24, 27, 0.96)",
|
|
745
|
+
border: "1px solid rgba(63, 63, 70, 0.9)",
|
|
746
|
+
boxShadow: "0 8px 32px rgba(0,0,0,0.35)",
|
|
747
|
+
minWidth: 300,
|
|
748
|
+
maxWidth: "min(560px, calc(100vw - 24px))"
|
|
749
|
+
};
|
|
750
|
+
const syncStatusText = dbStatusLabel(dbStatus);
|
|
751
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: shell, children: [
|
|
752
|
+
open && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: panel, children: [
|
|
753
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { marginBottom: 12 }, children: [
|
|
754
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { style: { fontWeight: 600, fontSize: 12 }, children: "Basic SDK" }),
|
|
755
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { color: "#71717a", fontSize: 10, marginTop: 2 }, children: [
|
|
756
|
+
"v",
|
|
757
|
+
version
|
|
758
|
+
] })
|
|
759
|
+
] }),
|
|
760
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionHeader, { children: "Auth" }),
|
|
761
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
762
|
+
CopyableRow,
|
|
763
|
+
{
|
|
764
|
+
rowKey: "ready",
|
|
765
|
+
label: "Ready",
|
|
766
|
+
copyText: String(isReady),
|
|
767
|
+
copiedKey: rowCopied,
|
|
768
|
+
onCopied: onRowCopied,
|
|
769
|
+
children: String(isReady)
|
|
770
|
+
}
|
|
771
|
+
),
|
|
772
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
773
|
+
CopyableRow,
|
|
774
|
+
{
|
|
775
|
+
rowKey: "signedIn",
|
|
776
|
+
label: "Signed in",
|
|
777
|
+
copyText: String(isSignedIn),
|
|
778
|
+
copiedKey: rowCopied,
|
|
779
|
+
onCopied: onRowCopied,
|
|
780
|
+
children: String(isSignedIn)
|
|
781
|
+
}
|
|
782
|
+
),
|
|
783
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
784
|
+
CopyableRow,
|
|
785
|
+
{
|
|
786
|
+
rowKey: "did",
|
|
787
|
+
label: "DID",
|
|
788
|
+
copyText: did || "",
|
|
789
|
+
copiedKey: rowCopied,
|
|
790
|
+
onCopied: onRowCopied,
|
|
791
|
+
children: displayDid(did)
|
|
792
|
+
}
|
|
793
|
+
),
|
|
794
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
795
|
+
CopyableRow,
|
|
796
|
+
{
|
|
797
|
+
rowKey: "user",
|
|
798
|
+
label: "User",
|
|
799
|
+
copyText: user ? displayUserLine(user) : "",
|
|
800
|
+
copiedKey: rowCopied,
|
|
801
|
+
onCopied: onRowCopied,
|
|
802
|
+
children: user ? displayUserLine(user) : "\u2014"
|
|
803
|
+
}
|
|
804
|
+
),
|
|
805
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
806
|
+
CopyableRow,
|
|
807
|
+
{
|
|
808
|
+
rowKey: "scopes",
|
|
809
|
+
label: "Scopes",
|
|
810
|
+
copyText: scope || "",
|
|
811
|
+
copiedKey: rowCopied,
|
|
812
|
+
onCopied: onRowCopied,
|
|
813
|
+
children: scope || "\u2014"
|
|
814
|
+
}
|
|
815
|
+
),
|
|
816
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
817
|
+
CopyableRow,
|
|
818
|
+
{
|
|
819
|
+
rowKey: "missingScopes",
|
|
820
|
+
label: "Missing scopes",
|
|
821
|
+
copyText: missingList.length ? missingList.join(", ") : "",
|
|
822
|
+
copiedKey: rowCopied,
|
|
823
|
+
onCopied: onRowCopied,
|
|
824
|
+
children: missingList.length ? missingList.join(", ") : "\u2014"
|
|
825
|
+
}
|
|
826
|
+
),
|
|
827
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionRule, {}),
|
|
828
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionHeader, { children: "Database" }),
|
|
829
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
830
|
+
CopyableRow,
|
|
831
|
+
{
|
|
832
|
+
rowKey: "dbMode",
|
|
833
|
+
label: "Mode",
|
|
834
|
+
copyText: dbMode,
|
|
835
|
+
copiedKey: rowCopied,
|
|
836
|
+
onCopied: onRowCopied,
|
|
837
|
+
children: dbMode
|
|
838
|
+
}
|
|
839
|
+
),
|
|
840
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
841
|
+
CopyableRow,
|
|
842
|
+
{
|
|
843
|
+
rowKey: "indexedDb",
|
|
844
|
+
label: "IndexedDB",
|
|
845
|
+
copyText: dbMode === "sync" ? INDEXED_DB_NAME : "",
|
|
846
|
+
copiedKey: rowCopied,
|
|
847
|
+
onCopied: onRowCopied,
|
|
848
|
+
children: dbMode === "sync" ? INDEXED_DB_NAME : "\u2014"
|
|
849
|
+
}
|
|
850
|
+
),
|
|
851
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
852
|
+
CopyableRow,
|
|
853
|
+
{
|
|
854
|
+
rowKey: "syncStatus",
|
|
855
|
+
label: "Sync / status",
|
|
856
|
+
copyText: syncStatusText,
|
|
857
|
+
copiedKey: rowCopied,
|
|
858
|
+
onCopied: onRowCopied,
|
|
859
|
+
children: syncStatusText
|
|
860
|
+
}
|
|
861
|
+
),
|
|
862
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionRule, {}),
|
|
863
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(SectionHeader, { children: "Schema" }),
|
|
864
|
+
devInfo ? /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [
|
|
865
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
866
|
+
CopyableRow,
|
|
867
|
+
{
|
|
868
|
+
rowKey: "schemaProject",
|
|
869
|
+
label: "Project",
|
|
870
|
+
copyText: devInfo.projectId ?? "",
|
|
871
|
+
copiedKey: rowCopied,
|
|
872
|
+
onCopied: onRowCopied,
|
|
873
|
+
children: devInfo.projectId ?? "\u2014"
|
|
874
|
+
}
|
|
875
|
+
),
|
|
876
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
877
|
+
CopyableRow,
|
|
878
|
+
{
|
|
879
|
+
rowKey: "schemaLocalVer",
|
|
880
|
+
label: "Local version",
|
|
881
|
+
copyText: devInfo.localVersion !== void 0 && devInfo.localVersion !== null ? String(devInfo.localVersion) : "",
|
|
882
|
+
copiedKey: rowCopied,
|
|
883
|
+
onCopied: onRowCopied,
|
|
884
|
+
children: devInfo.localVersion ?? "\u2014"
|
|
885
|
+
}
|
|
886
|
+
),
|
|
887
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
888
|
+
CopyableRow,
|
|
889
|
+
{
|
|
890
|
+
rowKey: "schemaRemote",
|
|
891
|
+
label: "Remote check",
|
|
892
|
+
copyText: devInfo.status,
|
|
893
|
+
copiedKey: rowCopied,
|
|
894
|
+
onCopied: onRowCopied,
|
|
895
|
+
children: devInfo.status
|
|
896
|
+
}
|
|
897
|
+
),
|
|
898
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
899
|
+
CopyableRow,
|
|
900
|
+
{
|
|
901
|
+
rowKey: "schemaValid",
|
|
902
|
+
label: "Valid",
|
|
903
|
+
copyText: String(devInfo.valid),
|
|
904
|
+
copiedKey: rowCopied,
|
|
905
|
+
onCopied: onRowCopied,
|
|
906
|
+
children: String(devInfo.valid)
|
|
907
|
+
}
|
|
908
|
+
),
|
|
909
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
910
|
+
CopyableRow,
|
|
911
|
+
{
|
|
912
|
+
rowKey: "schemaChecked",
|
|
913
|
+
label: "Checked",
|
|
914
|
+
copyText: devInfo.lastCheckedAt ? new Date(devInfo.lastCheckedAt).toISOString() : "",
|
|
915
|
+
copiedKey: rowCopied,
|
|
916
|
+
onCopied: onRowCopied,
|
|
917
|
+
children: devInfo.lastCheckedAt ? new Date(devInfo.lastCheckedAt).toLocaleString() : "\u2014"
|
|
918
|
+
}
|
|
919
|
+
),
|
|
920
|
+
devInfo.error ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
921
|
+
CopyableRow,
|
|
922
|
+
{
|
|
923
|
+
rowKey: "schemaError",
|
|
924
|
+
label: "Error",
|
|
925
|
+
copyText: devInfo.error,
|
|
926
|
+
copiedKey: rowCopied,
|
|
927
|
+
onCopied: onRowCopied,
|
|
928
|
+
children: devInfo.error
|
|
929
|
+
}
|
|
930
|
+
) : null
|
|
931
|
+
] }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
932
|
+
CopyableRow,
|
|
933
|
+
{
|
|
934
|
+
rowKey: "schemaStatus",
|
|
935
|
+
label: "Status",
|
|
936
|
+
copyText: "No schema on provider",
|
|
937
|
+
copiedKey: rowCopied,
|
|
938
|
+
onCopied: onRowCopied,
|
|
939
|
+
children: "No schema on provider"
|
|
940
|
+
}
|
|
941
|
+
),
|
|
942
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { style: { display: "flex", gap: 8, marginTop: 12, flexWrap: "wrap" }, children: [
|
|
943
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
944
|
+
"button",
|
|
945
|
+
{
|
|
946
|
+
type: "button",
|
|
947
|
+
onClick: (e) => {
|
|
948
|
+
e.stopPropagation();
|
|
949
|
+
void handleRefreshSchema();
|
|
950
|
+
},
|
|
951
|
+
disabled: refreshing,
|
|
952
|
+
style: {
|
|
953
|
+
padding: "6px 10px",
|
|
954
|
+
borderRadius: 6,
|
|
955
|
+
border: "1px solid #3f3f46",
|
|
956
|
+
background: "#27272a",
|
|
957
|
+
color: "#e4e4e7",
|
|
958
|
+
cursor: refreshing ? "wait" : "pointer",
|
|
959
|
+
fontSize: 11,
|
|
960
|
+
fontFamily: "inherit"
|
|
961
|
+
},
|
|
962
|
+
children: refreshing ? "Refreshing\u2026" : "Refresh schema"
|
|
963
|
+
}
|
|
964
|
+
),
|
|
965
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
966
|
+
"button",
|
|
967
|
+
{
|
|
968
|
+
type: "button",
|
|
969
|
+
onClick: (e) => {
|
|
970
|
+
e.stopPropagation();
|
|
971
|
+
void handleCopy();
|
|
972
|
+
},
|
|
973
|
+
style: {
|
|
974
|
+
padding: "6px 10px",
|
|
975
|
+
borderRadius: 6,
|
|
976
|
+
border: "1px solid #3f3f46",
|
|
977
|
+
background: "#27272a",
|
|
978
|
+
color: "#e4e4e7",
|
|
979
|
+
cursor: "pointer",
|
|
980
|
+
fontSize: 11,
|
|
981
|
+
fontFamily: "inherit"
|
|
982
|
+
},
|
|
983
|
+
children: copied ? "Copied" : "Copy debug info"
|
|
984
|
+
}
|
|
985
|
+
)
|
|
986
|
+
] })
|
|
987
|
+
] }),
|
|
988
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
989
|
+
"button",
|
|
990
|
+
{
|
|
991
|
+
type: "button",
|
|
992
|
+
"aria-expanded": open,
|
|
993
|
+
onClick: () => setOpen((o) => !o),
|
|
994
|
+
style: {
|
|
995
|
+
...bar,
|
|
996
|
+
border: "none",
|
|
997
|
+
width: "100%",
|
|
998
|
+
cursor: "pointer"
|
|
999
|
+
},
|
|
1000
|
+
children: [
|
|
1001
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { fontWeight: 600, letterSpacing: 0.02 }, children: "Basic" }),
|
|
1002
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
|
|
1003
|
+
"span",
|
|
1004
|
+
{
|
|
1005
|
+
style: {
|
|
1006
|
+
display: "inline-flex",
|
|
1007
|
+
alignItems: "center",
|
|
1008
|
+
gap: 6,
|
|
1009
|
+
marginLeft: 8,
|
|
1010
|
+
height: 6,
|
|
1011
|
+
flexShrink: 0,
|
|
1012
|
+
lineHeight: 0
|
|
1013
|
+
},
|
|
1014
|
+
children: [
|
|
1015
|
+
dotSlot("Auth", authTone),
|
|
1016
|
+
dotSlot("DB", dbTone),
|
|
1017
|
+
dotSlot("Sync", syncTone),
|
|
1018
|
+
dotSlot("Schema", schemaTone)
|
|
1019
|
+
]
|
|
1020
|
+
}
|
|
1021
|
+
),
|
|
1022
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { style: { color: "#71717a", marginLeft: 4 }, children: open ? "\u25BE" : "\u25B4" })
|
|
1023
|
+
]
|
|
1024
|
+
}
|
|
1025
|
+
)
|
|
1026
|
+
] });
|
|
1027
|
+
}
|
|
1028
|
+
var import_react2, import_jsx_runtime, INDEXED_DB_NAME, PANEL_PAD_X;
|
|
1029
|
+
var init_BasicDevToolbar = __esm({
|
|
1030
|
+
"src/dev/BasicDevToolbar.tsx"() {
|
|
1031
|
+
"use strict";
|
|
1032
|
+
"use client";
|
|
1033
|
+
import_react2 = require("react");
|
|
1034
|
+
init_context();
|
|
1035
|
+
init_package();
|
|
1036
|
+
init_network();
|
|
1037
|
+
import_jsx_runtime = require("react/jsx-runtime");
|
|
1038
|
+
INDEXED_DB_NAME = "basicdb";
|
|
1039
|
+
PANEL_PAD_X = 12;
|
|
1040
|
+
}
|
|
1041
|
+
});
|
|
1042
|
+
|
|
241
1043
|
// src/index.ts
|
|
242
1044
|
var index_exports = {};
|
|
243
1045
|
__export(index_exports, {
|
|
1046
|
+
BasicDevToolbar: () => BasicDevToolbar,
|
|
244
1047
|
BasicProvider: () => BasicProvider,
|
|
245
1048
|
DBStatus: () => DBStatus,
|
|
246
1049
|
NotAuthenticatedError: () => NotAuthenticatedError,
|
|
@@ -257,7 +1060,7 @@ __export(index_exports, {
|
|
|
257
1060
|
module.exports = __toCommonJS(index_exports);
|
|
258
1061
|
|
|
259
1062
|
// src/AuthContext.tsx
|
|
260
|
-
var
|
|
1063
|
+
var import_react3 = require("react");
|
|
261
1064
|
|
|
262
1065
|
// src/sync/index.ts
|
|
263
1066
|
var import_uuid = require("uuid");
|
|
@@ -848,75 +1651,8 @@ async function resolveHandle(handle) {
|
|
|
848
1651
|
return resolved;
|
|
849
1652
|
}
|
|
850
1653
|
|
|
851
|
-
// src/utils/network.ts
|
|
852
|
-
init_config();
|
|
853
|
-
|
|
854
|
-
// package.json
|
|
855
|
-
var version = "0.8.0-beta.1";
|
|
856
|
-
|
|
857
|
-
// src/utils/network.ts
|
|
858
|
-
function isDevelopment(debug) {
|
|
859
|
-
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;
|
|
860
|
-
}
|
|
861
|
-
async function checkForNewVersion() {
|
|
862
|
-
try {
|
|
863
|
-
const isBeta = version.includes("beta");
|
|
864
|
-
const response = await fetch(`https://registry.npmjs.org/@basictech/react/${isBeta ? "beta" : "latest"}`);
|
|
865
|
-
if (!response.ok) {
|
|
866
|
-
throw new Error("Failed to fetch version from npm");
|
|
867
|
-
}
|
|
868
|
-
const data = await response.json();
|
|
869
|
-
const latestVersion = data.version;
|
|
870
|
-
if (latestVersion !== version) {
|
|
871
|
-
console.warn("[basic] New version available:", latestVersion, `
|
|
872
|
-
run "npm install @basictech/react@${latestVersion}" to update`);
|
|
873
|
-
}
|
|
874
|
-
if (isBeta) {
|
|
875
|
-
log("thank you for being on basictech/react beta :)");
|
|
876
|
-
}
|
|
877
|
-
return {
|
|
878
|
-
hasNewVersion: version !== latestVersion,
|
|
879
|
-
latestVersion,
|
|
880
|
-
currentVersion: version
|
|
881
|
-
};
|
|
882
|
-
} catch (error) {
|
|
883
|
-
log("Error checking for new version:", error);
|
|
884
|
-
return {
|
|
885
|
-
hasNewVersion: false,
|
|
886
|
-
latestVersion: null,
|
|
887
|
-
currentVersion: null
|
|
888
|
-
};
|
|
889
|
-
}
|
|
890
|
-
}
|
|
891
|
-
function cleanOAuthParamsFromUrl() {
|
|
892
|
-
if (window.location.search.includes("code") || window.location.search.includes("state")) {
|
|
893
|
-
const url = new URL(window.location.href);
|
|
894
|
-
url.searchParams.delete("code");
|
|
895
|
-
url.searchParams.delete("state");
|
|
896
|
-
window.history.pushState({}, document.title, url.pathname + url.search);
|
|
897
|
-
log("Cleaned OAuth parameters from URL");
|
|
898
|
-
}
|
|
899
|
-
}
|
|
900
|
-
function getSyncStatus(statusCode) {
|
|
901
|
-
switch (statusCode) {
|
|
902
|
-
case -1:
|
|
903
|
-
return "ERROR";
|
|
904
|
-
case 0:
|
|
905
|
-
return "OFFLINE";
|
|
906
|
-
case 1:
|
|
907
|
-
return "CONNECTING";
|
|
908
|
-
case 2:
|
|
909
|
-
return "ONLINE";
|
|
910
|
-
case 3:
|
|
911
|
-
return "SYNCING";
|
|
912
|
-
case 4:
|
|
913
|
-
return "ERROR_WILL_RETRY";
|
|
914
|
-
default:
|
|
915
|
-
return "UNKNOWN";
|
|
916
|
-
}
|
|
917
|
-
}
|
|
918
|
-
|
|
919
1654
|
// src/core/auth/AuthManager.ts
|
|
1655
|
+
init_network();
|
|
920
1656
|
init_config();
|
|
921
1657
|
function generateCodeVerifier() {
|
|
922
1658
|
const array = new Uint8Array(32);
|
|
@@ -1617,6 +2353,7 @@ var AuthManager = class {
|
|
|
1617
2353
|
|
|
1618
2354
|
// src/AuthContext.tsx
|
|
1619
2355
|
init_config();
|
|
2356
|
+
init_package();
|
|
1620
2357
|
|
|
1621
2358
|
// src/updater/versionUpdater.ts
|
|
1622
2359
|
init_config();
|
|
@@ -1741,6 +2478,9 @@ function getMigrations() {
|
|
|
1741
2478
|
];
|
|
1742
2479
|
}
|
|
1743
2480
|
|
|
2481
|
+
// src/AuthContext.tsx
|
|
2482
|
+
init_network();
|
|
2483
|
+
|
|
1744
2484
|
// src/utils/schema.ts
|
|
1745
2485
|
var import_schema3 = require("@basictech/schema");
|
|
1746
2486
|
init_config();
|
|
@@ -1840,57 +2580,18 @@ async function validateAndCheckSchema(schema) {
|
|
|
1840
2580
|
}
|
|
1841
2581
|
|
|
1842
2582
|
// src/AuthContext.tsx
|
|
1843
|
-
|
|
2583
|
+
init_context();
|
|
2584
|
+
init_context();
|
|
2585
|
+
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
2586
|
+
var BasicDevToolbar2 = (0, import_react3.lazy)(
|
|
2587
|
+
() => Promise.resolve().then(() => (init_BasicDevToolbar(), BasicDevToolbar_exports)).then((m) => ({ default: m.BasicDevToolbar }))
|
|
2588
|
+
);
|
|
1844
2589
|
var DEFAULT_AUTH_CONFIG = {
|
|
1845
2590
|
scopes: "profile,email,app:admin",
|
|
1846
2591
|
pds_url: "https://pds.basic.id",
|
|
1847
2592
|
admin_url: "https://api.basic.tech",
|
|
1848
2593
|
ws_url: "wss://pds.basic.id/ws"
|
|
1849
2594
|
};
|
|
1850
|
-
var DBStatus = /* @__PURE__ */ ((DBStatus2) => {
|
|
1851
|
-
DBStatus2["LOADING"] = "LOADING";
|
|
1852
|
-
DBStatus2["OFFLINE"] = "OFFLINE";
|
|
1853
|
-
DBStatus2["CONNECTING"] = "CONNECTING";
|
|
1854
|
-
DBStatus2["ONLINE"] = "ONLINE";
|
|
1855
|
-
DBStatus2["SYNCING"] = "SYNCING";
|
|
1856
|
-
DBStatus2["ERROR"] = "ERROR";
|
|
1857
|
-
DBStatus2["ERROR_WILL_RETRY"] = "ERROR_WILL_RETRY";
|
|
1858
|
-
DBStatus2["ERROR_TOKEN_EXPIRED"] = "ERROR_TOKEN_EXPIRED";
|
|
1859
|
-
return DBStatus2;
|
|
1860
|
-
})(DBStatus || {});
|
|
1861
|
-
var noDb = {
|
|
1862
|
-
collection: () => {
|
|
1863
|
-
throw new Error("no basicdb found - initialization failed. double check your schema.");
|
|
1864
|
-
}
|
|
1865
|
-
};
|
|
1866
|
-
var BasicContext = (0, import_react.createContext)({
|
|
1867
|
-
// Auth state
|
|
1868
|
-
isReady: false,
|
|
1869
|
-
isSignedIn: false,
|
|
1870
|
-
user: null,
|
|
1871
|
-
did: null,
|
|
1872
|
-
scope: null,
|
|
1873
|
-
hasScope: () => false,
|
|
1874
|
-
missingScopes: () => [],
|
|
1875
|
-
// Auth actions
|
|
1876
|
-
signIn: () => Promise.resolve(),
|
|
1877
|
-
signInWithHandle: () => Promise.resolve(),
|
|
1878
|
-
signOut: () => Promise.resolve(),
|
|
1879
|
-
signInWithCode: () => Promise.resolve({ success: false }),
|
|
1880
|
-
// Token management
|
|
1881
|
-
getToken: (_options) => Promise.reject(new Error("no token")),
|
|
1882
|
-
getSignInUrl: () => Promise.resolve(""),
|
|
1883
|
-
// DB access
|
|
1884
|
-
db: noDb,
|
|
1885
|
-
dbStatus: "LOADING" /* LOADING */,
|
|
1886
|
-
dbMode: "sync",
|
|
1887
|
-
// Legacy aliases
|
|
1888
|
-
isAuthReady: false,
|
|
1889
|
-
signin: () => Promise.resolve(),
|
|
1890
|
-
signout: () => Promise.resolve(),
|
|
1891
|
-
signinWithCode: () => Promise.resolve({ success: false }),
|
|
1892
|
-
getSignInLink: () => Promise.resolve("")
|
|
1893
|
-
});
|
|
1894
2595
|
function snapshotAuth(mgr) {
|
|
1895
2596
|
return {
|
|
1896
2597
|
isSignedIn: mgr.isSignedIn,
|
|
@@ -1908,7 +2609,8 @@ function BasicProvider({
|
|
|
1908
2609
|
debug = false,
|
|
1909
2610
|
storage,
|
|
1910
2611
|
auth,
|
|
1911
|
-
dbMode = "sync"
|
|
2612
|
+
dbMode = "sync",
|
|
2613
|
+
devToolbar = false
|
|
1912
2614
|
}) {
|
|
1913
2615
|
const project_id = schema?.project_id || project_id_prop;
|
|
1914
2616
|
if (auth?.server_url && !auth?.pds_url) {
|
|
@@ -1921,9 +2623,11 @@ function BasicProvider({
|
|
|
1921
2623
|
ws_url: auth?.ws_url || DEFAULT_AUTH_CONFIG.ws_url
|
|
1922
2624
|
};
|
|
1923
2625
|
const scopesString = Array.isArray(authConfig.scopes) ? authConfig.scopes.join(" ") : authConfig.scopes;
|
|
1924
|
-
const storageRef = (0,
|
|
2626
|
+
const storageRef = (0, import_react3.useRef)(storage || new LocalStorageAdapter());
|
|
1925
2627
|
const storageAdapter = storageRef.current;
|
|
1926
|
-
const
|
|
2628
|
+
const schemaRef = (0, import_react3.useRef)(schema);
|
|
2629
|
+
schemaRef.current = schema;
|
|
2630
|
+
const [authState, setAuthState] = (0, import_react3.useState)({
|
|
1927
2631
|
isSignedIn: false,
|
|
1928
2632
|
hasToken: false,
|
|
1929
2633
|
isAuthReady: false,
|
|
@@ -1931,7 +2635,7 @@ function BasicProvider({
|
|
|
1931
2635
|
did: null,
|
|
1932
2636
|
tokenScope: null
|
|
1933
2637
|
});
|
|
1934
|
-
const authRef = (0,
|
|
2638
|
+
const authRef = (0, import_react3.useRef)(null);
|
|
1935
2639
|
if (!authRef.current) {
|
|
1936
2640
|
authRef.current = new AuthManager(
|
|
1937
2641
|
{
|
|
@@ -1945,14 +2649,50 @@ function BasicProvider({
|
|
|
1945
2649
|
() => setAuthState(snapshotAuth(authRef.current))
|
|
1946
2650
|
);
|
|
1947
2651
|
}
|
|
1948
|
-
const syncRef = (0,
|
|
1949
|
-
const remoteDbRef = (0,
|
|
1950
|
-
const [shouldConnect, setShouldConnect] = (0,
|
|
1951
|
-
const [dbStatus, setDbStatus] = (0,
|
|
1952
|
-
const [isReady, setIsReady] = (0,
|
|
1953
|
-
const [error, setError] = (0,
|
|
2652
|
+
const syncRef = (0, import_react3.useRef)(null);
|
|
2653
|
+
const remoteDbRef = (0, import_react3.useRef)(null);
|
|
2654
|
+
const [shouldConnect, setShouldConnect] = (0, import_react3.useState)(false);
|
|
2655
|
+
const [dbStatus, setDbStatus] = (0, import_react3.useState)("OFFLINE" /* OFFLINE */);
|
|
2656
|
+
const [isReady, setIsReady] = (0, import_react3.useState)(false);
|
|
2657
|
+
const [error, setError] = (0, import_react3.useState)(null);
|
|
2658
|
+
const [schemaDevInfo, setSchemaDevInfo] = (0, import_react3.useState)(null);
|
|
1954
2659
|
const isDevMode = () => isDevelopment(debug);
|
|
1955
|
-
(0,
|
|
2660
|
+
const refreshSchemaStatus = (0, import_react3.useCallback)(async () => {
|
|
2661
|
+
const s = schemaRef.current;
|
|
2662
|
+
if (!s) {
|
|
2663
|
+
setSchemaDevInfo(
|
|
2664
|
+
project_id ? {
|
|
2665
|
+
projectId: project_id,
|
|
2666
|
+
localVersion: void 0,
|
|
2667
|
+
status: "no_schema",
|
|
2668
|
+
valid: false,
|
|
2669
|
+
lastCheckedAt: Date.now()
|
|
2670
|
+
} : null
|
|
2671
|
+
);
|
|
2672
|
+
return;
|
|
2673
|
+
}
|
|
2674
|
+
const result = await validateAndCheckSchema(s);
|
|
2675
|
+
if (!result.isValid) {
|
|
2676
|
+
const errText = result.errors?.map((e) => e.message || "").join("; ") || "invalid";
|
|
2677
|
+
setSchemaDevInfo({
|
|
2678
|
+
projectId: s.project_id ?? null,
|
|
2679
|
+
localVersion: s.version,
|
|
2680
|
+
status: "invalid",
|
|
2681
|
+
valid: false,
|
|
2682
|
+
lastCheckedAt: Date.now(),
|
|
2683
|
+
error: errText
|
|
2684
|
+
});
|
|
2685
|
+
return;
|
|
2686
|
+
}
|
|
2687
|
+
setSchemaDevInfo({
|
|
2688
|
+
projectId: s.project_id ?? null,
|
|
2689
|
+
localVersion: s.version,
|
|
2690
|
+
status: result.schemaStatus.status ?? "unknown",
|
|
2691
|
+
valid: result.schemaStatus.valid,
|
|
2692
|
+
lastCheckedAt: Date.now()
|
|
2693
|
+
});
|
|
2694
|
+
}, [project_id]);
|
|
2695
|
+
(0, import_react3.useEffect)(() => {
|
|
1956
2696
|
const runVersionUpdater = async () => {
|
|
1957
2697
|
try {
|
|
1958
2698
|
const versionUpdater = createVersionUpdater(storageAdapter, version, getMigrations());
|
|
@@ -1970,7 +2710,7 @@ function BasicProvider({
|
|
|
1970
2710
|
authRef.current.initialize();
|
|
1971
2711
|
return authRef.current.setupNetworkListeners();
|
|
1972
2712
|
}, []);
|
|
1973
|
-
(0,
|
|
2713
|
+
(0, import_react3.useEffect)(() => {
|
|
1974
2714
|
async function initSyncDb(options) {
|
|
1975
2715
|
if (!syncRef.current) {
|
|
1976
2716
|
log("Initializing Basic Sync DB");
|
|
@@ -2025,11 +2765,19 @@ function BasicProvider({
|
|
|
2025
2765
|
if (!result.isValid) {
|
|
2026
2766
|
let errorMessage = "";
|
|
2027
2767
|
if (result.errors) {
|
|
2028
|
-
result.errors.forEach((
|
|
2029
|
-
errorMessage += `${index + 1}: ${
|
|
2768
|
+
result.errors.forEach((err, index) => {
|
|
2769
|
+
errorMessage += `${index + 1}: ${err.message} - at ${err.instancePath}
|
|
2030
2770
|
`;
|
|
2031
2771
|
});
|
|
2032
2772
|
}
|
|
2773
|
+
setSchemaDevInfo({
|
|
2774
|
+
projectId: schema?.project_id ?? null,
|
|
2775
|
+
localVersion: schema?.version,
|
|
2776
|
+
status: "invalid",
|
|
2777
|
+
valid: false,
|
|
2778
|
+
lastCheckedAt: Date.now(),
|
|
2779
|
+
error: errorMessage.trim() || void 0
|
|
2780
|
+
});
|
|
2033
2781
|
setError({
|
|
2034
2782
|
code: "schema_invalid",
|
|
2035
2783
|
title: "Basic Schema is invalid!",
|
|
@@ -2038,6 +2786,13 @@ function BasicProvider({
|
|
|
2038
2786
|
setIsReady(true);
|
|
2039
2787
|
return null;
|
|
2040
2788
|
}
|
|
2789
|
+
setSchemaDevInfo({
|
|
2790
|
+
projectId: schema?.project_id ?? null,
|
|
2791
|
+
localVersion: schema?.version,
|
|
2792
|
+
status: result.schemaStatus.status ?? "unknown",
|
|
2793
|
+
valid: result.schemaStatus.valid,
|
|
2794
|
+
lastCheckedAt: Date.now()
|
|
2795
|
+
});
|
|
2041
2796
|
if (dbMode === "remote") {
|
|
2042
2797
|
initRemoteDb();
|
|
2043
2798
|
} else {
|
|
@@ -2057,6 +2812,15 @@ function BasicProvider({
|
|
|
2057
2812
|
if (schema) {
|
|
2058
2813
|
checkSchema();
|
|
2059
2814
|
} else {
|
|
2815
|
+
setSchemaDevInfo(
|
|
2816
|
+
project_id ? {
|
|
2817
|
+
projectId: project_id,
|
|
2818
|
+
localVersion: void 0,
|
|
2819
|
+
status: "no_schema",
|
|
2820
|
+
valid: false,
|
|
2821
|
+
lastCheckedAt: Date.now()
|
|
2822
|
+
} : null
|
|
2823
|
+
);
|
|
2060
2824
|
if (dbMode === "remote" && project_id) {
|
|
2061
2825
|
initRemoteDb();
|
|
2062
2826
|
} else {
|
|
@@ -2064,7 +2828,7 @@ function BasicProvider({
|
|
|
2064
2828
|
}
|
|
2065
2829
|
}
|
|
2066
2830
|
}, []);
|
|
2067
|
-
(0,
|
|
2831
|
+
(0, import_react3.useEffect)(() => {
|
|
2068
2832
|
if (authState.hasToken && syncRef.current && authState.isSignedIn && shouldConnect) {
|
|
2069
2833
|
log("connecting to db...");
|
|
2070
2834
|
syncRef.current?.connect({
|
|
@@ -2123,69 +2887,72 @@ function BasicProvider({
|
|
|
2123
2887
|
return syncRef.current || noDb;
|
|
2124
2888
|
};
|
|
2125
2889
|
const contextValue = {
|
|
2126
|
-
// Auth state
|
|
2127
2890
|
isReady: authState.isAuthReady,
|
|
2128
2891
|
isSignedIn: authState.isSignedIn,
|
|
2129
2892
|
user: authState.user,
|
|
2130
2893
|
did: authState.did,
|
|
2131
2894
|
scope: authState.tokenScope,
|
|
2132
|
-
hasScope: (
|
|
2895
|
+
hasScope: (s) => authRef.current.hasScope(s),
|
|
2133
2896
|
missingScopes: () => authRef.current.missingScopes(),
|
|
2134
|
-
// Auth actions
|
|
2135
2897
|
signIn: handleSignIn,
|
|
2136
2898
|
signInWithHandle: handleSignInWithHandle,
|
|
2137
2899
|
signOut: handleSignOut,
|
|
2138
2900
|
signInWithCode: (code, state) => authRef.current.signInWithCode(code, state),
|
|
2139
|
-
// Token management
|
|
2140
2901
|
getToken: (opts) => authRef.current.getToken(opts),
|
|
2141
2902
|
getSignInUrl: (redirectUri) => authRef.current.getSignInUrl(redirectUri),
|
|
2142
|
-
// DB access
|
|
2143
2903
|
db: getCurrentDb(),
|
|
2144
2904
|
dbStatus,
|
|
2145
2905
|
dbMode,
|
|
2146
|
-
|
|
2906
|
+
devInfo: schemaDevInfo,
|
|
2907
|
+
refreshSchemaStatus,
|
|
2147
2908
|
isAuthReady: authState.isAuthReady,
|
|
2148
2909
|
signin: handleSignIn,
|
|
2149
2910
|
signout: handleSignOut,
|
|
2150
2911
|
signinWithCode: (code, state) => authRef.current.signInWithCode(code, state),
|
|
2151
2912
|
getSignInLink: (redirectUri) => authRef.current.getSignInUrl(redirectUri)
|
|
2152
2913
|
};
|
|
2153
|
-
return /* @__PURE__ */ (0,
|
|
2154
|
-
error && isDevMode() && /* @__PURE__ */ (0,
|
|
2914
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(BasicContext.Provider, { value: contextValue, children: [
|
|
2915
|
+
error && isDevMode() && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ErrorDisplay, { error }),
|
|
2916
|
+
devToolbar && isDevMode() && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react3.Suspense, { fallback: null, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(BasicDevToolbar2, { debug }) }),
|
|
2155
2917
|
isReady && children
|
|
2156
2918
|
] });
|
|
2157
2919
|
}
|
|
2158
2920
|
function ErrorDisplay({ error }) {
|
|
2159
|
-
return /* @__PURE__ */ (0,
|
|
2160
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
2166
|
-
|
|
2167
|
-
|
|
2168
|
-
|
|
2169
|
-
|
|
2170
|
-
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2174
|
-
|
|
2175
|
-
|
|
2176
|
-
|
|
2177
|
-
|
|
2178
|
-
|
|
2179
|
-
|
|
2180
|
-
}
|
|
2181
|
-
|
|
2182
|
-
|
|
2921
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2922
|
+
"div",
|
|
2923
|
+
{
|
|
2924
|
+
style: {
|
|
2925
|
+
position: "absolute",
|
|
2926
|
+
top: 20,
|
|
2927
|
+
left: 20,
|
|
2928
|
+
color: "black",
|
|
2929
|
+
backgroundColor: "#f8d7da",
|
|
2930
|
+
border: "1px solid #f5c6cb",
|
|
2931
|
+
borderRadius: "4px",
|
|
2932
|
+
padding: "20px",
|
|
2933
|
+
maxWidth: "400px",
|
|
2934
|
+
margin: "20px auto",
|
|
2935
|
+
boxShadow: "0 2px 4px rgba(0, 0, 0, 0.1)",
|
|
2936
|
+
fontFamily: "monospace"
|
|
2937
|
+
},
|
|
2938
|
+
children: [
|
|
2939
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("h3", { style: { fontSize: "0.8rem", opacity: 0.8 }, children: [
|
|
2940
|
+
"code: ",
|
|
2941
|
+
error.code
|
|
2942
|
+
] }),
|
|
2943
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("h1", { style: { fontSize: "1.2rem", lineHeight: 1.5 }, children: error.title }),
|
|
2944
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { children: error.message })
|
|
2945
|
+
]
|
|
2946
|
+
}
|
|
2947
|
+
);
|
|
2183
2948
|
}
|
|
2184
2949
|
|
|
2185
2950
|
// src/index.ts
|
|
2186
2951
|
var import_dexie_react_hooks = require("dexie-react-hooks");
|
|
2952
|
+
init_BasicDevToolbar();
|
|
2187
2953
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2188
2954
|
0 && (module.exports = {
|
|
2955
|
+
BasicDevToolbar,
|
|
2189
2956
|
BasicProvider,
|
|
2190
2957
|
DBStatus,
|
|
2191
2958
|
NotAuthenticatedError,
|