@meechi-ai/core 1.0.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.
Files changed (116) hide show
  1. package/LICENSE +624 -0
  2. package/README.md +59 -0
  3. package/dist/components/CalendarView.d.ts +3 -0
  4. package/dist/components/CalendarView.js +72 -0
  5. package/dist/components/ChatInterface.d.ts +6 -0
  6. package/dist/components/ChatInterface.js +105 -0
  7. package/dist/components/FileExplorer.d.ts +9 -0
  8. package/dist/components/FileExplorer.js +757 -0
  9. package/dist/components/Icon.d.ts +9 -0
  10. package/dist/components/Icon.js +44 -0
  11. package/dist/components/SourceEditor.d.ts +13 -0
  12. package/dist/components/SourceEditor.js +50 -0
  13. package/dist/components/ThemeProvider.d.ts +5 -0
  14. package/dist/components/ThemeProvider.js +105 -0
  15. package/dist/components/ThemeSwitcher.d.ts +1 -0
  16. package/dist/components/ThemeSwitcher.js +16 -0
  17. package/dist/components/voice/VoiceInputArea.d.ts +14 -0
  18. package/dist/components/voice/VoiceInputArea.js +190 -0
  19. package/dist/components/voice/VoiceOverlay.d.ts +7 -0
  20. package/dist/components/voice/VoiceOverlay.js +71 -0
  21. package/dist/hooks/useMeechi.d.ts +16 -0
  22. package/dist/hooks/useMeechi.js +461 -0
  23. package/dist/hooks/useSync.d.ts +8 -0
  24. package/dist/hooks/useSync.js +87 -0
  25. package/dist/index.d.ts +14 -0
  26. package/dist/index.js +22 -0
  27. package/dist/lib/ai/embeddings.d.ts +15 -0
  28. package/dist/lib/ai/embeddings.js +128 -0
  29. package/dist/lib/ai/gpu-lock.d.ts +19 -0
  30. package/dist/lib/ai/gpu-lock.js +43 -0
  31. package/dist/lib/ai/llm.worker.d.ts +1 -0
  32. package/dist/lib/ai/llm.worker.js +7 -0
  33. package/dist/lib/ai/local-llm.d.ts +30 -0
  34. package/dist/lib/ai/local-llm.js +211 -0
  35. package/dist/lib/ai/manager.d.ts +20 -0
  36. package/dist/lib/ai/manager.js +51 -0
  37. package/dist/lib/ai/parsing.d.ts +12 -0
  38. package/dist/lib/ai/parsing.js +56 -0
  39. package/dist/lib/ai/prompts.d.ts +2 -0
  40. package/dist/lib/ai/prompts.js +2 -0
  41. package/dist/lib/ai/providers/gemini.d.ts +6 -0
  42. package/dist/lib/ai/providers/gemini.js +88 -0
  43. package/dist/lib/ai/providers/groq.d.ts +6 -0
  44. package/dist/lib/ai/providers/groq.js +42 -0
  45. package/dist/lib/ai/registry.d.ts +29 -0
  46. package/dist/lib/ai/registry.js +52 -0
  47. package/dist/lib/ai/tools.d.ts +2 -0
  48. package/dist/lib/ai/tools.js +106 -0
  49. package/dist/lib/ai/types.d.ts +22 -0
  50. package/dist/lib/ai/types.js +1 -0
  51. package/dist/lib/ai/worker.d.ts +1 -0
  52. package/dist/lib/ai/worker.js +60 -0
  53. package/dist/lib/audio/input.d.ts +13 -0
  54. package/dist/lib/audio/input.js +121 -0
  55. package/dist/lib/audio/stt.d.ts +13 -0
  56. package/dist/lib/audio/stt.js +119 -0
  57. package/dist/lib/audio/tts.d.ts +12 -0
  58. package/dist/lib/audio/tts.js +128 -0
  59. package/dist/lib/audio/vad.d.ts +18 -0
  60. package/dist/lib/audio/vad.js +117 -0
  61. package/dist/lib/colors.d.ts +16 -0
  62. package/dist/lib/colors.js +67 -0
  63. package/dist/lib/extensions.d.ts +35 -0
  64. package/dist/lib/extensions.js +24 -0
  65. package/dist/lib/hooks/use-voice-loop.d.ts +13 -0
  66. package/dist/lib/hooks/use-voice-loop.js +313 -0
  67. package/dist/lib/mcp/McpClient.d.ts +19 -0
  68. package/dist/lib/mcp/McpClient.js +42 -0
  69. package/dist/lib/mcp/McpRegistry.d.ts +47 -0
  70. package/dist/lib/mcp/McpRegistry.js +117 -0
  71. package/dist/lib/mcp/native/GroqVoiceNative.d.ts +21 -0
  72. package/dist/lib/mcp/native/GroqVoiceNative.js +29 -0
  73. package/dist/lib/mcp/native/LocalSyncNative.d.ts +19 -0
  74. package/dist/lib/mcp/native/LocalSyncNative.js +26 -0
  75. package/dist/lib/mcp/native/LocalVoiceNative.d.ts +19 -0
  76. package/dist/lib/mcp/native/LocalVoiceNative.js +27 -0
  77. package/dist/lib/mcp/native/MeechiNativeCore.d.ts +25 -0
  78. package/dist/lib/mcp/native/MeechiNativeCore.js +209 -0
  79. package/dist/lib/mcp/native/index.d.ts +10 -0
  80. package/dist/lib/mcp/native/index.js +10 -0
  81. package/dist/lib/mcp/types.d.ts +35 -0
  82. package/dist/lib/mcp/types.js +1 -0
  83. package/dist/lib/pdf.d.ts +10 -0
  84. package/dist/lib/pdf.js +142 -0
  85. package/dist/lib/settings.d.ts +48 -0
  86. package/dist/lib/settings.js +87 -0
  87. package/dist/lib/storage/db.d.ts +57 -0
  88. package/dist/lib/storage/db.js +45 -0
  89. package/dist/lib/storage/local.d.ts +28 -0
  90. package/dist/lib/storage/local.js +534 -0
  91. package/dist/lib/storage/migrate.d.ts +3 -0
  92. package/dist/lib/storage/migrate.js +122 -0
  93. package/dist/lib/storage/types.d.ts +66 -0
  94. package/dist/lib/storage/types.js +1 -0
  95. package/dist/lib/sync/client-drive.d.ts +9 -0
  96. package/dist/lib/sync/client-drive.js +69 -0
  97. package/dist/lib/sync/engine.d.ts +18 -0
  98. package/dist/lib/sync/engine.js +517 -0
  99. package/dist/lib/sync/google-drive.d.ts +52 -0
  100. package/dist/lib/sync/google-drive.js +183 -0
  101. package/dist/lib/sync/merge.d.ts +1 -0
  102. package/dist/lib/sync/merge.js +68 -0
  103. package/dist/lib/yjs/YjsProvider.d.ts +11 -0
  104. package/dist/lib/yjs/YjsProvider.js +33 -0
  105. package/dist/lib/yjs/graph.d.ts +11 -0
  106. package/dist/lib/yjs/graph.js +7 -0
  107. package/dist/lib/yjs/hooks.d.ts +7 -0
  108. package/dist/lib/yjs/hooks.js +37 -0
  109. package/dist/lib/yjs/store.d.ts +4 -0
  110. package/dist/lib/yjs/store.js +19 -0
  111. package/dist/lib/yjs/syncGraph.d.ts +1 -0
  112. package/dist/lib/yjs/syncGraph.js +38 -0
  113. package/dist/providers/theme-provider.d.ts +3 -0
  114. package/dist/providers/theme-provider.js +18 -0
  115. package/dist/tsconfig.lib.tsbuildinfo +1 -0
  116. package/package.json +69 -0
