@sybil-studio-devs/sdk 0.1.1 → 0.2.0

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.
@@ -20,7 +20,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/react/index.ts
21
21
  var react_exports = {};
22
22
  __export(react_exports, {
23
+ SybilAtlas: () => SybilAtlas,
24
+ SybilNexus: () => SybilNexus,
23
25
  SybilPages: () => SybilPages,
26
+ useAtlas: () => useAtlas,
27
+ useNexus: () => useNexus,
24
28
  useSybilPages: () => useSybilPages
25
29
  });
26
30
  module.exports = __toCommonJS(react_exports);
@@ -437,23 +441,1454 @@ var SybilPages = (0, import_react.forwardRef)(function SybilPages2({
437
441
  );
438
442
  });
439
443
 
444
+ // src/react/SybilAtlas.tsx
445
+ var import_react2 = require("react");
446
+
447
+ // src/atlas/client.ts
448
+ var DEFAULT_BASE_URL2 = "https://app.sybil.studio";
449
+ var AtlasLogger = class {
450
+ constructor(config) {
451
+ this.logs = [];
452
+ this.config = config;
453
+ }
454
+ log(level, category, message, data, duration) {
455
+ if (!this.config?.enabled) return;
456
+ const levels = ["debug", "info", "warn", "error"];
457
+ const configLevel = this.config.level || "info";
458
+ if (levels.indexOf(level) < levels.indexOf(configLevel)) return;
459
+ const entry = {
460
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
461
+ level,
462
+ category,
463
+ message,
464
+ data,
465
+ duration
466
+ };
467
+ this.logs.push(entry);
468
+ this.config.onLog?.(entry);
469
+ if (typeof console !== "undefined") {
470
+ const prefix = `[Atlas SDK] [${category}]`;
471
+ switch (level) {
472
+ case "debug":
473
+ console.debug(prefix, message, data || "");
474
+ break;
475
+ case "info":
476
+ console.info(prefix, message, data || "");
477
+ break;
478
+ case "warn":
479
+ console.warn(prefix, message, data || "");
480
+ break;
481
+ case "error":
482
+ console.error(prefix, message, data || "");
483
+ break;
484
+ }
485
+ }
486
+ }
487
+ getLogs() {
488
+ return [...this.logs];
489
+ }
490
+ clearLogs() {
491
+ this.logs = [];
492
+ }
493
+ };
494
+ function embedAtlas(config) {
495
+ const {
496
+ apiKey,
497
+ workspaceId,
498
+ container,
499
+ baseUrl = DEFAULT_BASE_URL2,
500
+ theme = "dark",
501
+ showSidebar = true,
502
+ sidebarWidth = 260,
503
+ sidebarCollapsible = true,
504
+ readOnly = false,
505
+ defaultPageId,
506
+ allowCreate = true,
507
+ allowDelete = true,
508
+ allowExport = true,
509
+ features = {},
510
+ logging,
511
+ onReady,
512
+ onPageChange,
513
+ onPageCreate,
514
+ onPageDelete,
515
+ onPageUpdate,
516
+ onError,
517
+ onNavigate
518
+ } = config;
519
+ const logger = new AtlasLogger(logging);
520
+ const startTime = Date.now();
521
+ logger.log("info", "render", "Initializing Atlas embed", {
522
+ workspaceId,
523
+ showSidebar,
524
+ readOnly,
525
+ features
526
+ });
527
+ const containerEl = typeof container === "string" ? document.querySelector(container) : container;
528
+ if (!containerEl) {
529
+ const error = {
530
+ code: "CONTAINER_NOT_FOUND",
531
+ message: "Container element not found",
532
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
533
+ };
534
+ onError?.(error);
535
+ throw new Error(error.message);
536
+ }
537
+ const params = new URLSearchParams({
538
+ apiKey,
539
+ workspaceId,
540
+ readOnly: readOnly.toString(),
541
+ showSidebar: showSidebar.toString(),
542
+ sidebarWidth: sidebarWidth.toString(),
543
+ sidebarCollapsible: sidebarCollapsible.toString(),
544
+ allowCreate: allowCreate.toString(),
545
+ allowDelete: allowDelete.toString(),
546
+ allowExport: allowExport.toString()
547
+ });
548
+ if (defaultPageId) params.set("defaultPageId", defaultPageId);
549
+ if (typeof theme === "string") {
550
+ params.set("theme", theme);
551
+ } else {
552
+ Object.entries(theme).forEach(([key, value]) => {
553
+ if (value) params.set(`theme_${key}`, value);
554
+ });
555
+ }
556
+ Object.entries(features).forEach(([key, value]) => {
557
+ if (typeof value === "boolean") {
558
+ params.set(`feature_${key}`, value.toString());
559
+ }
560
+ });
561
+ const iframe = document.createElement("iframe");
562
+ iframe.src = `${baseUrl}/embed/atlas?${params.toString()}`;
563
+ iframe.style.width = "100%";
564
+ iframe.style.height = "100%";
565
+ iframe.style.border = "none";
566
+ iframe.style.borderRadius = "8px";
567
+ iframe.allow = "clipboard-write";
568
+ let currentPage = null;
569
+ let isReady = false;
570
+ const createError = (code, message, status) => ({
571
+ code,
572
+ message,
573
+ status,
574
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
575
+ requestId: `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
576
+ });
577
+ const apiRequest = async (endpoint, options = {}) => {
578
+ const requestStart = Date.now();
579
+ const url = `${baseUrl}/api/sdk/v1${endpoint}`;
580
+ logger.log("debug", "api", `Request: ${options.method || "GET"} ${endpoint}`, {
581
+ url,
582
+ method: options.method || "GET"
583
+ });
584
+ try {
585
+ const response = await fetch(url, {
586
+ ...options,
587
+ headers: {
588
+ "x-api-key": apiKey,
589
+ "Content-Type": "application/json",
590
+ ...options.headers
591
+ }
592
+ });
593
+ const duration = Date.now() - requestStart;
594
+ if (!response.ok) {
595
+ const errorData = await response.json().catch(() => ({}));
596
+ const error = createError(
597
+ errorData.error?.code || "API_ERROR",
598
+ errorData.error?.message || `Request failed with status ${response.status}`,
599
+ response.status
600
+ );
601
+ logger.log("error", "api", `Request failed: ${endpoint}`, {
602
+ status: response.status,
603
+ error: errorData
604
+ }, duration);
605
+ onError?.(error);
606
+ throw error;
607
+ }
608
+ const data = await response.json();
609
+ logger.log("debug", "api", `Response: ${endpoint}`, { status: response.status }, duration);
610
+ return data;
611
+ } catch (err) {
612
+ if (err.code) throw err;
613
+ const error = createError("NETWORK_ERROR", err.message);
614
+ logger.log("error", "api", "Network error", { error: err.message });
615
+ onError?.(error);
616
+ throw error;
617
+ }
618
+ };
619
+ const postMessage = (type, payload) => {
620
+ iframe.contentWindow?.postMessage({ type, ...payload }, baseUrl);
621
+ };
622
+ const handleMessage = (event) => {
623
+ if (event.origin !== new URL(baseUrl).origin) return;
624
+ const { type, ...data } = event.data || {};
625
+ logger.log("debug", "render", `Message received: ${type}`, data);
626
+ switch (type) {
627
+ case "sybil:atlas:ready":
628
+ isReady = true;
629
+ logger.log("info", "render", "Atlas embed ready", {}, Date.now() - startTime);
630
+ onReady?.(instance);
631
+ break;
632
+ case "sybil:atlas:page:changed":
633
+ currentPage = data.page;
634
+ logger.log("info", "navigation", "Page changed", { pageId: data.page?.id });
635
+ onPageChange?.(data.page);
636
+ break;
637
+ case "sybil:atlas:page:created":
638
+ logger.log("info", "editor", "Page created", { pageId: data.page?.id });
639
+ onPageCreate?.(data.page);
640
+ break;
641
+ case "sybil:atlas:page:deleted":
642
+ logger.log("info", "editor", "Page deleted", { pageId: data.pageId });
643
+ onPageDelete?.(data.pageId);
644
+ break;
645
+ case "sybil:atlas:page:updated":
646
+ currentPage = data.page;
647
+ logger.log("debug", "sync", "Page updated", { pageId: data.page?.id });
648
+ onPageUpdate?.(data.page);
649
+ break;
650
+ case "sybil:atlas:navigate":
651
+ logger.log("info", "navigation", "Navigation requested", { pageId: data.pageId });
652
+ onNavigate?.(data.pageId);
653
+ break;
654
+ case "sybil:atlas:error":
655
+ const error = createError(data.code || "EMBED_ERROR", data.message);
656
+ logger.log("error", "render", "Embed error", data);
657
+ onError?.(error);
658
+ break;
659
+ }
660
+ };
661
+ window.addEventListener("message", handleMessage);
662
+ containerEl.appendChild(iframe);
663
+ const instance = {
664
+ getPages: async () => {
665
+ logger.log("info", "api", "Fetching pages");
666
+ const response = await apiRequest(
667
+ `/atlas/workspaces/${workspaceId}/sidebar`
668
+ );
669
+ return response.sidebar;
670
+ },
671
+ getPage: async (pageId) => {
672
+ logger.log("info", "api", "Fetching page", { pageId });
673
+ const response = await apiRequest(
674
+ `/atlas/pages/${pageId}`
675
+ );
676
+ return response.page;
677
+ },
678
+ createPage: async (params2) => {
679
+ logger.log("info", "api", "Creating page", params2);
680
+ const response = await apiRequest(
681
+ `/atlas/workspaces/${workspaceId}/pages`,
682
+ {
683
+ method: "POST",
684
+ body: JSON.stringify(params2)
685
+ }
686
+ );
687
+ postMessage("sybil:atlas:refresh");
688
+ return response.page;
689
+ },
690
+ updatePage: async (pageId, params2) => {
691
+ logger.log("info", "api", "Updating page", { pageId, ...params2 });
692
+ const response = await apiRequest(
693
+ `/atlas/pages/${pageId}`,
694
+ {
695
+ method: "PUT",
696
+ body: JSON.stringify(params2)
697
+ }
698
+ );
699
+ postMessage("sybil:atlas:refresh");
700
+ return response.page;
701
+ },
702
+ deletePage: async (pageId) => {
703
+ logger.log("info", "api", "Deleting page", { pageId });
704
+ await apiRequest(`/atlas/pages/${pageId}`, { method: "DELETE" });
705
+ postMessage("sybil:atlas:refresh");
706
+ },
707
+ navigateTo: (pageId) => {
708
+ logger.log("info", "navigation", "Navigating to page", { pageId });
709
+ postMessage("sybil:atlas:navigate", { pageId });
710
+ },
711
+ getCurrentPage: () => currentPage,
712
+ exportPage: async (pageId, format) => {
713
+ logger.log("info", "api", "Exporting page", { pageId, format });
714
+ const response = await fetch(
715
+ `${baseUrl}/api/sdk/v1/atlas/pages/${pageId}/export?format=${format}`,
716
+ {
717
+ headers: { "x-api-key": apiKey }
718
+ }
719
+ );
720
+ if (!response.ok) {
721
+ const error = createError("EXPORT_FAILED", "Failed to export page");
722
+ onError?.(error);
723
+ throw error;
724
+ }
725
+ return response.blob();
726
+ },
727
+ toggleSidebar: () => {
728
+ logger.log("debug", "render", "Toggling sidebar");
729
+ postMessage("sybil:atlas:toggleSidebar");
730
+ },
731
+ setSidebarWidth: (width) => {
732
+ logger.log("debug", "render", "Setting sidebar width", { width });
733
+ postMessage("sybil:atlas:setSidebarWidth", { width });
734
+ },
735
+ setTheme: (newTheme) => {
736
+ logger.log("debug", "render", "Setting theme", { theme: newTheme });
737
+ postMessage("sybil:atlas:setTheme", { theme: newTheme });
738
+ },
739
+ refresh: async () => {
740
+ logger.log("info", "sync", "Refreshing");
741
+ postMessage("sybil:atlas:refresh");
742
+ },
743
+ destroy: () => {
744
+ logger.log("info", "render", "Destroying Atlas embed");
745
+ window.removeEventListener("message", handleMessage);
746
+ iframe.remove();
747
+ },
748
+ getLogs: () => logger.getLogs(),
749
+ clearLogs: () => logger.clearLogs()
750
+ };
751
+ return instance;
752
+ }
753
+ var AtlasClient = class {
754
+ constructor(config) {
755
+ this.apiKey = config.apiKey;
756
+ this.workspaceId = config.workspaceId;
757
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL2;
758
+ this.logger = new AtlasLogger(config.logging);
759
+ }
760
+ async request(endpoint, options = {}) {
761
+ const url = `${this.baseUrl}/api/sdk/v1${endpoint}`;
762
+ const startTime = Date.now();
763
+ this.logger.log("debug", "api", `Request: ${options.method || "GET"} ${endpoint}`);
764
+ const response = await fetch(url, {
765
+ ...options,
766
+ headers: {
767
+ "x-api-key": this.apiKey,
768
+ "Content-Type": "application/json",
769
+ ...options.headers
770
+ }
771
+ });
772
+ const duration = Date.now() - startTime;
773
+ if (!response.ok) {
774
+ const errorData = await response.json().catch(() => ({}));
775
+ this.logger.log("error", "api", `Request failed: ${endpoint}`, {
776
+ status: response.status,
777
+ error: errorData
778
+ }, duration);
779
+ throw new Error(errorData.error?.message || `Request failed with status ${response.status}`);
780
+ }
781
+ this.logger.log("debug", "api", `Response: ${endpoint}`, { status: response.status }, duration);
782
+ return response.json();
783
+ }
784
+ async getSidebar() {
785
+ const response = await this.request(
786
+ `/atlas/workspaces/${this.workspaceId}/sidebar`
787
+ );
788
+ return response.sidebar;
789
+ }
790
+ async getPage(pageId) {
791
+ const response = await this.request(`/atlas/pages/${pageId}`);
792
+ return response.page;
793
+ }
794
+ async createPage(params = {}) {
795
+ const response = await this.request(
796
+ `/atlas/workspaces/${this.workspaceId}/pages`,
797
+ { method: "POST", body: JSON.stringify(params) }
798
+ );
799
+ return response.page;
800
+ }
801
+ async updatePage(pageId, params) {
802
+ const response = await this.request(
803
+ `/atlas/pages/${pageId}`,
804
+ { method: "PUT", body: JSON.stringify(params) }
805
+ );
806
+ return response.page;
807
+ }
808
+ async deletePage(pageId) {
809
+ await this.request(`/atlas/pages/${pageId}`, { method: "DELETE" });
810
+ }
811
+ async exportPage(pageId, format) {
812
+ const response = await fetch(
813
+ `${this.baseUrl}/api/sdk/v1/atlas/pages/${pageId}/export?format=${format}`,
814
+ { headers: { "x-api-key": this.apiKey } }
815
+ );
816
+ if (!response.ok) throw new Error("Failed to export page");
817
+ return response.blob();
818
+ }
819
+ async toggleFavorite(pageId) {
820
+ const response = await this.request(
821
+ `/atlas/pages/${pageId}/favorite`,
822
+ { method: "POST" }
823
+ );
824
+ return response.page;
825
+ }
826
+ getLogs() {
827
+ return this.logger.getLogs();
828
+ }
829
+ clearLogs() {
830
+ this.logger.clearLogs();
831
+ }
832
+ };
833
+
834
+ // src/react/SybilAtlas.tsx
835
+ var import_jsx_runtime2 = require("react/jsx-runtime");
836
+ var SybilAtlas = (0, import_react2.forwardRef)(function SybilAtlas2({
837
+ apiKey,
838
+ workspaceId,
839
+ baseUrl,
840
+ theme = "dark",
841
+ showSidebar = true,
842
+ sidebarWidth = 260,
843
+ sidebarCollapsible = true,
844
+ readOnly = false,
845
+ defaultPageId,
846
+ allowCreate = true,
847
+ allowDelete = true,
848
+ allowExport = true,
849
+ features,
850
+ logging,
851
+ className,
852
+ style,
853
+ onReady,
854
+ onPageChange,
855
+ onPageCreate,
856
+ onPageDelete,
857
+ onPageUpdate,
858
+ onError,
859
+ onNavigate
860
+ }, ref) {
861
+ const containerRef = (0, import_react2.useRef)(null);
862
+ const instanceRef = (0, import_react2.useRef)(null);
863
+ (0, import_react2.useImperativeHandle)(ref, () => ({
864
+ getPages: async () => {
865
+ if (!instanceRef.current) throw new Error("Atlas not initialized");
866
+ return instanceRef.current.getPages();
867
+ },
868
+ getPage: async (pageId) => {
869
+ if (!instanceRef.current) throw new Error("Atlas not initialized");
870
+ return instanceRef.current.getPage(pageId);
871
+ },
872
+ createPage: async (params) => {
873
+ if (!instanceRef.current) throw new Error("Atlas not initialized");
874
+ return instanceRef.current.createPage(params || {});
875
+ },
876
+ updatePage: async (pageId, params) => {
877
+ if (!instanceRef.current) throw new Error("Atlas not initialized");
878
+ return instanceRef.current.updatePage(pageId, params);
879
+ },
880
+ deletePage: async (pageId) => {
881
+ if (!instanceRef.current) throw new Error("Atlas not initialized");
882
+ return instanceRef.current.deletePage(pageId);
883
+ },
884
+ navigateTo: (pageId) => {
885
+ instanceRef.current?.navigateTo(pageId);
886
+ },
887
+ getCurrentPage: () => {
888
+ return instanceRef.current?.getCurrentPage() || null;
889
+ },
890
+ exportPage: async (pageId, format) => {
891
+ if (!instanceRef.current) throw new Error("Atlas not initialized");
892
+ return instanceRef.current.exportPage(pageId, format);
893
+ },
894
+ toggleSidebar: () => {
895
+ instanceRef.current?.toggleSidebar();
896
+ },
897
+ setSidebarWidth: (width) => {
898
+ instanceRef.current?.setSidebarWidth(width);
899
+ },
900
+ setTheme: (newTheme) => {
901
+ instanceRef.current?.setTheme(newTheme);
902
+ },
903
+ refresh: async () => {
904
+ return instanceRef.current?.refresh();
905
+ },
906
+ getLogs: () => {
907
+ return instanceRef.current?.getLogs() || [];
908
+ },
909
+ clearLogs: () => {
910
+ instanceRef.current?.clearLogs();
911
+ }
912
+ }));
913
+ (0, import_react2.useEffect)(() => {
914
+ if (!containerRef.current || !apiKey || !workspaceId) return;
915
+ instanceRef.current?.destroy();
916
+ const config = {
917
+ apiKey,
918
+ workspaceId,
919
+ container: containerRef.current,
920
+ baseUrl,
921
+ theme,
922
+ showSidebar,
923
+ sidebarWidth,
924
+ sidebarCollapsible,
925
+ readOnly,
926
+ defaultPageId,
927
+ allowCreate,
928
+ allowDelete,
929
+ allowExport,
930
+ features,
931
+ logging,
932
+ onReady,
933
+ onPageChange,
934
+ onPageCreate,
935
+ onPageDelete,
936
+ onPageUpdate,
937
+ onError,
938
+ onNavigate
939
+ };
940
+ instanceRef.current = embedAtlas(config);
941
+ return () => {
942
+ instanceRef.current?.destroy();
943
+ instanceRef.current = null;
944
+ };
945
+ }, [apiKey, workspaceId, baseUrl]);
946
+ (0, import_react2.useEffect)(() => {
947
+ instanceRef.current?.setTheme(theme);
948
+ }, [theme]);
949
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
950
+ "div",
951
+ {
952
+ ref: containerRef,
953
+ className,
954
+ style: {
955
+ width: "100%",
956
+ height: "100%",
957
+ minHeight: "500px",
958
+ ...style
959
+ }
960
+ }
961
+ );
962
+ });
963
+
964
+ // src/react/SybilNexus.tsx
965
+ var import_react3 = require("react");
966
+
967
+ // src/nexus/client.ts
968
+ var DEFAULT_BASE_URL3 = "https://app.sybil.studio";
969
+ var NexusLogger = class {
970
+ constructor(config) {
971
+ this.logs = [];
972
+ this.config = config;
973
+ }
974
+ log(level, category, message, data, duration) {
975
+ if (!this.config?.enabled) return;
976
+ const levels = ["debug", "info", "warn", "error"];
977
+ const configLevel = this.config.level || "info";
978
+ if (levels.indexOf(level) < levels.indexOf(configLevel)) return;
979
+ const entry = {
980
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
981
+ level,
982
+ category,
983
+ message,
984
+ data,
985
+ duration,
986
+ fileId: data?.fileId,
987
+ folderId: data?.folderId
988
+ };
989
+ this.logs.push(entry);
990
+ this.config.onLog?.(entry);
991
+ if (typeof console !== "undefined") {
992
+ const prefix = `[Nexus SDK] [${category}]`;
993
+ switch (level) {
994
+ case "debug":
995
+ console.debug(prefix, message, data || "");
996
+ break;
997
+ case "info":
998
+ console.info(prefix, message, data || "");
999
+ break;
1000
+ case "warn":
1001
+ console.warn(prefix, message, data || "");
1002
+ break;
1003
+ case "error":
1004
+ console.error(prefix, message, data || "");
1005
+ break;
1006
+ }
1007
+ }
1008
+ }
1009
+ getLogs() {
1010
+ return [...this.logs];
1011
+ }
1012
+ clearLogs() {
1013
+ this.logs = [];
1014
+ }
1015
+ };
1016
+ function embedNexus(config) {
1017
+ const {
1018
+ apiKey,
1019
+ workspaceId,
1020
+ container,
1021
+ baseUrl = DEFAULT_BASE_URL3,
1022
+ theme = "dark",
1023
+ initialFolderId = null,
1024
+ viewMode = "list",
1025
+ showSidebar = true,
1026
+ showActivityFeed = true,
1027
+ showBreadcrumbs = true,
1028
+ showSearch = true,
1029
+ allowUpload = true,
1030
+ allowDownload = true,
1031
+ allowDelete = true,
1032
+ allowMove = true,
1033
+ allowRename = true,
1034
+ allowCreateFolder = true,
1035
+ allowMultiSelect = true,
1036
+ maxUploadSize,
1037
+ acceptedFileTypes,
1038
+ features = {},
1039
+ logging,
1040
+ onReady,
1041
+ onNavigate,
1042
+ onFileSelect,
1043
+ onFileOpen,
1044
+ onFileUpload,
1045
+ onFileDelete,
1046
+ onFolderCreate,
1047
+ onFolderDelete,
1048
+ onSelectionChange,
1049
+ onError
1050
+ } = config;
1051
+ const logger = new NexusLogger(logging);
1052
+ const startTime = Date.now();
1053
+ logger.log("info", "ui", "Initializing Nexus embed", {
1054
+ workspaceId,
1055
+ initialFolderId,
1056
+ viewMode,
1057
+ features
1058
+ });
1059
+ const containerEl = typeof container === "string" ? document.querySelector(container) : container;
1060
+ if (!containerEl) {
1061
+ const error = {
1062
+ code: "CONTAINER_NOT_FOUND",
1063
+ message: "Container element not found",
1064
+ timestamp: (/* @__PURE__ */ new Date()).toISOString()
1065
+ };
1066
+ onError?.(error);
1067
+ throw new Error(error.message);
1068
+ }
1069
+ const params = new URLSearchParams({
1070
+ apiKey,
1071
+ workspaceId,
1072
+ viewMode,
1073
+ showSidebar: showSidebar.toString(),
1074
+ showActivityFeed: showActivityFeed.toString(),
1075
+ showBreadcrumbs: showBreadcrumbs.toString(),
1076
+ showSearch: showSearch.toString(),
1077
+ allowUpload: allowUpload.toString(),
1078
+ allowDownload: allowDownload.toString(),
1079
+ allowDelete: allowDelete.toString(),
1080
+ allowMove: allowMove.toString(),
1081
+ allowRename: allowRename.toString(),
1082
+ allowCreateFolder: allowCreateFolder.toString(),
1083
+ allowMultiSelect: allowMultiSelect.toString()
1084
+ });
1085
+ if (initialFolderId) params.set("folderId", initialFolderId);
1086
+ if (maxUploadSize) params.set("maxUploadSize", maxUploadSize.toString());
1087
+ if (acceptedFileTypes?.length) params.set("acceptedFileTypes", acceptedFileTypes.join(","));
1088
+ if (typeof theme === "string") {
1089
+ params.set("theme", theme);
1090
+ } else {
1091
+ Object.entries(theme).forEach(([key, value]) => {
1092
+ if (value) params.set(`theme_${key}`, value);
1093
+ });
1094
+ }
1095
+ Object.entries(features).forEach(([key, value]) => {
1096
+ if (typeof value === "boolean") {
1097
+ params.set(`feature_${key}`, value.toString());
1098
+ }
1099
+ });
1100
+ const iframe = document.createElement("iframe");
1101
+ iframe.src = `${baseUrl}/embed/nexus?${params.toString()}`;
1102
+ iframe.style.width = "100%";
1103
+ iframe.style.height = "100%";
1104
+ iframe.style.border = "none";
1105
+ iframe.style.borderRadius = "8px";
1106
+ iframe.allow = "clipboard-write";
1107
+ let currentFolderId = initialFolderId;
1108
+ let selectedItems = [];
1109
+ let isReady = false;
1110
+ const createError = (code, message, status) => ({
1111
+ code,
1112
+ message,
1113
+ status,
1114
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
1115
+ requestId: `req_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
1116
+ });
1117
+ const apiRequest = async (endpoint, options = {}) => {
1118
+ const requestStart = Date.now();
1119
+ const url = `${baseUrl}/api/sdk/v1${endpoint}`;
1120
+ logger.log("debug", "api", `Request: ${options.method || "GET"} ${endpoint}`, {
1121
+ url,
1122
+ method: options.method || "GET"
1123
+ });
1124
+ try {
1125
+ const response = await fetch(url, {
1126
+ ...options,
1127
+ headers: {
1128
+ "x-api-key": apiKey,
1129
+ ...options.body instanceof FormData ? {} : { "Content-Type": "application/json" },
1130
+ ...options.headers
1131
+ }
1132
+ });
1133
+ const duration = Date.now() - requestStart;
1134
+ if (!response.ok) {
1135
+ const errorData = await response.json().catch(() => ({}));
1136
+ const error = createError(
1137
+ errorData.error?.code || "API_ERROR",
1138
+ errorData.error?.message || `Request failed with status ${response.status}`,
1139
+ response.status
1140
+ );
1141
+ logger.log("error", "api", `Request failed: ${endpoint}`, {
1142
+ status: response.status,
1143
+ error: errorData
1144
+ }, duration);
1145
+ onError?.(error);
1146
+ throw error;
1147
+ }
1148
+ const data = await response.json();
1149
+ logger.log("debug", "api", `Response: ${endpoint}`, { status: response.status }, duration);
1150
+ return data;
1151
+ } catch (err) {
1152
+ if (err.code) throw err;
1153
+ const error = createError("NETWORK_ERROR", err.message);
1154
+ logger.log("error", "api", "Network error", { error: err.message });
1155
+ onError?.(error);
1156
+ throw error;
1157
+ }
1158
+ };
1159
+ const postMessage = (type, payload) => {
1160
+ iframe.contentWindow?.postMessage({ type, ...payload }, baseUrl);
1161
+ };
1162
+ const handleMessage = (event) => {
1163
+ if (event.origin !== new URL(baseUrl).origin) return;
1164
+ const { type, ...data } = event.data || {};
1165
+ logger.log("debug", "ui", `Message received: ${type}`, data);
1166
+ switch (type) {
1167
+ case "sybil:nexus:ready":
1168
+ isReady = true;
1169
+ logger.log("info", "ui", "Nexus embed ready", {}, Date.now() - startTime);
1170
+ onReady?.(instance);
1171
+ break;
1172
+ case "sybil:nexus:navigate":
1173
+ currentFolderId = data.folderId;
1174
+ logger.log("info", "navigation", "Navigated to folder", { folderId: data.folderId });
1175
+ onNavigate?.(data.folderId);
1176
+ break;
1177
+ case "sybil:nexus:file:select":
1178
+ logger.log("debug", "selection", "File selected", { fileId: data.file?.id });
1179
+ onFileSelect?.(data.file);
1180
+ break;
1181
+ case "sybil:nexus:file:open":
1182
+ logger.log("info", "ui", "File opened", { fileId: data.file?.id });
1183
+ onFileOpen?.(data.file);
1184
+ break;
1185
+ case "sybil:nexus:file:upload":
1186
+ logger.log("info", "upload", "File uploaded", { fileId: data.file?.id });
1187
+ onFileUpload?.(data.file);
1188
+ break;
1189
+ case "sybil:nexus:file:delete":
1190
+ logger.log("info", "api", "File deleted", { fileId: data.fileId });
1191
+ onFileDelete?.(data.fileId);
1192
+ break;
1193
+ case "sybil:nexus:folder:create":
1194
+ logger.log("info", "api", "Folder created", { folderId: data.folder?.id });
1195
+ onFolderCreate?.(data.folder);
1196
+ break;
1197
+ case "sybil:nexus:folder:delete":
1198
+ logger.log("info", "api", "Folder deleted", { folderId: data.folderId });
1199
+ onFolderDelete?.(data.folderId);
1200
+ break;
1201
+ case "sybil:nexus:selection:change":
1202
+ selectedItems = data.items || [];
1203
+ logger.log("debug", "selection", "Selection changed", { count: selectedItems.length });
1204
+ onSelectionChange?.(selectedItems);
1205
+ break;
1206
+ case "sybil:nexus:error":
1207
+ const error = createError(data.code || "EMBED_ERROR", data.message);
1208
+ logger.log("error", "ui", "Embed error", data);
1209
+ onError?.(error);
1210
+ break;
1211
+ }
1212
+ };
1213
+ window.addEventListener("message", handleMessage);
1214
+ containerEl.appendChild(iframe);
1215
+ const instance = {
1216
+ getFiles: async (folderId) => {
1217
+ logger.log("info", "api", "Fetching files", { folderId });
1218
+ const params2 = new URLSearchParams({ workspaceId });
1219
+ if (folderId !== void 0) params2.set("folderId", folderId || "null");
1220
+ const response = await apiRequest(
1221
+ `/nexus/files?${params2.toString()}`
1222
+ );
1223
+ return response.files.map((f) => ({
1224
+ ...f,
1225
+ itemType: "file"
1226
+ }));
1227
+ },
1228
+ getFolders: async (parentId) => {
1229
+ logger.log("info", "api", "Fetching folders", { parentId });
1230
+ const params2 = new URLSearchParams({ workspaceId });
1231
+ if (parentId !== void 0) params2.set("parentId", parentId || "null");
1232
+ const response = await apiRequest(
1233
+ `/nexus/folders?${params2.toString()}`
1234
+ );
1235
+ return response.folders;
1236
+ },
1237
+ getFolderContents: async (folderId) => {
1238
+ logger.log("info", "api", "Fetching folder contents", { folderId });
1239
+ const params2 = new URLSearchParams({ workspaceId });
1240
+ if (folderId) params2.set("folderId", folderId);
1241
+ const response = await apiRequest(
1242
+ `/nexus/folders/contents?${params2.toString()}`
1243
+ );
1244
+ return response;
1245
+ },
1246
+ getFolderTree: async () => {
1247
+ logger.log("info", "api", "Fetching folder tree");
1248
+ const response = await apiRequest(
1249
+ `/nexus/folders/tree?workspaceId=${workspaceId}`
1250
+ );
1251
+ return response.tree;
1252
+ },
1253
+ getFile: async (fileId) => {
1254
+ logger.log("info", "api", "Fetching file", { fileId });
1255
+ const response = await apiRequest(`/nexus/files/${fileId}`);
1256
+ return response.file;
1257
+ },
1258
+ getFolder: async (folderId) => {
1259
+ logger.log("info", "api", "Fetching folder", { folderId });
1260
+ const response = await apiRequest(
1261
+ `/nexus/folders/${folderId}`
1262
+ );
1263
+ return response.folder;
1264
+ },
1265
+ uploadFile: async (file, folderId, onProgress) => {
1266
+ logger.log("info", "upload", "Uploading file", { fileName: file.name, size: file.size, folderId });
1267
+ const formData = new FormData();
1268
+ formData.append("file", file);
1269
+ formData.append("workspaceId", workspaceId);
1270
+ if (folderId) formData.append("folderId", folderId);
1271
+ const xhr = new XMLHttpRequest();
1272
+ return new Promise((resolve, reject) => {
1273
+ xhr.upload.addEventListener("progress", (e) => {
1274
+ if (e.lengthComputable) {
1275
+ const progress = Math.round(e.loaded / e.total * 100);
1276
+ logger.log("debug", "upload", "Upload progress", { progress, fileName: file.name });
1277
+ onProgress?.(progress);
1278
+ }
1279
+ });
1280
+ xhr.addEventListener("load", () => {
1281
+ if (xhr.status >= 200 && xhr.status < 300) {
1282
+ const response = JSON.parse(xhr.responseText);
1283
+ logger.log("info", "upload", "Upload complete", { fileId: response.file?.id });
1284
+ postMessage("sybil:nexus:refresh");
1285
+ resolve(response.file);
1286
+ } else {
1287
+ const error = createError("UPLOAD_FAILED", "Failed to upload file", xhr.status);
1288
+ logger.log("error", "upload", "Upload failed", { status: xhr.status });
1289
+ onError?.(error);
1290
+ reject(error);
1291
+ }
1292
+ });
1293
+ xhr.addEventListener("error", () => {
1294
+ const error = createError("UPLOAD_ERROR", "Network error during upload");
1295
+ logger.log("error", "upload", "Upload network error");
1296
+ onError?.(error);
1297
+ reject(error);
1298
+ });
1299
+ xhr.open("POST", `${baseUrl}/api/sdk/v1/nexus/upload`);
1300
+ xhr.setRequestHeader("x-api-key", apiKey);
1301
+ xhr.send(formData);
1302
+ });
1303
+ },
1304
+ uploadFiles: async (files, folderId, onProgress) => {
1305
+ logger.log("info", "upload", "Uploading multiple files", { count: files.length, folderId });
1306
+ const results = [];
1307
+ for (let i = 0; i < files.length; i++) {
1308
+ const file = await instance.uploadFile(files[i], folderId, (progress) => {
1309
+ onProgress?.(i, progress);
1310
+ });
1311
+ results.push(file);
1312
+ }
1313
+ return results;
1314
+ },
1315
+ downloadFile: async (fileId) => {
1316
+ logger.log("info", "download", "Downloading file", { fileId });
1317
+ const response = await fetch(`${baseUrl}/api/sdk/v1/nexus/files/${fileId}/content`, {
1318
+ headers: { "x-api-key": apiKey }
1319
+ });
1320
+ if (!response.ok) {
1321
+ const error = createError("DOWNLOAD_FAILED", "Failed to download file", response.status);
1322
+ onError?.(error);
1323
+ throw error;
1324
+ }
1325
+ return response.blob();
1326
+ },
1327
+ getDownloadUrl: async (fileId) => {
1328
+ logger.log("info", "download", "Getting download URL", { fileId });
1329
+ const response = await apiRequest(`/nexus/files/${fileId}/url`);
1330
+ return response.signedUrl;
1331
+ },
1332
+ deleteFile: async (fileId) => {
1333
+ logger.log("info", "api", "Deleting file", { fileId });
1334
+ await apiRequest(`/nexus/files/${fileId}`, { method: "DELETE" });
1335
+ postMessage("sybil:nexus:refresh");
1336
+ },
1337
+ deleteFiles: async (fileIds) => {
1338
+ logger.log("info", "api", "Deleting multiple files", { count: fileIds.length });
1339
+ await apiRequest("/nexus/files/bulk", {
1340
+ method: "DELETE",
1341
+ body: JSON.stringify({ fileIds })
1342
+ });
1343
+ postMessage("sybil:nexus:refresh");
1344
+ },
1345
+ moveFile: async (fileId, targetFolderId) => {
1346
+ logger.log("info", "api", "Moving file", { fileId, targetFolderId });
1347
+ const response = await apiRequest(`/nexus/files/${fileId}`, {
1348
+ method: "PATCH",
1349
+ body: JSON.stringify({ folderId: targetFolderId })
1350
+ });
1351
+ postMessage("sybil:nexus:refresh");
1352
+ return response.file;
1353
+ },
1354
+ moveFiles: async (fileIds, targetFolderId) => {
1355
+ logger.log("info", "api", "Moving multiple files", { count: fileIds.length, targetFolderId });
1356
+ const response = await apiRequest("/nexus/files/bulk", {
1357
+ method: "PATCH",
1358
+ body: JSON.stringify({ fileIds, folderId: targetFolderId })
1359
+ });
1360
+ postMessage("sybil:nexus:refresh");
1361
+ return response.files;
1362
+ },
1363
+ renameFile: async (fileId, newName) => {
1364
+ logger.log("info", "api", "Renaming file", { fileId, newName });
1365
+ const response = await apiRequest(`/nexus/files/${fileId}`, {
1366
+ method: "PATCH",
1367
+ body: JSON.stringify({ name: newName })
1368
+ });
1369
+ postMessage("sybil:nexus:refresh");
1370
+ return response.file;
1371
+ },
1372
+ starFile: async (fileId, starred) => {
1373
+ logger.log("info", "api", "Starring file", { fileId, starred });
1374
+ const response = await apiRequest(`/nexus/files/${fileId}`, {
1375
+ method: "PATCH",
1376
+ body: JSON.stringify({ isStarred: starred })
1377
+ });
1378
+ postMessage("sybil:nexus:refresh");
1379
+ return response.file;
1380
+ },
1381
+ starFiles: async (fileIds, starred) => {
1382
+ logger.log("info", "api", "Starring multiple files", { count: fileIds.length, starred });
1383
+ await apiRequest("/nexus/files/bulk", {
1384
+ method: "PATCH",
1385
+ body: JSON.stringify({ fileIds, isStarred: starred })
1386
+ });
1387
+ postMessage("sybil:nexus:refresh");
1388
+ },
1389
+ trashFile: async (fileId) => {
1390
+ logger.log("info", "api", "Trashing file", { fileId });
1391
+ await apiRequest(`/nexus/files/${fileId}`, { method: "DELETE" });
1392
+ postMessage("sybil:nexus:refresh");
1393
+ },
1394
+ restoreFile: async (fileId, folderId) => {
1395
+ logger.log("info", "api", "Restoring file", { fileId, folderId });
1396
+ const response = await apiRequest(`/nexus/files/${fileId}/restore`, {
1397
+ method: "POST",
1398
+ body: JSON.stringify({ folderId })
1399
+ });
1400
+ postMessage("sybil:nexus:refresh");
1401
+ return response.file;
1402
+ },
1403
+ createFolder: async (name, parentId, options) => {
1404
+ logger.log("info", "api", "Creating folder", { name, parentId, options });
1405
+ const response = await apiRequest("/nexus/folders", {
1406
+ method: "POST",
1407
+ body: JSON.stringify({ workspaceId, name, parentId, ...options })
1408
+ });
1409
+ postMessage("sybil:nexus:refresh");
1410
+ return response.folder;
1411
+ },
1412
+ deleteFolder: async (folderId) => {
1413
+ logger.log("info", "api", "Deleting folder", { folderId });
1414
+ await apiRequest(`/nexus/folders/${folderId}`, { method: "DELETE" });
1415
+ postMessage("sybil:nexus:refresh");
1416
+ },
1417
+ moveFolder: async (folderId, targetParentId) => {
1418
+ logger.log("info", "api", "Moving folder", { folderId, targetParentId });
1419
+ const response = await apiRequest(`/nexus/folders/${folderId}`, {
1420
+ method: "PATCH",
1421
+ body: JSON.stringify({ parentId: targetParentId })
1422
+ });
1423
+ postMessage("sybil:nexus:refresh");
1424
+ return response.folder;
1425
+ },
1426
+ renameFolder: async (folderId, newName) => {
1427
+ logger.log("info", "api", "Renaming folder", { folderId, newName });
1428
+ const response = await apiRequest(`/nexus/folders/${folderId}`, {
1429
+ method: "PATCH",
1430
+ body: JSON.stringify({ name: newName })
1431
+ });
1432
+ postMessage("sybil:nexus:refresh");
1433
+ return response.folder;
1434
+ },
1435
+ navigateTo: (folderId) => {
1436
+ currentFolderId = folderId;
1437
+ logger.log("info", "navigation", "Navigating to folder", { folderId });
1438
+ postMessage("sybil:nexus:navigate", { folderId });
1439
+ },
1440
+ getCurrentFolder: () => currentFolderId,
1441
+ getSelection: () => [...selectedItems],
1442
+ setSelection: (itemIds) => {
1443
+ logger.log("debug", "selection", "Setting selection", { count: itemIds.length });
1444
+ postMessage("sybil:nexus:setSelection", { itemIds });
1445
+ },
1446
+ clearSelection: () => {
1447
+ logger.log("debug", "selection", "Clearing selection");
1448
+ postMessage("sybil:nexus:clearSelection");
1449
+ },
1450
+ selectAll: () => {
1451
+ logger.log("debug", "selection", "Selecting all");
1452
+ postMessage("sybil:nexus:selectAll");
1453
+ },
1454
+ setViewMode: (mode) => {
1455
+ logger.log("debug", "ui", "Setting view mode", { mode });
1456
+ postMessage("sybil:nexus:setViewMode", { mode });
1457
+ },
1458
+ toggleActivityFeed: () => {
1459
+ logger.log("debug", "ui", "Toggling activity feed");
1460
+ postMessage("sybil:nexus:toggleActivity");
1461
+ },
1462
+ toggleSidebar: () => {
1463
+ logger.log("debug", "ui", "Toggling sidebar");
1464
+ postMessage("sybil:nexus:toggleSidebar");
1465
+ },
1466
+ refresh: async () => {
1467
+ logger.log("info", "ui", "Refreshing");
1468
+ postMessage("sybil:nexus:refresh");
1469
+ },
1470
+ search: async (query) => {
1471
+ logger.log("info", "api", "Searching", { query });
1472
+ const params2 = new URLSearchParams({ workspaceId, search: query });
1473
+ const response = await apiRequest(
1474
+ `/nexus/files?${params2.toString()}`
1475
+ );
1476
+ return response.files.map((f) => ({
1477
+ ...f,
1478
+ itemType: "file"
1479
+ }));
1480
+ },
1481
+ getStats: async () => {
1482
+ logger.log("info", "api", "Fetching stats");
1483
+ const response = await apiRequest(
1484
+ `/nexus/stats?workspaceId=${workspaceId}`
1485
+ );
1486
+ return response.stats;
1487
+ },
1488
+ getActivity: async (limit = 50) => {
1489
+ logger.log("info", "api", "Fetching activity", { limit });
1490
+ const response = await apiRequest(
1491
+ `/nexus/activity?workspaceId=${workspaceId}&limit=${limit}`
1492
+ );
1493
+ return response.activities;
1494
+ },
1495
+ getLabels: async () => {
1496
+ logger.log("info", "api", "Fetching labels");
1497
+ const response = await apiRequest(
1498
+ `/nexus/labels?workspaceId=${workspaceId}`
1499
+ );
1500
+ return response.labels;
1501
+ },
1502
+ applyLabel: async (itemIds, labelId) => {
1503
+ logger.log("info", "api", "Applying label", { count: itemIds.length, labelId });
1504
+ await apiRequest("/nexus/labels/apply", {
1505
+ method: "POST",
1506
+ body: JSON.stringify({ itemIds, labelId })
1507
+ });
1508
+ postMessage("sybil:nexus:refresh");
1509
+ },
1510
+ removeLabel: async (itemIds, labelId) => {
1511
+ logger.log("info", "api", "Removing label", { count: itemIds.length, labelId });
1512
+ await apiRequest("/nexus/labels/apply", {
1513
+ method: "DELETE",
1514
+ body: JSON.stringify({ itemIds, labelId })
1515
+ });
1516
+ postMessage("sybil:nexus:refresh");
1517
+ },
1518
+ setTheme: (newTheme) => {
1519
+ logger.log("debug", "ui", "Setting theme", { theme: newTheme });
1520
+ postMessage("sybil:nexus:setTheme", { theme: newTheme });
1521
+ },
1522
+ destroy: () => {
1523
+ logger.log("info", "ui", "Destroying Nexus embed");
1524
+ window.removeEventListener("message", handleMessage);
1525
+ iframe.remove();
1526
+ },
1527
+ getLogs: () => logger.getLogs(),
1528
+ clearLogs: () => logger.clearLogs()
1529
+ };
1530
+ return instance;
1531
+ }
1532
+ var NexusClient = class {
1533
+ constructor(config) {
1534
+ this.apiKey = config.apiKey;
1535
+ this.workspaceId = config.workspaceId;
1536
+ this.baseUrl = config.baseUrl || DEFAULT_BASE_URL3;
1537
+ this.logger = new NexusLogger(config.logging);
1538
+ }
1539
+ async request(endpoint, options = {}) {
1540
+ const url = `${this.baseUrl}/api/sdk/v1${endpoint}`;
1541
+ const startTime = Date.now();
1542
+ this.logger.log("debug", "api", `Request: ${options.method || "GET"} ${endpoint}`);
1543
+ const response = await fetch(url, {
1544
+ ...options,
1545
+ headers: {
1546
+ "x-api-key": this.apiKey,
1547
+ ...options.body instanceof FormData ? {} : { "Content-Type": "application/json" },
1548
+ ...options.headers
1549
+ }
1550
+ });
1551
+ const duration = Date.now() - startTime;
1552
+ if (!response.ok) {
1553
+ const errorData = await response.json().catch(() => ({}));
1554
+ this.logger.log("error", "api", `Request failed: ${endpoint}`, {
1555
+ status: response.status,
1556
+ error: errorData
1557
+ }, duration);
1558
+ throw new Error(errorData.error?.message || `Request failed with status ${response.status}`);
1559
+ }
1560
+ this.logger.log("debug", "api", `Response: ${endpoint}`, { status: response.status }, duration);
1561
+ return response.json();
1562
+ }
1563
+ async listFiles(folderId) {
1564
+ const params = new URLSearchParams({ workspaceId: this.workspaceId });
1565
+ if (folderId !== void 0) params.set("folderId", folderId || "null");
1566
+ const response = await this.request(`/nexus/files?${params.toString()}`);
1567
+ return response.files;
1568
+ }
1569
+ async listFolders(parentId) {
1570
+ const params = new URLSearchParams({ workspaceId: this.workspaceId });
1571
+ if (parentId !== void 0) params.set("parentId", parentId || "null");
1572
+ const response = await this.request(`/nexus/folders?${params.toString()}`);
1573
+ return response.folders;
1574
+ }
1575
+ async getFolderContents(folderId) {
1576
+ const params = new URLSearchParams({ workspaceId: this.workspaceId });
1577
+ if (folderId) params.set("folderId", folderId);
1578
+ return this.request(`/nexus/folders/contents?${params.toString()}`);
1579
+ }
1580
+ async getFile(fileId) {
1581
+ const response = await this.request(`/nexus/files/${fileId}`);
1582
+ return response.file;
1583
+ }
1584
+ async uploadFile(file, folderId) {
1585
+ const formData = new FormData();
1586
+ formData.append("file", file);
1587
+ formData.append("workspaceId", this.workspaceId);
1588
+ if (folderId) formData.append("folderId", folderId);
1589
+ const response = await fetch(`${this.baseUrl}/api/sdk/v1/nexus/upload`, {
1590
+ method: "POST",
1591
+ headers: { "x-api-key": this.apiKey },
1592
+ body: formData
1593
+ });
1594
+ if (!response.ok) throw new Error("Failed to upload file");
1595
+ const data = await response.json();
1596
+ return data.file;
1597
+ }
1598
+ async deleteFile(fileId) {
1599
+ await this.request(`/nexus/files/${fileId}`, { method: "DELETE" });
1600
+ }
1601
+ async createFolder(name, parentId) {
1602
+ const response = await this.request("/nexus/folders", {
1603
+ method: "POST",
1604
+ body: JSON.stringify({ workspaceId: this.workspaceId, name, parentId })
1605
+ });
1606
+ return response.folder;
1607
+ }
1608
+ async deleteFolder(folderId) {
1609
+ await this.request(`/nexus/folders/${folderId}`, { method: "DELETE" });
1610
+ }
1611
+ async getStats() {
1612
+ const response = await this.request(
1613
+ `/nexus/stats?workspaceId=${this.workspaceId}`
1614
+ );
1615
+ return response.stats;
1616
+ }
1617
+ async getActivity(limit = 50) {
1618
+ const response = await this.request(
1619
+ `/nexus/activity?workspaceId=${this.workspaceId}&limit=${limit}`
1620
+ );
1621
+ return response.activities;
1622
+ }
1623
+ getLogs() {
1624
+ return this.logger.getLogs();
1625
+ }
1626
+ clearLogs() {
1627
+ this.logger.clearLogs();
1628
+ }
1629
+ };
1630
+
1631
+ // src/react/SybilNexus.tsx
1632
+ var import_jsx_runtime3 = require("react/jsx-runtime");
1633
+ var SybilNexus = (0, import_react3.forwardRef)(function SybilNexus2({
1634
+ apiKey,
1635
+ workspaceId,
1636
+ baseUrl,
1637
+ theme = "dark",
1638
+ initialFolderId = null,
1639
+ viewMode = "list",
1640
+ showSidebar = true,
1641
+ showActivityFeed = true,
1642
+ showBreadcrumbs = true,
1643
+ showSearch = true,
1644
+ allowUpload = true,
1645
+ allowDownload = true,
1646
+ allowDelete = true,
1647
+ allowMove = true,
1648
+ allowRename = true,
1649
+ allowCreateFolder = true,
1650
+ allowMultiSelect = true,
1651
+ maxUploadSize,
1652
+ acceptedFileTypes,
1653
+ features,
1654
+ logging,
1655
+ className,
1656
+ style,
1657
+ onReady,
1658
+ onNavigate,
1659
+ onFileSelect,
1660
+ onFileOpen,
1661
+ onFileUpload,
1662
+ onFileDelete,
1663
+ onFolderCreate,
1664
+ onFolderDelete,
1665
+ onSelectionChange,
1666
+ onError
1667
+ }, ref) {
1668
+ const containerRef = (0, import_react3.useRef)(null);
1669
+ const instanceRef = (0, import_react3.useRef)(null);
1670
+ (0, import_react3.useImperativeHandle)(ref, () => ({
1671
+ getFiles: async (folderId) => {
1672
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1673
+ return instanceRef.current.getFiles(folderId);
1674
+ },
1675
+ getFolders: async (parentId) => {
1676
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1677
+ return instanceRef.current.getFolders(parentId);
1678
+ },
1679
+ getFolderContents: async (folderId) => {
1680
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1681
+ return instanceRef.current.getFolderContents(folderId);
1682
+ },
1683
+ getFolderTree: async () => {
1684
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1685
+ return instanceRef.current.getFolderTree();
1686
+ },
1687
+ getFile: async (fileId) => {
1688
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1689
+ return instanceRef.current.getFile(fileId);
1690
+ },
1691
+ getFolder: async (folderId) => {
1692
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1693
+ return instanceRef.current.getFolder(folderId);
1694
+ },
1695
+ uploadFile: async (file, folderId, onProgress) => {
1696
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1697
+ return instanceRef.current.uploadFile(file, folderId, onProgress);
1698
+ },
1699
+ uploadFiles: async (files, folderId, onProgress) => {
1700
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1701
+ return instanceRef.current.uploadFiles(files, folderId, onProgress);
1702
+ },
1703
+ downloadFile: async (fileId) => {
1704
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1705
+ return instanceRef.current.downloadFile(fileId);
1706
+ },
1707
+ getDownloadUrl: async (fileId) => {
1708
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1709
+ return instanceRef.current.getDownloadUrl(fileId);
1710
+ },
1711
+ deleteFile: async (fileId) => {
1712
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1713
+ return instanceRef.current.deleteFile(fileId);
1714
+ },
1715
+ deleteFiles: async (fileIds) => {
1716
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1717
+ return instanceRef.current.deleteFiles(fileIds);
1718
+ },
1719
+ moveFile: async (fileId, targetFolderId) => {
1720
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1721
+ return instanceRef.current.moveFile(fileId, targetFolderId);
1722
+ },
1723
+ renameFile: async (fileId, newName) => {
1724
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1725
+ return instanceRef.current.renameFile(fileId, newName);
1726
+ },
1727
+ starFile: async (fileId, starred) => {
1728
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1729
+ return instanceRef.current.starFile(fileId, starred);
1730
+ },
1731
+ createFolder: async (name, parentId, options) => {
1732
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1733
+ return instanceRef.current.createFolder(name, parentId, options);
1734
+ },
1735
+ deleteFolder: async (folderId) => {
1736
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1737
+ return instanceRef.current.deleteFolder(folderId);
1738
+ },
1739
+ moveFolder: async (folderId, targetParentId) => {
1740
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1741
+ return instanceRef.current.moveFolder(folderId, targetParentId);
1742
+ },
1743
+ renameFolder: async (folderId, newName) => {
1744
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1745
+ return instanceRef.current.renameFolder(folderId, newName);
1746
+ },
1747
+ navigateTo: (folderId) => {
1748
+ instanceRef.current?.navigateTo(folderId);
1749
+ },
1750
+ getCurrentFolder: () => {
1751
+ return instanceRef.current?.getCurrentFolder() || null;
1752
+ },
1753
+ getSelection: () => {
1754
+ return instanceRef.current?.getSelection() || [];
1755
+ },
1756
+ setSelection: (itemIds) => {
1757
+ instanceRef.current?.setSelection(itemIds);
1758
+ },
1759
+ clearSelection: () => {
1760
+ instanceRef.current?.clearSelection();
1761
+ },
1762
+ selectAll: () => {
1763
+ instanceRef.current?.selectAll();
1764
+ },
1765
+ setViewMode: (mode) => {
1766
+ instanceRef.current?.setViewMode(mode);
1767
+ },
1768
+ toggleActivityFeed: () => {
1769
+ instanceRef.current?.toggleActivityFeed();
1770
+ },
1771
+ toggleSidebar: () => {
1772
+ instanceRef.current?.toggleSidebar();
1773
+ },
1774
+ refresh: async () => {
1775
+ return instanceRef.current?.refresh();
1776
+ },
1777
+ search: async (query) => {
1778
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1779
+ return instanceRef.current.search(query);
1780
+ },
1781
+ getStats: async () => {
1782
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1783
+ return instanceRef.current.getStats();
1784
+ },
1785
+ getActivity: async (limit) => {
1786
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1787
+ return instanceRef.current.getActivity(limit);
1788
+ },
1789
+ getLabels: async () => {
1790
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1791
+ return instanceRef.current.getLabels();
1792
+ },
1793
+ applyLabel: async (itemIds, labelId) => {
1794
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1795
+ return instanceRef.current.applyLabel(itemIds, labelId);
1796
+ },
1797
+ removeLabel: async (itemIds, labelId) => {
1798
+ if (!instanceRef.current) throw new Error("Nexus not initialized");
1799
+ return instanceRef.current.removeLabel(itemIds, labelId);
1800
+ },
1801
+ setTheme: (newTheme) => {
1802
+ instanceRef.current?.setTheme(newTheme);
1803
+ },
1804
+ getLogs: () => {
1805
+ return instanceRef.current?.getLogs() || [];
1806
+ },
1807
+ clearLogs: () => {
1808
+ instanceRef.current?.clearLogs();
1809
+ }
1810
+ }));
1811
+ (0, import_react3.useEffect)(() => {
1812
+ if (!containerRef.current || !apiKey || !workspaceId) return;
1813
+ instanceRef.current?.destroy();
1814
+ const config = {
1815
+ apiKey,
1816
+ workspaceId,
1817
+ container: containerRef.current,
1818
+ baseUrl,
1819
+ theme,
1820
+ initialFolderId,
1821
+ viewMode,
1822
+ showSidebar,
1823
+ showActivityFeed,
1824
+ showBreadcrumbs,
1825
+ showSearch,
1826
+ allowUpload,
1827
+ allowDownload,
1828
+ allowDelete,
1829
+ allowMove,
1830
+ allowRename,
1831
+ allowCreateFolder,
1832
+ allowMultiSelect,
1833
+ maxUploadSize,
1834
+ acceptedFileTypes,
1835
+ features,
1836
+ logging,
1837
+ onReady,
1838
+ onNavigate,
1839
+ onFileSelect,
1840
+ onFileOpen,
1841
+ onFileUpload,
1842
+ onFileDelete,
1843
+ onFolderCreate,
1844
+ onFolderDelete,
1845
+ onSelectionChange,
1846
+ onError
1847
+ };
1848
+ instanceRef.current = embedNexus(config);
1849
+ return () => {
1850
+ instanceRef.current?.destroy();
1851
+ instanceRef.current = null;
1852
+ };
1853
+ }, [apiKey, workspaceId, baseUrl]);
1854
+ (0, import_react3.useEffect)(() => {
1855
+ instanceRef.current?.setTheme(theme);
1856
+ }, [theme]);
1857
+ (0, import_react3.useEffect)(() => {
1858
+ instanceRef.current?.setViewMode(viewMode);
1859
+ }, [viewMode]);
1860
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
1861
+ "div",
1862
+ {
1863
+ ref: containerRef,
1864
+ className,
1865
+ style: {
1866
+ width: "100%",
1867
+ height: "100%",
1868
+ minHeight: "500px",
1869
+ ...style
1870
+ }
1871
+ }
1872
+ );
1873
+ });
1874
+
440
1875
  // src/react/hooks.ts
441
- var import_react2 = require("react");
1876
+ var import_react4 = require("react");
442
1877
  function useSybilPages(options) {
443
1878
  const { apiKey, baseUrl } = options;
444
- const [page, setPage] = (0, import_react2.useState)(null);
445
- const [loading, setLoading] = (0, import_react2.useState)(false);
446
- const [saving, setSaving] = (0, import_react2.useState)(false);
447
- const [error, setError] = (0, import_react2.useState)(null);
448
- const sdkRef = (0, import_react2.useRef)(null);
449
- const pendingBlocksRef = (0, import_react2.useRef)(null);
450
- (0, import_react2.useEffect)(() => {
1879
+ const [page, setPage] = (0, import_react4.useState)(null);
1880
+ const [loading, setLoading] = (0, import_react4.useState)(false);
1881
+ const [saving, setSaving] = (0, import_react4.useState)(false);
1882
+ const [error, setError] = (0, import_react4.useState)(null);
1883
+ const sdkRef = (0, import_react4.useRef)(null);
1884
+ const pendingBlocksRef = (0, import_react4.useRef)(null);
1885
+ (0, import_react4.useEffect)(() => {
451
1886
  sdkRef.current = new SybilSDK({
452
1887
  apiKey,
453
1888
  baseUrl: baseUrl ? `${baseUrl}/api/sdk/v1` : void 0
454
1889
  });
455
1890
  }, [apiKey, baseUrl]);
456
- const fetchPage = (0, import_react2.useCallback)(async (pageId) => {
1891
+ const fetchPage = (0, import_react4.useCallback)(async (pageId) => {
457
1892
  if (!sdkRef.current) return;
458
1893
  setLoading(true);
459
1894
  setError(null);
@@ -466,7 +1901,7 @@ function useSybilPages(options) {
466
1901
  setLoading(false);
467
1902
  }
468
1903
  }, []);
469
- const createPage = (0, import_react2.useCallback)(async (params = {}) => {
1904
+ const createPage = (0, import_react4.useCallback)(async (params = {}) => {
470
1905
  if (!sdkRef.current) throw new Error("SDK not initialized");
471
1906
  setLoading(true);
472
1907
  setError(null);
@@ -482,7 +1917,7 @@ function useSybilPages(options) {
482
1917
  setLoading(false);
483
1918
  }
484
1919
  }, []);
485
- const updatePage = (0, import_react2.useCallback)(async (pageId, params) => {
1920
+ const updatePage = (0, import_react4.useCallback)(async (pageId, params) => {
486
1921
  if (!sdkRef.current) throw new Error("SDK not initialized");
487
1922
  setSaving(true);
488
1923
  setError(null);
@@ -498,7 +1933,7 @@ function useSybilPages(options) {
498
1933
  setSaving(false);
499
1934
  }
500
1935
  }, []);
501
- const deletePage = (0, import_react2.useCallback)(async (pageId) => {
1936
+ const deletePage = (0, import_react4.useCallback)(async (pageId) => {
502
1937
  if (!sdkRef.current) throw new Error("SDK not initialized");
503
1938
  setLoading(true);
504
1939
  setError(null);
@@ -513,11 +1948,11 @@ function useSybilPages(options) {
513
1948
  setLoading(false);
514
1949
  }
515
1950
  }, []);
516
- const setBlocks = (0, import_react2.useCallback)((blocks) => {
1951
+ const setBlocks = (0, import_react4.useCallback)((blocks) => {
517
1952
  pendingBlocksRef.current = blocks;
518
1953
  setPage((prev) => prev ? { ...prev, blocks } : null);
519
1954
  }, []);
520
- const save = (0, import_react2.useCallback)(async () => {
1955
+ const save = (0, import_react4.useCallback)(async () => {
521
1956
  if (!page || !sdkRef.current || !pendingBlocksRef.current) return;
522
1957
  await updatePage(page.id, { blocks: pendingBlocksRef.current });
523
1958
  pendingBlocksRef.current = null;
@@ -535,8 +1970,385 @@ function useSybilPages(options) {
535
1970
  save
536
1971
  };
537
1972
  }
1973
+
1974
+ // src/react/hooks/useAtlas.ts
1975
+ var import_react5 = require("react");
1976
+ function useAtlas(options) {
1977
+ const { apiKey, workspaceId, baseUrl, logging } = options;
1978
+ const [sidebar, setSidebar] = (0, import_react5.useState)(null);
1979
+ const [currentPage, setCurrentPage] = (0, import_react5.useState)(null);
1980
+ const [loading, setLoading] = (0, import_react5.useState)(false);
1981
+ const [saving, setSaving] = (0, import_react5.useState)(false);
1982
+ const [error, setError] = (0, import_react5.useState)(null);
1983
+ const clientRef = (0, import_react5.useRef)(null);
1984
+ (0, import_react5.useEffect)(() => {
1985
+ clientRef.current = new AtlasClient({
1986
+ apiKey,
1987
+ workspaceId,
1988
+ baseUrl,
1989
+ logging
1990
+ });
1991
+ }, [apiKey, workspaceId, baseUrl, logging]);
1992
+ const fetchSidebar = (0, import_react5.useCallback)(async () => {
1993
+ if (!clientRef.current) throw new Error("Client not initialized");
1994
+ setLoading(true);
1995
+ setError(null);
1996
+ try {
1997
+ const data = await clientRef.current.getSidebar();
1998
+ setSidebar(data);
1999
+ return data;
2000
+ } catch (err) {
2001
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch sidebar");
2002
+ setError(error2);
2003
+ throw error2;
2004
+ } finally {
2005
+ setLoading(false);
2006
+ }
2007
+ }, []);
2008
+ const fetchPage = (0, import_react5.useCallback)(async (pageId) => {
2009
+ if (!clientRef.current) throw new Error("Client not initialized");
2010
+ setLoading(true);
2011
+ setError(null);
2012
+ try {
2013
+ const page = await clientRef.current.getPage(pageId);
2014
+ setCurrentPage(page);
2015
+ return page;
2016
+ } catch (err) {
2017
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch page");
2018
+ setError(error2);
2019
+ throw error2;
2020
+ } finally {
2021
+ setLoading(false);
2022
+ }
2023
+ }, []);
2024
+ const createPage = (0, import_react5.useCallback)(async (params = {}) => {
2025
+ if (!clientRef.current) throw new Error("Client not initialized");
2026
+ setSaving(true);
2027
+ setError(null);
2028
+ try {
2029
+ const page = await clientRef.current.createPage(params);
2030
+ await fetchSidebar();
2031
+ return page;
2032
+ } catch (err) {
2033
+ const error2 = err instanceof Error ? err : new Error("Failed to create page");
2034
+ setError(error2);
2035
+ throw error2;
2036
+ } finally {
2037
+ setSaving(false);
2038
+ }
2039
+ }, [fetchSidebar]);
2040
+ const updatePage = (0, import_react5.useCallback)(async (pageId, params) => {
2041
+ if (!clientRef.current) throw new Error("Client not initialized");
2042
+ setSaving(true);
2043
+ setError(null);
2044
+ try {
2045
+ const page = await clientRef.current.updatePage(pageId, params);
2046
+ setCurrentPage(page);
2047
+ await fetchSidebar();
2048
+ return page;
2049
+ } catch (err) {
2050
+ const error2 = err instanceof Error ? err : new Error("Failed to update page");
2051
+ setError(error2);
2052
+ throw error2;
2053
+ } finally {
2054
+ setSaving(false);
2055
+ }
2056
+ }, [fetchSidebar]);
2057
+ const deletePage = (0, import_react5.useCallback)(async (pageId) => {
2058
+ if (!clientRef.current) throw new Error("Client not initialized");
2059
+ setSaving(true);
2060
+ setError(null);
2061
+ try {
2062
+ await clientRef.current.deletePage(pageId);
2063
+ if (currentPage?.id === pageId) {
2064
+ setCurrentPage(null);
2065
+ }
2066
+ await fetchSidebar();
2067
+ } catch (err) {
2068
+ const error2 = err instanceof Error ? err : new Error("Failed to delete page");
2069
+ setError(error2);
2070
+ throw error2;
2071
+ } finally {
2072
+ setSaving(false);
2073
+ }
2074
+ }, [currentPage, fetchSidebar]);
2075
+ const toggleFavorite = (0, import_react5.useCallback)(async (pageId) => {
2076
+ if (!clientRef.current) throw new Error("Client not initialized");
2077
+ try {
2078
+ const page = await clientRef.current.toggleFavorite(pageId);
2079
+ if (currentPage?.id === pageId) {
2080
+ setCurrentPage(page);
2081
+ }
2082
+ await fetchSidebar();
2083
+ return page;
2084
+ } catch (err) {
2085
+ const error2 = err instanceof Error ? err : new Error("Failed to toggle favorite");
2086
+ setError(error2);
2087
+ throw error2;
2088
+ }
2089
+ }, [currentPage, fetchSidebar]);
2090
+ const exportPage = (0, import_react5.useCallback)(async (pageId, format) => {
2091
+ if (!clientRef.current) throw new Error("Client not initialized");
2092
+ setLoading(true);
2093
+ try {
2094
+ return await clientRef.current.exportPage(pageId, format);
2095
+ } catch (err) {
2096
+ const error2 = err instanceof Error ? err : new Error("Failed to export page");
2097
+ setError(error2);
2098
+ throw error2;
2099
+ } finally {
2100
+ setLoading(false);
2101
+ }
2102
+ }, []);
2103
+ const getLogs = (0, import_react5.useCallback)(() => {
2104
+ return clientRef.current?.getLogs() || [];
2105
+ }, []);
2106
+ const clearLogs = (0, import_react5.useCallback)(() => {
2107
+ clientRef.current?.clearLogs();
2108
+ }, []);
2109
+ return {
2110
+ sidebar,
2111
+ currentPage,
2112
+ loading,
2113
+ saving,
2114
+ error,
2115
+ fetchSidebar,
2116
+ fetchPage,
2117
+ createPage,
2118
+ updatePage,
2119
+ deletePage,
2120
+ toggleFavorite,
2121
+ exportPage,
2122
+ setCurrentPage,
2123
+ getLogs,
2124
+ clearLogs
2125
+ };
2126
+ }
2127
+
2128
+ // src/react/hooks/useNexus.ts
2129
+ var import_react6 = require("react");
2130
+ function useNexus(options) {
2131
+ const { apiKey, workspaceId, baseUrl, logging } = options;
2132
+ const [files, setFiles] = (0, import_react6.useState)([]);
2133
+ const [folders, setFolders] = (0, import_react6.useState)([]);
2134
+ const [currentFolder, setCurrentFolder] = (0, import_react6.useState)(null);
2135
+ const [breadcrumb, setBreadcrumb] = (0, import_react6.useState)([]);
2136
+ const [loading, setLoading] = (0, import_react6.useState)(false);
2137
+ const [uploading, setUploading] = (0, import_react6.useState)(false);
2138
+ const [uploadProgress, setUploadProgress] = (0, import_react6.useState)(0);
2139
+ const [error, setError] = (0, import_react6.useState)(null);
2140
+ const clientRef = (0, import_react6.useRef)(null);
2141
+ (0, import_react6.useEffect)(() => {
2142
+ clientRef.current = new NexusClient({
2143
+ apiKey,
2144
+ workspaceId,
2145
+ baseUrl,
2146
+ logging
2147
+ });
2148
+ }, [apiKey, workspaceId, baseUrl, logging]);
2149
+ const fetchFiles = (0, import_react6.useCallback)(async (folderId) => {
2150
+ if (!clientRef.current) throw new Error("Client not initialized");
2151
+ setLoading(true);
2152
+ setError(null);
2153
+ try {
2154
+ const data = await clientRef.current.listFiles(folderId);
2155
+ setFiles(data);
2156
+ return data;
2157
+ } catch (err) {
2158
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch files");
2159
+ setError(error2);
2160
+ throw error2;
2161
+ } finally {
2162
+ setLoading(false);
2163
+ }
2164
+ }, []);
2165
+ const fetchFolders = (0, import_react6.useCallback)(async (parentId) => {
2166
+ if (!clientRef.current) throw new Error("Client not initialized");
2167
+ setLoading(true);
2168
+ setError(null);
2169
+ try {
2170
+ const data = await clientRef.current.listFolders(parentId);
2171
+ setFolders(data);
2172
+ return data;
2173
+ } catch (err) {
2174
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch folders");
2175
+ setError(error2);
2176
+ throw error2;
2177
+ } finally {
2178
+ setLoading(false);
2179
+ }
2180
+ }, []);
2181
+ const fetchFolderContents = (0, import_react6.useCallback)(async (folderId) => {
2182
+ if (!clientRef.current) throw new Error("Client not initialized");
2183
+ setLoading(true);
2184
+ setError(null);
2185
+ try {
2186
+ const data = await clientRef.current.getFolderContents(folderId);
2187
+ setBreadcrumb(data.breadcrumb);
2188
+ setCurrentFolder(folderId || null);
2189
+ return data;
2190
+ } catch (err) {
2191
+ const error2 = err instanceof Error ? err : new Error("Failed to fetch folder contents");
2192
+ setError(error2);
2193
+ throw error2;
2194
+ } finally {
2195
+ setLoading(false);
2196
+ }
2197
+ }, []);
2198
+ const getFile = (0, import_react6.useCallback)(async (fileId) => {
2199
+ if (!clientRef.current) throw new Error("Client not initialized");
2200
+ setLoading(true);
2201
+ setError(null);
2202
+ try {
2203
+ return await clientRef.current.getFile(fileId);
2204
+ } catch (err) {
2205
+ const error2 = err instanceof Error ? err : new Error("Failed to get file");
2206
+ setError(error2);
2207
+ throw error2;
2208
+ } finally {
2209
+ setLoading(false);
2210
+ }
2211
+ }, []);
2212
+ const uploadFile = (0, import_react6.useCallback)(async (file, folderId) => {
2213
+ if (!clientRef.current) throw new Error("Client not initialized");
2214
+ setUploading(true);
2215
+ setUploadProgress(0);
2216
+ setError(null);
2217
+ try {
2218
+ const result = await clientRef.current.uploadFile(file, folderId);
2219
+ await fetchFiles(folderId);
2220
+ return result;
2221
+ } catch (err) {
2222
+ const error2 = err instanceof Error ? err : new Error("Failed to upload file");
2223
+ setError(error2);
2224
+ throw error2;
2225
+ } finally {
2226
+ setUploading(false);
2227
+ setUploadProgress(0);
2228
+ }
2229
+ }, [fetchFiles]);
2230
+ const uploadFiles = (0, import_react6.useCallback)(async (filesToUpload, folderId) => {
2231
+ if (!clientRef.current) throw new Error("Client not initialized");
2232
+ setUploading(true);
2233
+ setUploadProgress(0);
2234
+ setError(null);
2235
+ const results = [];
2236
+ try {
2237
+ for (let i = 0; i < filesToUpload.length; i++) {
2238
+ const result = await clientRef.current.uploadFile(filesToUpload[i], folderId);
2239
+ results.push(result);
2240
+ setUploadProgress((i + 1) / filesToUpload.length * 100);
2241
+ }
2242
+ await fetchFiles(folderId);
2243
+ return results;
2244
+ } catch (err) {
2245
+ const error2 = err instanceof Error ? err : new Error("Failed to upload files");
2246
+ setError(error2);
2247
+ throw error2;
2248
+ } finally {
2249
+ setUploading(false);
2250
+ setUploadProgress(0);
2251
+ }
2252
+ }, [fetchFiles]);
2253
+ const deleteFile = (0, import_react6.useCallback)(async (fileId) => {
2254
+ if (!clientRef.current) throw new Error("Client not initialized");
2255
+ setLoading(true);
2256
+ setError(null);
2257
+ try {
2258
+ await clientRef.current.deleteFile(fileId);
2259
+ await fetchFiles(currentFolder);
2260
+ } catch (err) {
2261
+ const error2 = err instanceof Error ? err : new Error("Failed to delete file");
2262
+ setError(error2);
2263
+ throw error2;
2264
+ } finally {
2265
+ setLoading(false);
2266
+ }
2267
+ }, [currentFolder, fetchFiles]);
2268
+ const createFolder = (0, import_react6.useCallback)(async (name, parentId) => {
2269
+ if (!clientRef.current) throw new Error("Client not initialized");
2270
+ setLoading(true);
2271
+ setError(null);
2272
+ try {
2273
+ const result = await clientRef.current.createFolder(name, parentId);
2274
+ await fetchFolders(parentId);
2275
+ return result;
2276
+ } catch (err) {
2277
+ const error2 = err instanceof Error ? err : new Error("Failed to create folder");
2278
+ setError(error2);
2279
+ throw error2;
2280
+ } finally {
2281
+ setLoading(false);
2282
+ }
2283
+ }, [fetchFolders]);
2284
+ const deleteFolder = (0, import_react6.useCallback)(async (folderId) => {
2285
+ if (!clientRef.current) throw new Error("Client not initialized");
2286
+ setLoading(true);
2287
+ setError(null);
2288
+ try {
2289
+ await clientRef.current.deleteFolder(folderId);
2290
+ await fetchFolders(currentFolder);
2291
+ } catch (err) {
2292
+ const error2 = err instanceof Error ? err : new Error("Failed to delete folder");
2293
+ setError(error2);
2294
+ throw error2;
2295
+ } finally {
2296
+ setLoading(false);
2297
+ }
2298
+ }, [currentFolder, fetchFolders]);
2299
+ const navigateTo = (0, import_react6.useCallback)((folderId) => {
2300
+ setCurrentFolder(folderId);
2301
+ fetchFolderContents(folderId);
2302
+ }, [fetchFolderContents]);
2303
+ const getStats = (0, import_react6.useCallback)(async () => {
2304
+ if (!clientRef.current) throw new Error("Client not initialized");
2305
+ return clientRef.current.getStats();
2306
+ }, []);
2307
+ const getActivity = (0, import_react6.useCallback)(async (limit) => {
2308
+ if (!clientRef.current) throw new Error("Client not initialized");
2309
+ return clientRef.current.getActivity(limit);
2310
+ }, []);
2311
+ const refresh = (0, import_react6.useCallback)(async () => {
2312
+ await fetchFolderContents(currentFolder);
2313
+ }, [currentFolder, fetchFolderContents]);
2314
+ const getLogs = (0, import_react6.useCallback)(() => {
2315
+ return clientRef.current?.getLogs() || [];
2316
+ }, []);
2317
+ const clearLogs = (0, import_react6.useCallback)(() => {
2318
+ clientRef.current?.clearLogs();
2319
+ }, []);
2320
+ return {
2321
+ files,
2322
+ folders,
2323
+ currentFolder,
2324
+ breadcrumb,
2325
+ loading,
2326
+ uploading,
2327
+ uploadProgress,
2328
+ error,
2329
+ fetchFiles,
2330
+ fetchFolders,
2331
+ fetchFolderContents,
2332
+ getFile,
2333
+ uploadFile,
2334
+ uploadFiles,
2335
+ deleteFile,
2336
+ createFolder,
2337
+ deleteFolder,
2338
+ navigateTo,
2339
+ getStats,
2340
+ getActivity,
2341
+ refresh,
2342
+ getLogs,
2343
+ clearLogs
2344
+ };
2345
+ }
538
2346
  // Annotate the CommonJS export names for ESM import in node:
539
2347
  0 && (module.exports = {
2348
+ SybilAtlas,
2349
+ SybilNexus,
540
2350
  SybilPages,
2351
+ useAtlas,
2352
+ useNexus,
541
2353
  useSybilPages
542
2354
  });