@@ -0,0 +1,183 @@
1
+ export class GoogleDriveClient {
2
+ constructor(accessToken) {
3
+ this.accessToken = accessToken;
4
+ }
5
+ async request(endpoint, options = {}) {
6
+ var _a;
7
+ const url = `https://www.googleapis.com/drive/v3/${endpoint}`;
8
+ const headers = Object.assign({ 'Authorization': `Bearer ${this.accessToken}`, 'Content-Type': 'application/json' }, (options.headers || {}));
9
+ console.log(`[DriveAPI] ${options.method || 'GET'} ${url}`);
10
+ const controller = new AbortController();
11
+ const id = setTimeout(() => controller.abort(), 30000); // 30s Timeout
12
+ try {
13
+ const res = await fetch(url, Object.assign(Object.assign({}, options), { headers, signal: controller.signal }));
14
+ clearTimeout(id);
15
+ if (res.status === 401) {
16
+ console.error(`[DriveAPI] 401 Unauthorized for ${url}`);
17
+ throw new Error("Unauthorized: Token expired or invalid");
18
+ }
19
+ if (!res.ok) {
20
+ const err = await res.json().catch(() => ({}));
21
+ console.error(`[DriveAPI] Error ${res.status} for ${url}:`, err);
22
+ throw new Error(`Drive API Error: ${((_a = err.error) === null || _a === void 0 ? void 0 : _a.message) || res.statusText}`);
23
+ }
24
+ return res;
25
+ }
26
+ catch (error) {
27
+ clearTimeout(id);
28
+ if (error.name === 'AbortError') {
29
+ console.error(`[DriveAPI] Timeout for ${url}`);
30
+ throw new Error("Drive API Timeout (30s)");
31
+ }
32
+ console.error(`[DriveAPI] Fetch Error for ${url}:`, error);
33
+ throw error;
34
+ }
35
+ }
36
+ /**
37
+ * Search for files.
38
+ * query: e.g. "name = 'foo.txt' and trashed = false"
39
+ */
40
+ async listFiles(query) {
41
+ const params = new URLSearchParams({
42
+ q: query,
43
+ fields: 'files(id, name, mimeType, parents, modifiedTime, version, trashed, capabilities, appProperties)',
44
+ pageSize: '1000',
45
+ });
46
+ const res = await this.request(`files?${params.toString()}`);
47
+ return (await res.json()).files;
48
+ }
49
+ /**
50
+ * Get Sync Token for tracking changes
51
+ */
52
+ async getStartPageToken() {
53
+ const res = await this.request('changes/startPageToken');
54
+ return (await res.json()).startPageToken;
55
+ }
56
+ /**
57
+ * List changes since token
58
+ */
59
+ async listChanges(pageToken) {
60
+ const params = new URLSearchParams({
61
+ pageToken,
62
+ fields: 'nextPageToken, newStartPageToken, changes(fileId, removed, file(id, name, mimeType, parents, modifiedTime, version, trashed, appProperties))',
63
+ });
64
+ const res = await this.request(`changes?${params.toString()}`);
65
+ return await res.json();
66
+ }
67
+ /**
68
+ * Download file content
69
+ */
70
+ async downloadFile(fileId) {
71
+ const res = await this.request(`files/${fileId}?alt=media`);
72
+ return await res.text();
73
+ }
74
+ /**
75
+ * Download file content as Binary (ArrayBuffer)
76
+ */
77
+ async downloadBinary(fileId) {
78
+ const res = await this.request(`files/${fileId}?alt=media`);
79
+ return await res.arrayBuffer();
80
+ }
81
+ /**
82
+ * Get file metadata
83
+ */
84
+ async getFileMetadata(fileId) {
85
+ const res = await this.request(`files/${fileId}?fields=id,name,parents,mimeType,modifiedTime,trashed,appProperties`);
86
+ return await res.json();
87
+ }
88
+ /**
89
+ * Update file content
90
+ */
91
+ async updateMetadata(fileId, metadata) {
92
+ const url = new URL(`https://www.googleapis.com/drive/v3/files/${fileId}`);
93
+ if (metadata.addParents)
94
+ url.searchParams.append('addParents', metadata.addParents.join(','));
95
+ if (metadata.removeParents)
96
+ url.searchParams.append('removeParents', metadata.removeParents.join(',')); // Important: remove old parents for move
97
+ const body = {};
98
+ if (metadata.name)
99
+ body.name = metadata.name;
100
+ if (metadata.appProperties)
101
+ body.appProperties = metadata.appProperties;
102
+ const res = await this.request(url.toString().replace('https://www.googleapis.com/drive/v3/', ''), {
103
+ method: 'PATCH',
104
+ body: JSON.stringify(body)
105
+ });
106
+ return await res.json();
107
+ }
108
+ async updateFile(fileId, content) {
109
+ // Simple upload (media only) is easiest for updates, but multipart is robust.
110
+ // For updates, we often just want to update content.
111
+ // Google Drive API supports PATCHing content.
112
+ // Ref: https://developers.google.com/drive/api/guides/manage-uploads#simple
113
+ const blob = content instanceof Blob ? content : new Blob([content]);
114
+ const res = await fetch(`https://www.googleapis.com/upload/drive/v3/files/${fileId}?uploadType=media`, {
115
+ method: 'PATCH',
116
+ headers: {
117
+ 'Authorization': `Bearer ${this.accessToken}`,
118
+ 'Content-Type': blob.type || 'application/octet-stream'
119
+ },
120
+ body: blob
121
+ });
122
+ if (!res.ok)
123
+ throw new Error("Update content failed");
124
+ return await res.json();
125
+ }
126
+ /**
127
+ * Create file
128
+ */
129
+ async createFile(name, folderId, content, appProperties) {
130
+ let mimeType = 'application/octet-stream';
131
+ if (name.endsWith('.md'))
132
+ mimeType = 'text/markdown';
133
+ else if (name.endsWith('.txt'))
134
+ mimeType = 'text/plain';
135
+ else if (name.endsWith('.pdf'))
136
+ mimeType = 'application/pdf';
137
+ const blob = content instanceof Blob ? content : new Blob([content], { type: mimeType });
138
+ const metadata = {
139
+ name,
140
+ parents: folderId ? [folderId] : [],
141
+ };
142
+ if (appProperties)
143
+ metadata.appProperties = appProperties;
144
+ const form = new FormData();
145
+ form.append('metadata', new Blob([JSON.stringify(metadata)], { type: 'application/json' }));
146
+ form.append('file', blob);
147
+ const res = await fetch('https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart', {
148
+ method: 'POST',
149
+ headers: {
150
+ 'Authorization': `Bearer ${this.accessToken}`,
151
+ },
152
+ body: form
153
+ });
154
+ if (!res.ok)
155
+ throw new Error("Create failed");
156
+ return await res.json();
157
+ }
158
+ /**
159
+ * Create Folder
160
+ */
161
+ async createFolder(name, parentId) {
162
+ const metadata = {
163
+ name,
164
+ mimeType: 'application/vnd.google-apps.folder',
165
+ parents: parentId ? [parentId] : []
166
+ };
167
+ const res = await this.request('files', {
168
+ method: 'POST',
169
+ body: JSON.stringify(metadata)
170
+ });
171
+ return await res.json();
172
+ }
173
+ /**
174
+ * Delete file (Trash)
175
+ */
176
+ async deleteFile(fileId) {
177
+ const res = await this.request(`files/${fileId}`, {
178
+ method: 'DELETE'
179
+ });
180
+ if (!res.ok)
181
+ throw new Error("Delete failed");
182
+ }
183
+ }
@@ -0,0 +1 @@
1
+ export declare function mergeLogs(local: string, remote: string): string;
@@ -0,0 +1,68 @@
1
+ export function mergeLogs(local, remote) {
2
+ const localEntries = parseEntries(local);
3
+ const remoteEntries = parseEntries(remote);
4
+ // Merge map: Key = "Timestamp|ContentHash" -> Entry
5
+ const merged = new Map();
6
+ // Add Remote first (Truth)
7
+ remoteEntries.forEach(entry => {
8
+ const key = generateKey(entry);
9
+ merged.set(key, entry.fullText);
10
+ });
11
+ // Add Local (Append/Fill gaps)
12
+ localEntries.forEach(entry => {
13
+ const key = generateKey(entry);
14
+ if (!merged.has(key)) {
15
+ merged.set(key, entry.fullText);
16
+ }
17
+ });
18
+ // Sort by Timestamp
19
+ const sortedEntries = Array.from(merged.values()).sort((a, b) => {
20
+ const timeA = extractDate(a);
21
+ const timeB = extractDate(b);
22
+ return timeA.getTime() - timeB.getTime();
23
+ });
24
+ return sortedEntries.join('\n\n');
25
+ }
26
+ // Helpers
27
+ function parseEntries(log) {
28
+ if (!log)
29
+ return [];
30
+ return log.split('### ').filter(c => c.trim()).map(chunk => {
31
+ // Re-add delimiter for reconstruction
32
+ const fullText = '### ' + chunk.trim();
33
+ const lines = chunk.split('\n');
34
+ // Timestamp is the first line after ###
35
+ const timestampStr = lines[0].trim();
36
+ // We assume today's date for sorting relative to each other (since files are per day)
37
+ // Ideally we'd parse the full date if available, but time string works for daily logs
38
+ return {
39
+ timestampStr,
40
+ fullText
41
+ };
42
+ });
43
+ }
44
+ function generateKey(entry) {
45
+ // Simple key: Time + First 20 chars of content (to distinguish different messages at same second)
46
+ const contentSignature = entry.fullText.replace(/\s/g, '').slice(0, 50);
47
+ return `${entry.timestampStr}|${contentSignature}`;
48
+ }
49
+ function extractDate(entryText) {
50
+ // Extract "12:00:00 PM"
51
+ const match = entryText.match(/### (.*?)(\n|$)/);
52
+ if (!match)
53
+ return new Date(0);
54
+ const timeStr = match[1];
55
+ // Parse Time String (assuming today context, but really we just need relative sort)
56
+ // "12:00:00 PM" -> Date
57
+ const d = new Date();
58
+ const [time, period] = timeStr.split(' ');
59
+ if (!time)
60
+ return new Date(0);
61
+ let [hours, minutes, seconds] = time.split(':').map(Number);
62
+ if (period === 'PM' && hours !== 12)
63
+ hours += 12;
64
+ if (period === 'AM' && hours === 12)
65
+ hours = 0;
66
+ d.setHours(hours || 0, minutes || 0, seconds || 0);
67
+ return d;
68
+ }
@@ -0,0 +1,11 @@
1
+ import React from 'react';
2
+ import * as Y from 'yjs';
3
+ interface YjsContextType {
4
+ doc: Y.Doc;
5
+ synced: boolean;
6
+ }
7
+ export declare function YjsProvider({ children }: {
8
+ children: React.ReactNode;
9
+ }): import("react/jsx-runtime").JSX.Element;
10
+ export declare const useYjs: () => YjsContextType;
11
+ export {};
@@ -0,0 +1,33 @@
1
+ 'use client';
2
+ import { jsx as _jsx } from "react/jsx-runtime";
3
+ import { createContext, useContext, useEffect, useState } from 'react';
4
+ import { doc, yProvider } from './store';
5
+ const YjsContext = createContext({
6
+ doc,
7
+ synced: false,
8
+ });
9
+ export function YjsProvider({ children }) {
10
+ const [synced, setSynced] = useState(false);
11
+ useEffect(() => {
12
+ if (!yProvider) {
13
+ // Server-side or non-browser environment
14
+ setSynced(true);
15
+ return;
16
+ }
17
+ const onSynced = () => setSynced(true);
18
+ // Check if already synced
19
+ if (yProvider.synced) {
20
+ setSynced(true);
21
+ }
22
+ else {
23
+ yProvider.on('synced', onSynced);
24
+ }
25
+ return () => {
26
+ if (yProvider) {
27
+ yProvider.off('synced', onSynced);
28
+ }
29
+ };
30
+ }, []);
31
+ return (_jsx(YjsContext.Provider, { value: { doc, synced }, children: children }));
32
+ }
33
+ export const useYjs = () => useContext(YjsContext);
@@ -0,0 +1,11 @@
1
+ import * as Y from 'yjs';
2
+ export interface GraphEdge {
3
+ id: string;
4
+ source: string;
5
+ target: string;
6
+ relation: string;
7
+ weight?: number;
8
+ createdAt: number;
9
+ metadata?: any;
10
+ }
11
+ export declare const getEdgesMap: () => Y.Map<GraphEdge>;
@@ -0,0 +1,7 @@
1
+ import { doc } from './store';
2
+ // Access the Y.Map for edges
3
+ // Key: Edge ID (UUID)
4
+ // Value: GraphEdge object
5
+ export const getEdgesMap = () => {
6
+ return doc.getMap('graph-edges');
7
+ };
@@ -0,0 +1,7 @@
1
+ import * as Y from 'yjs';
2
+ export declare function useYDoc(): {
3
+ doc: Y.Doc;
4
+ synced: boolean;
5
+ };
6
+ export declare function useYMap<T>(name: string): [Y.Map<T>, T];
7
+ export declare function useYArray<T>(name: string): [Y.Array<T>, T[]];
@@ -0,0 +1,37 @@
1
+ 'use client';
2
+ import { useState, useEffect } from 'react';
3
+ import { useYjs } from './YjsProvider';
4
+ export function useYDoc() {
5
+ const { doc, synced } = useYjs();
6
+ return { doc, synced };
7
+ }
8
+ export function useYMap(name) {
9
+ const { doc } = useYjs();
10
+ const map = doc.getMap(name);
11
+ const [toJSON, setToJSON] = useState(map.toJSON());
12
+ useEffect(() => {
13
+ const onChange = () => {
14
+ setToJSON(map.toJSON());
15
+ };
16
+ map.observe(onChange);
17
+ return () => {
18
+ map.unobserve(onChange);
19
+ };
20
+ }, [map]);
21
+ return [map, toJSON];
22
+ }
23
+ export function useYArray(name) {
24
+ const { doc } = useYjs();
25
+ const array = doc.getArray(name);
26
+ const [toJSON, setToJSON] = useState(array.toArray());
27
+ useEffect(() => {
28
+ const onChange = () => {
29
+ setToJSON(array.toArray());
30
+ };
31
+ array.observe(onChange);
32
+ return () => {
33
+ array.unobserve(onChange);
34
+ };
35
+ }, [array]);
36
+ return [array, toJSON];
37
+ }
@@ -0,0 +1,4 @@
1
+ import * as Y from 'yjs';
2
+ import { IndexeddbPersistence } from 'y-indexeddb';
3
+ export declare const doc: Y.Doc;
4
+ export declare const yProvider: IndexeddbPersistence | null;
@@ -0,0 +1,19 @@
1
+ import * as Y from 'yjs';
2
+ import { IndexeddbPersistence } from 'y-indexeddb';
3
+ // Create the global Yjs document
4
+ export const doc = new Y.Doc();
5
+ // Initialize the persistence layer (Browser only)
6
+ let persistence = null;
7
+ if (typeof window !== 'undefined') {
8
+ // 'meechi-database' matches our app name logic, but distinct from Dexie which is 'meechi-db' usually
9
+ persistence = new IndexeddbPersistence('meechi-yjs-store', doc);
10
+ persistence.on('synced', () => {
11
+ console.log('[Yjs] Content loaded from IndexedDB');
12
+ });
13
+ // Initialize Graph Sync (Yjs -> Dexie)
14
+ // We do this here to ensure it runs as a side-effect of the app starting
15
+ import('./syncGraph').then(({ initGraphSync }) => {
16
+ initGraphSync();
17
+ });
18
+ }
19
+ export const yProvider = persistence;
@@ -0,0 +1 @@
1
+ export declare function initGraphSync(): void;
@@ -0,0 +1,38 @@
1
+ import { db } from '../storage/db';
2
+ import { getEdgesMap } from './graph';
3
+ // Sync Yjs Graph Edges -> Dexie 'edges' table
4
+ // This allows us to use Dexie for fast GraphRAG querying (e.g. "Find all neighbors of Ada")
5
+ // while keeping Yjs as the source of truth for sync.
6
+ export function initGraphSync() {
7
+ console.log('[GraphSync] Initializing...');
8
+ const edgesMap = getEdgesMap();
9
+ // 1. Initial Sync: Ensure specific indexes match if needed, or just rely on eventual consistency.
10
+ // For now, we trust the observe events or a full re-sync if strictly needed.
11
+ // Ideally, Yjs persistence loads the doc, and then we might want to dump to Dexie if Dexie is empty.
12
+ // But since Yjs persistence goes to IndexedDB anyway, this is "Derived Data".
13
+ // We observe changes.
14
+ edgesMap.observe((event) => {
15
+ // event.keysChanged is a Set of keys (Edge IDs) that changed
16
+ const changes = Array.from(event.keysChanged);
17
+ db.transaction('rw', db.edges, async () => {
18
+ for (const key of changes) {
19
+ const type = event.changes.keys.get(key);
20
+ // type.action is 'add', 'update', or 'delete'
21
+ if ((type === null || type === void 0 ? void 0 : type.action) === 'delete') {
22
+ // Deleted from Yjs -> Delete from Dexie
23
+ await db.edges.delete(key);
24
+ }
25
+ else {
26
+ // Added or Updated -> Put to Dexie
27
+ const edge = edgesMap.get(key);
28
+ if (edge) {
29
+ await db.edges.put(edge);
30
+ }
31
+ }
32
+ }
33
+ }).catch(err => {
34
+ console.error('[GraphSync] Error syncing to Dexie:', err);
35
+ });
36
+ });
37
+ console.log('[GraphSync] Listening for changes.');
38
+ }
@@ -0,0 +1,3 @@
1
+ import * as React from "react";
2
+ import { ThemeProvider as NextThemesProvider } from "next-themes";
3
+ export declare function ThemeProvider({ children, ...props }: React.ComponentProps<typeof NextThemesProvider>): import("react/jsx-runtime").JSX.Element;
@@ -0,0 +1,18 @@
1
+ "use client";
2
+ var __rest = (this && this.__rest) || function (s, e) {
3
+ var t = {};
4
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
5
+ t[p] = s[p];
6
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
7
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
8
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
9
+ t[p[i]] = s[p[i]];
10
+ }
11
+ return t;
12
+ };
13
+ import { jsx as _jsx } from "react/jsx-runtime";
14
+ import { ThemeProvider as NextThemesProvider } from "next-themes";
15
+ export function ThemeProvider(_a) {
16
+ var { children } = _a, props = __rest(_a, ["children"]);
17
+ return _jsx(NextThemesProvider, Object.assign({}, props, { children: children }));
18
+ }