@agent-native/core 0.2.3 → 0.2.7-dev.712fefc

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 (109) hide show
  1. package/README.md +122 -0
  2. package/dist/adapters/firestore/adapter.d.ts +47 -0
  3. package/dist/adapters/firestore/adapter.d.ts.map +1 -0
  4. package/dist/adapters/firestore/adapter.js +45 -0
  5. package/dist/adapters/firestore/adapter.js.map +1 -0
  6. package/dist/adapters/firestore/index.d.ts +3 -3
  7. package/dist/adapters/firestore/index.d.ts.map +1 -1
  8. package/dist/adapters/firestore/index.js +2 -3
  9. package/dist/adapters/firestore/index.js.map +1 -1
  10. package/dist/adapters/neon/adapter.d.ts +28 -0
  11. package/dist/adapters/neon/adapter.d.ts.map +1 -0
  12. package/dist/adapters/neon/adapter.js +119 -0
  13. package/dist/adapters/neon/adapter.js.map +1 -0
  14. package/dist/adapters/neon/index.d.ts +3 -0
  15. package/dist/adapters/neon/index.d.ts.map +1 -0
  16. package/dist/adapters/neon/index.js +3 -0
  17. package/dist/adapters/neon/index.js.map +1 -0
  18. package/dist/adapters/supabase/adapter.d.ts +42 -0
  19. package/dist/adapters/supabase/adapter.d.ts.map +1 -0
  20. package/dist/adapters/supabase/adapter.js +126 -0
  21. package/dist/adapters/supabase/adapter.js.map +1 -0
  22. package/dist/adapters/supabase/index.d.ts +3 -0
  23. package/dist/adapters/supabase/index.d.ts.map +1 -0
  24. package/dist/adapters/supabase/index.js +3 -0
  25. package/dist/adapters/supabase/index.js.map +1 -0
  26. package/dist/adapters/{firestore → sync}/config.d.ts +1 -1
  27. package/dist/adapters/sync/config.d.ts.map +1 -0
  28. package/dist/adapters/{firestore → sync}/config.js +1 -1
  29. package/dist/adapters/sync/config.js.map +1 -0
  30. package/dist/adapters/{firestore/sync.d.ts → sync/file-sync.d.ts} +6 -37
  31. package/dist/adapters/sync/file-sync.d.ts.map +1 -0
  32. package/dist/adapters/{firestore/sync.js → sync/file-sync.js} +45 -59
  33. package/dist/adapters/sync/file-sync.js.map +1 -0
  34. package/dist/adapters/sync/index.d.ts +5 -0
  35. package/dist/adapters/sync/index.d.ts.map +1 -0
  36. package/dist/adapters/sync/index.js +4 -0
  37. package/dist/adapters/sync/index.js.map +1 -0
  38. package/dist/adapters/sync/merge.d.ts.map +1 -0
  39. package/dist/adapters/sync/merge.js.map +1 -0
  40. package/dist/adapters/sync/types.d.ts +28 -0
  41. package/dist/adapters/sync/types.d.ts.map +1 -0
  42. package/dist/adapters/sync/types.js +2 -0
  43. package/dist/adapters/sync/types.js.map +1 -0
  44. package/dist/cli/create.d.ts.map +1 -1
  45. package/dist/cli/create.js +41 -3
  46. package/dist/cli/create.js.map +1 -1
  47. package/dist/cli/index.js +12 -9
  48. package/dist/cli/index.js.map +1 -1
  49. package/dist/client/components/ApiKeySettings.d.ts +12 -0
  50. package/dist/client/components/ApiKeySettings.d.ts.map +1 -0
  51. package/dist/client/components/ApiKeySettings.js +203 -0
  52. package/dist/client/components/ApiKeySettings.js.map +1 -0
  53. package/dist/client/components/MissingKeyCard.d.ts +7 -0
  54. package/dist/client/components/MissingKeyCard.d.ts.map +1 -0
  55. package/dist/client/components/MissingKeyCard.js +27 -0
  56. package/dist/client/components/MissingKeyCard.js.map +1 -0
  57. package/dist/client/index.d.ts +1 -0
  58. package/dist/client/index.d.ts.map +1 -1
  59. package/dist/client/index.js +1 -0
  60. package/dist/client/index.js.map +1 -1
  61. package/dist/client/use-file-watcher.d.ts.map +1 -1
  62. package/dist/client/use-file-watcher.js +24 -14
  63. package/dist/client/use-file-watcher.js.map +1 -1
  64. package/dist/index.browser.d.ts +1 -1
  65. package/dist/index.browser.d.ts.map +1 -1
  66. package/dist/index.browser.js +1 -1
  67. package/dist/index.browser.js.map +1 -1
  68. package/dist/index.d.ts +1 -1
  69. package/dist/index.d.ts.map +1 -1
  70. package/dist/index.js +1 -1
  71. package/dist/index.js.map +1 -1
  72. package/dist/scripts/runner.js +1 -1
  73. package/dist/scripts/runner.js.map +1 -1
  74. package/dist/server/create-server.d.ts +11 -0
  75. package/dist/server/create-server.d.ts.map +1 -1
  76. package/dist/server/create-server.js +102 -0
  77. package/dist/server/create-server.js.map +1 -1
  78. package/dist/server/index.d.ts +2 -1
  79. package/dist/server/index.d.ts.map +1 -1
  80. package/dist/server/index.js +1 -0
  81. package/dist/server/index.js.map +1 -1
  82. package/dist/server/missing-key.d.ts +17 -0
  83. package/dist/server/missing-key.d.ts.map +1 -0
  84. package/dist/server/missing-key.js +17 -0
  85. package/dist/server/missing-key.js.map +1 -0
  86. package/dist/shared/agent-env.d.ts +23 -0
  87. package/dist/shared/agent-env.d.ts.map +1 -0
  88. package/dist/shared/agent-env.js +36 -0
  89. package/dist/shared/agent-env.js.map +1 -0
  90. package/dist/shared/index.d.ts +1 -0
  91. package/dist/shared/index.d.ts.map +1 -1
  92. package/dist/shared/index.js +1 -0
  93. package/dist/shared/index.js.map +1 -1
  94. package/dist/vite/client.d.ts.map +1 -1
  95. package/dist/vite/client.js +31 -0
  96. package/dist/vite/client.js.map +1 -1
  97. package/package.json +24 -3
  98. package/src/templates/default/.claude/settings.json +68 -0
  99. package/src/templates/default/AGENTS.md +4 -0
  100. package/src/templates/default/data/.gitkeep +0 -0
  101. package/src/templates/default/learnings.md +0 -0
  102. package/dist/adapters/firestore/config.d.ts.map +0 -1
  103. package/dist/adapters/firestore/config.js.map +0 -1
  104. package/dist/adapters/firestore/merge.d.ts.map +0 -1
  105. package/dist/adapters/firestore/merge.js.map +0 -1
  106. package/dist/adapters/firestore/sync.d.ts.map +0 -1
  107. package/dist/adapters/firestore/sync.js.map +0 -1
  108. /package/dist/adapters/{firestore → sync}/merge.d.ts +0 -0
  109. /package/dist/adapters/{firestore → sync}/merge.js +0 -0
package/README.md ADDED
@@ -0,0 +1,122 @@
1
+ # Agent-Native
2
+
3
+ **Agentic applications you own.**
4
+
5
+ Agent-native is an open source framework for building apps where an AI agent, a full application UI, and a computer work together as one. Fork a template, launch in minutes, and let AI help you customize it to your exact needs.
6
+
7
+ Other products charge you for rigid software you can't change. Agent-native gives you the code — you own it, you customize it, you evolve it with AI.
8
+
9
+ ## Templates
10
+
11
+ Start from a production-ready template. Each one replaces tools you're paying for — except you own everything and can customize it however you want.
12
+
13
+ <table>
14
+ <tr>
15
+ <td width="20%" align="center" valign="top">
16
+
17
+ **Analytics**
18
+
19
+ <a href="https://agent-native.com/templates/analytics"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F4933a80cc3134d7e874631f688be828a?format=webp&width=800" alt="Analytics template" width="100%" /></a>
20
+
21
+ **AI-Native Amplitude, Mixpanel**
22
+
23
+ Connect any data source, prompt for any chart. Build reusable dashboards, not throwaway Q&A.
24
+
25
+ </td>
26
+ <td width="20%" align="center" valign="top">
27
+
28
+ **Content**
29
+
30
+ <a href="https://agent-native.com/templates/content"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F89bcfc6106304bfbaf8ec8a7ccd721eb?format=webp&width=800" alt="Content template" width="100%" /></a>
31
+
32
+ **AI-Native Notion, Google Docs**
33
+
34
+ Write and organize content with an agent that knows your brand and publishing workflow.
35
+
36
+ </td>
37
+ <td width="20%" align="center" valign="top">
38
+
39
+ **Slides**
40
+
41
+ <a href="https://agent-native.com/templates/slides"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F2c09b451d40c4a74a89a38d69170c2d8?format=webp&width=800" alt="Slides template" width="100%" /></a>
42
+
43
+ **AI-Native Google Slides, Pitch**
44
+
45
+ Generate and edit React-based presentations via prompt or point-and-click.
46
+
47
+ </td>
48
+ <td width="20%" align="center" valign="top">
49
+
50
+ **Video**
51
+
52
+ <a href="https://agent-native.com/templates/video"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2F6b8bfcc18a1d4c47a491da3b2d4148a4?format=webp&width=800" alt="Video template" width="100%" /></a>
53
+
54
+ **AI-Native video editing**
55
+
56
+ Create and edit Remotion video compositions with agent assistance.
57
+
58
+ </td>
59
+ <td width="20%" align="center" valign="top">
60
+
61
+ **Calendar**
62
+
63
+ <a href="https://agent-native.com/templates/calendar"><img src="https://cdn.builder.io/api/v1/image/assets%2FYJIGb4i01jvw0SRdL5Bt%2Fcalendar-template-screenshot?format=webp&width=800" alt="Calendar template" width="100%" /></a>
64
+
65
+ **AI-Native Google Calendar, Calendly**
66
+
67
+ Manage events, sync with Google Calendar, and share a public booking page with AI scheduling.
68
+
69
+ </td>
70
+ </tr>
71
+ <tr>
72
+ <td align="center"><a href="https://agent-native.com/templates/analytics"><img src=".github/assets/launch-button.svg" alt="Launch Analytics" height="36" /></a></td>
73
+ <td align="center"><a href="https://agent-native.com/templates/content"><img src=".github/assets/launch-button.svg" alt="Launch Content" height="36" /></a></td>
74
+ <td align="center"><a href="https://agent-native.com/templates/slides"><img src=".github/assets/launch-button.svg" alt="Launch Slides" height="36" /></a></td>
75
+ <td align="center"><a href="https://agent-native.com/templates/video"><img src=".github/assets/launch-button.svg" alt="Launch Video" height="36" /></a></td>
76
+ <td align="center"><a href="https://agent-native.com/templates/calendar"><img src=".github/assets/launch-button.svg" alt="Launch Calendar" height="36" /></a></td>
77
+ </tr>
78
+ </table>
79
+
80
+ Every template is forkable, open source, and designed to be customized. Try them with example data before connecting your own sources.
81
+
82
+ ## Quick Start
83
+
84
+ ```bash
85
+ npx @agent-native/core create my-app
86
+ cd my-app
87
+ pnpm install
88
+ pnpm dev
89
+ ```
90
+
91
+ Or **[launch a template](https://agent-native.com/templates)** — no setup required.
92
+
93
+ ## How It Works
94
+
95
+ Agent-native apps follow five rules:
96
+
97
+ - **Files as database** — All state lives in files. The agent and UI share the same source of truth.
98
+ - **AI through the agent** — No inline LLM calls. The UI delegates to the agent via a chat bridge. One AI, customizable with skills and instructions.
99
+ - **Agent updates code** — The agent can modify the app itself. Your tools get better over time.
100
+ - **Real-time sync** — File watcher streams changes via SSE. Agent edits appear instantly.
101
+ - **Agent + UI + Computer** — The powerful trio. Everything the UI can do, the agent can do — and vice versa.
102
+
103
+ ## Harnesses
104
+
105
+ Agent-native apps run inside a **harness** — a host that provides the AI agent alongside your app UI.
106
+
107
+ | | Local / Open Source | Builder Cloud |
108
+ |---|---|---|
109
+ | **Run** | Claude Code CLI or any local harness | One-click launch from templates |
110
+ | **Collaboration** | Solo | Real-time multiplayer |
111
+ | **Features** | Full permissions, full control | Visual editing, roles & permissions |
112
+ | **Best for** | Solo dev, local testing, OSS | Teams, production |
113
+
114
+ Your app code is identical regardless of harness. Start local, go to cloud when you need teams.
115
+
116
+ ## Docs
117
+
118
+ Full documentation at **[agent-native.com](https://agent-native.com)**.
119
+
120
+ ## License
121
+
122
+ MIT
@@ -0,0 +1,47 @@
1
+ import type { FileSyncAdapter, FileRecord, FileChange, Unsubscribe } from "../sync/types.js";
2
+ export interface FirestoreCollection {
3
+ doc(id: string): FirestoreDocRef;
4
+ where(field: string, op: string, value: any): FirestoreQuery;
5
+ }
6
+ export interface FirestoreDocRef {
7
+ get(): Promise<FirestoreDocSnapshot>;
8
+ set(data: any, options?: {
9
+ merge?: boolean;
10
+ }): Promise<any>;
11
+ delete(): Promise<any>;
12
+ collection(name: string): FirestoreCollection;
13
+ }
14
+ export interface FirestoreQuery {
15
+ where(field: string, op: string, value: any): FirestoreQuery;
16
+ get(): Promise<FirestoreQuerySnapshot>;
17
+ onSnapshot(onNext: (snapshot: FirestoreQuerySnapshot) => void, onError: (error: any) => void): () => void;
18
+ }
19
+ export interface FirestoreDocSnapshot {
20
+ exists: boolean;
21
+ id: string;
22
+ data(): any;
23
+ }
24
+ export interface FirestoreQuerySnapshot {
25
+ docs: FirestoreDocSnapshot[];
26
+ size: number;
27
+ docChanges(): Array<{
28
+ type: "added" | "modified" | "removed";
29
+ doc: FirestoreDocSnapshot;
30
+ }>;
31
+ }
32
+ export declare class FirestoreFileSyncAdapter implements FileSyncAdapter {
33
+ private getCollection;
34
+ constructor(getCollection: () => FirestoreCollection);
35
+ query(appId: string, ownerId: string): Promise<{
36
+ id: string;
37
+ data: FileRecord;
38
+ }[]>;
39
+ get(id: string): Promise<{
40
+ id: string;
41
+ data: FileRecord;
42
+ } | null>;
43
+ set(id: string, record: Partial<FileRecord>): Promise<void>;
44
+ delete(id: string): Promise<void>;
45
+ subscribe(appId: string, ownerId: string, onChange: (changes: FileChange[]) => void, onError: (error: any) => void): Unsubscribe;
46
+ }
47
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/firestore/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM7F,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,eAAe,CAAC;IACjC,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,cAAc,CAAC;CAC9D;AAED,MAAM,WAAW,eAAe;IAC9B,GAAG,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACrC,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;QAAE,KAAK,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAC5D,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC;IACvB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,mBAAmB,CAAC;CAC/C;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,cAAc,CAAC;IAC7D,GAAG,IAAI,OAAO,CAAC,sBAAsB,CAAC,CAAC;IACvC,UAAU,CACR,MAAM,EAAE,CAAC,QAAQ,EAAE,sBAAsB,KAAK,IAAI,EAClD,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAC5B,MAAM,IAAI,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,MAAM,EAAE,OAAO,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,IAAI,GAAG,CAAC;CACb;AAED,MAAM,WAAW,sBAAsB;IACrC,IAAI,EAAE,oBAAoB,EAAE,CAAC;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,IAAI,KAAK,CAAC;QAClB,IAAI,EAAE,OAAO,GAAG,UAAU,GAAG,SAAS,CAAC;QACvC,GAAG,EAAE,oBAAoB,CAAC;KAC3B,CAAC,CAAC;CACJ;AAMD,qBAAa,wBAAyB,YAAW,eAAe;IAClD,OAAO,CAAC,aAAa;gBAAb,aAAa,EAAE,MAAM,mBAAmB;IAEtD,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,EAAE,CAAC;IAYlF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAMjE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAI3D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,SAAS,CACP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EACzC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAC5B,WAAW;CAgBf"}
@@ -0,0 +1,45 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Firestore adapter
3
+ // ---------------------------------------------------------------------------
4
+ export class FirestoreFileSyncAdapter {
5
+ getCollection;
6
+ constructor(getCollection) {
7
+ this.getCollection = getCollection;
8
+ }
9
+ async query(appId, ownerId) {
10
+ const snapshot = await this.getCollection()
11
+ .where("app", "==", appId)
12
+ .where("ownerId", "==", ownerId)
13
+ .get();
14
+ return snapshot.docs.map((doc) => ({
15
+ id: doc.id,
16
+ data: doc.data(),
17
+ }));
18
+ }
19
+ async get(id) {
20
+ const doc = await this.getCollection().doc(id).get();
21
+ if (!doc.exists)
22
+ return null;
23
+ return { id: doc.id, data: doc.data() };
24
+ }
25
+ async set(id, record) {
26
+ await this.getCollection().doc(id).set(record, { merge: true });
27
+ }
28
+ async delete(id) {
29
+ await this.getCollection().doc(id).delete();
30
+ }
31
+ subscribe(appId, ownerId, onChange, onError) {
32
+ return this.getCollection()
33
+ .where("app", "==", appId)
34
+ .where("ownerId", "==", ownerId)
35
+ .onSnapshot((snapshot) => {
36
+ const changes = snapshot.docChanges().map((change) => ({
37
+ type: change.type,
38
+ id: change.doc.id,
39
+ data: change.doc.data(),
40
+ }));
41
+ onChange(changes);
42
+ }, onError);
43
+ }
44
+ }
45
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/firestore/adapter.ts"],"names":[],"mappings":"AA0CA,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,MAAM,OAAO,wBAAwB;IACf;IAApB,YAAoB,aAAwC;QAAxC,kBAAa,GAAb,aAAa,CAA2B;IAAG,CAAC;IAEhE,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,OAAe;QACxC,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE;aACxC,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;aACzB,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC;aAC/B,GAAG,EAAE,CAAC;QAET,OAAO,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACjC,EAAE,EAAE,GAAG,CAAC,EAAE;YACV,IAAI,EAAE,GAAG,CAAC,IAAI,EAAgB;SAC/B,CAAC,CAAC,CAAC;IACN,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,EAAE,CAAC;QACrD,IAAI,CAAC,GAAG,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QAC7B,OAAO,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,GAAG,CAAC,IAAI,EAAgB,EAAE,CAAC;IACxD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,MAA2B;QAC/C,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAClE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,IAAI,CAAC,aAAa,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC;IAC9C,CAAC;IAED,SAAS,CACP,KAAa,EACb,OAAe,EACf,QAAyC,EACzC,OAA6B;QAE7B,OAAO,IAAI,CAAC,aAAa,EAAE;aACxB,KAAK,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;aACzB,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,CAAC;aAC/B,UAAU,CACT,CAAC,QAAQ,EAAE,EAAE;YACX,MAAM,OAAO,GAAiB,QAAQ,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACnE,IAAI,EAAE,MAAM,CAAC,IAAI;gBACjB,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,EAAE;gBACjB,IAAI,EAAE,MAAM,CAAC,GAAG,CAAC,IAAI,EAAgB;aACtC,CAAC,CAAC,CAAC;YACJ,QAAQ,CAAC,OAAO,CAAC,CAAC;QACpB,CAAC,EACD,OAAO,CACR,CAAC;IACN,CAAC;CACF"}
@@ -1,4 +1,4 @@
1
- export { FileSync, type FileSyncOptions, type SyncEvent } from "./sync.js";
2
- export { threeWayMerge, type MergeResult } from "./merge.js";
3
- export { loadSyncConfig, shouldSyncFile, getDocId, type SyncConfig, } from "./config.js";
1
+ export { FirestoreFileSyncAdapter } from "./adapter.js";
2
+ export type { FirestoreCollection, FirestoreDocRef, FirestoreQuery, FirestoreDocSnapshot, FirestoreQuerySnapshot, } from "./adapter.js";
3
+ export * from "../sync/index.js";
4
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/firestore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,eAAe,EAAE,KAAK,SAAS,EAAE,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAE,KAAK,WAAW,EAAE,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,cAAc,EACd,cAAc,EACd,QAAQ,EACR,KAAK,UAAU,GAChB,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/firestore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,YAAY,EACV,mBAAmB,EACnB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AACtB,cAAc,kBAAkB,CAAC"}
@@ -1,4 +1,3 @@
1
- export { FileSync } from "./sync.js";
2
- export { threeWayMerge } from "./merge.js";
3
- export { loadSyncConfig, shouldSyncFile, getDocId, } from "./config.js";
1
+ export { FirestoreFileSyncAdapter } from "./adapter.js";
2
+ export * from "../sync/index.js";
4
3
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/firestore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAwC,MAAM,WAAW,CAAC;AAC3E,OAAO,EAAE,aAAa,EAAoB,MAAM,YAAY,CAAC;AAC7D,OAAO,EACL,cAAc,EACd,cAAc,EACd,QAAQ,GAET,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/firestore/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AAQxD,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,28 @@
1
+ import type { FileSyncAdapter, FileRecord, FileChange, Unsubscribe } from "../sync/types.js";
2
+ interface NeonQueryResult {
3
+ rows: any[];
4
+ rowCount: number;
5
+ }
6
+ type NeonSql = (strings: TemplateStringsArray, ...values: any[]) => Promise<NeonQueryResult>;
7
+ export interface NeonAdapterOptions {
8
+ /** Polling interval in ms for subscribe(). Default: 2000 */
9
+ pollIntervalMs?: number;
10
+ }
11
+ export declare class NeonFileSyncAdapter implements FileSyncAdapter {
12
+ private sql;
13
+ private pollIntervalMs;
14
+ constructor(sql: NeonSql, options?: NeonAdapterOptions);
15
+ query(appId: string, ownerId: string): Promise<{
16
+ id: string;
17
+ data: FileRecord;
18
+ }[]>;
19
+ get(id: string): Promise<{
20
+ id: string;
21
+ data: FileRecord;
22
+ } | null>;
23
+ set(id: string, record: Partial<FileRecord>): Promise<void>;
24
+ delete(id: string): Promise<void>;
25
+ subscribe(appId: string, ownerId: string, onChange: (changes: FileChange[]) => void, onError: (error: any) => void): Unsubscribe;
26
+ }
27
+ export {};
28
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/neon/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM7F,UAAU,eAAe;IACvB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,KAAK,OAAO,GAAG,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,MAAM,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AA6B7F,MAAM,WAAW,kBAAkB;IACjC,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,mBAAoB,YAAW,eAAe;IAIvD,OAAO,CAAC,GAAG;IAHb,OAAO,CAAC,cAAc,CAAS;gBAGrB,GAAG,EAAE,OAAO,EACpB,OAAO,CAAC,EAAE,kBAAkB;IAKxB,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,EAAE,CAAC;IAOlF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IASjE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAqB3D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIvC,SAAS,CACP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EACzC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAC5B,WAAW;CA4Df"}
@@ -0,0 +1,119 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Column mapping helpers
3
+ // ---------------------------------------------------------------------------
4
+ /**
5
+ * Table schema (same as Supabase):
6
+ * files(id TEXT PK, path TEXT, content TEXT, app TEXT, owner_id TEXT,
7
+ * last_updated BIGINT, created_at BIGINT)
8
+ *
9
+ * CREATE INDEX idx_files_app_owner ON files(app, owner_id);
10
+ */
11
+ function rowToRecord(row) {
12
+ return {
13
+ path: row.path,
14
+ content: row.content,
15
+ app: row.app,
16
+ ownerId: row.owner_id,
17
+ lastUpdated: Number(row.last_updated),
18
+ createdAt: row.created_at != null ? Number(row.created_at) : undefined,
19
+ };
20
+ }
21
+ export class NeonFileSyncAdapter {
22
+ sql;
23
+ pollIntervalMs;
24
+ constructor(sql, options) {
25
+ this.sql = sql;
26
+ this.pollIntervalMs = options?.pollIntervalMs ?? 2000;
27
+ }
28
+ async query(appId, ownerId) {
29
+ const result = await this.sql `
30
+ SELECT * FROM files WHERE app = ${appId} AND owner_id = ${ownerId}
31
+ `;
32
+ return result.rows.map((row) => ({ id: row.id, data: rowToRecord(row) }));
33
+ }
34
+ async get(id) {
35
+ const result = await this.sql `
36
+ SELECT * FROM files WHERE id = ${id} LIMIT 1
37
+ `;
38
+ if (result.rows.length === 0)
39
+ return null;
40
+ const row = result.rows[0];
41
+ return { id: row.id, data: rowToRecord(row) };
42
+ }
43
+ async set(id, record) {
44
+ const path = record.path ?? "";
45
+ const content = record.content ?? "";
46
+ const app = record.app ?? "";
47
+ const ownerId = record.ownerId ?? "";
48
+ const lastUpdated = record.lastUpdated ?? 0;
49
+ const createdAt = record.createdAt ?? null;
50
+ await this.sql `
51
+ INSERT INTO files (id, path, content, app, owner_id, last_updated, created_at)
52
+ VALUES (${id}, ${path}, ${content}, ${app}, ${ownerId}, ${lastUpdated}, ${createdAt})
53
+ ON CONFLICT (id) DO UPDATE SET
54
+ path = COALESCE(EXCLUDED.path, files.path),
55
+ content = COALESCE(EXCLUDED.content, files.content),
56
+ app = COALESCE(EXCLUDED.app, files.app),
57
+ owner_id = COALESCE(EXCLUDED.owner_id, files.owner_id),
58
+ last_updated = COALESCE(EXCLUDED.last_updated, files.last_updated),
59
+ created_at = COALESCE(EXCLUDED.created_at, files.created_at)
60
+ `;
61
+ }
62
+ async delete(id) {
63
+ await this.sql `DELETE FROM files WHERE id = ${id}`;
64
+ }
65
+ subscribe(appId, ownerId, onChange, onError) {
66
+ const snapshot = new Map();
67
+ let stopped = false;
68
+ const poll = async () => {
69
+ if (stopped)
70
+ return;
71
+ try {
72
+ const result = await this.sql `
73
+ SELECT * FROM files WHERE app = ${appId} AND owner_id = ${ownerId}
74
+ `;
75
+ const currentIds = new Set();
76
+ const changes = [];
77
+ for (const row of result.rows) {
78
+ currentIds.add(row.id);
79
+ const record = rowToRecord(row);
80
+ const prev = snapshot.get(row.id);
81
+ if (!prev) {
82
+ changes.push({ type: "added", id: row.id, data: record });
83
+ snapshot.set(row.id, { content: row.content, lastUpdated: Number(row.last_updated) });
84
+ }
85
+ else if (prev.content !== row.content || prev.lastUpdated !== Number(row.last_updated)) {
86
+ changes.push({ type: "modified", id: row.id, data: record });
87
+ snapshot.set(row.id, { content: row.content, lastUpdated: Number(row.last_updated) });
88
+ }
89
+ }
90
+ for (const [id] of snapshot) {
91
+ if (!currentIds.has(id)) {
92
+ const prev = snapshot.get(id);
93
+ changes.push({
94
+ type: "removed",
95
+ id,
96
+ data: { path: "", content: prev.content, app: appId, ownerId, lastUpdated: prev.lastUpdated },
97
+ });
98
+ snapshot.delete(id);
99
+ }
100
+ }
101
+ if (changes.length > 0) {
102
+ onChange(changes);
103
+ }
104
+ }
105
+ catch (err) {
106
+ onError(err);
107
+ }
108
+ if (!stopped) {
109
+ setTimeout(poll, this.pollIntervalMs);
110
+ }
111
+ };
112
+ // Start polling
113
+ poll();
114
+ return () => {
115
+ stopped = true;
116
+ };
117
+ }
118
+ }
119
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/neon/adapter.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { NeonFileSyncAdapter, type NeonAdapterOptions } from "./adapter.js";
2
+ export * from "../sync/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/neon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,KAAK,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAC5E,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { NeonFileSyncAdapter } from "./adapter.js";
2
+ export * from "../sync/index.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/neon/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAA2B,MAAM,cAAc,CAAC;AAC5E,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,42 @@
1
+ import type { FileSyncAdapter, FileRecord, FileChange, Unsubscribe } from "../sync/types.js";
2
+ interface SupabaseFilterBuilder {
3
+ select(columns: string): SupabaseFilterBuilder;
4
+ eq(column: string, value: any): SupabaseFilterBuilder;
5
+ maybeSingle(): SupabaseFilterBuilder;
6
+ then(resolve: (value: any) => any, reject?: (error: any) => any): any;
7
+ }
8
+ interface SupabaseQueryBuilder {
9
+ select(columns: string): SupabaseFilterBuilder;
10
+ upsert(values: any, options?: {
11
+ onConflict?: string;
12
+ }): SupabaseFilterBuilder;
13
+ delete(): SupabaseFilterBuilder;
14
+ }
15
+ interface SupabaseRealtimeChannel {
16
+ on(event: string, filter: any, callback: (payload: any) => void): SupabaseRealtimeChannel;
17
+ subscribe(callback?: (status: string) => void): SupabaseRealtimeChannel;
18
+ unsubscribe(): void;
19
+ }
20
+ interface SupabaseClient {
21
+ from(table: string): SupabaseQueryBuilder;
22
+ channel(name: string): SupabaseRealtimeChannel;
23
+ removeChannel(channel: SupabaseRealtimeChannel): void;
24
+ }
25
+ export declare class SupabaseFileSyncAdapter implements FileSyncAdapter {
26
+ private client;
27
+ private table;
28
+ constructor(client: SupabaseClient, table?: string);
29
+ query(appId: string, ownerId: string): Promise<{
30
+ id: string;
31
+ data: FileRecord;
32
+ }[]>;
33
+ get(id: string): Promise<{
34
+ id: string;
35
+ data: FileRecord;
36
+ } | null>;
37
+ set(id: string, record: Partial<FileRecord>): Promise<void>;
38
+ delete(id: string): Promise<void>;
39
+ subscribe(appId: string, ownerId: string, onChange: (changes: FileChange[]) => void, onError: (error: any) => void): Unsubscribe;
40
+ }
41
+ export {};
42
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../../src/adapters/supabase/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAM7F,UAAU,qBAAqB;IAC7B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAAC;IAC/C,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,qBAAqB,CAAC;IACtD,WAAW,IAAI,qBAAqB,CAAC;IACrC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,GAAG,GAAG,GAAG,CAAC;CACvE;AAED,UAAU,oBAAoB;IAC5B,MAAM,CAAC,OAAO,EAAE,MAAM,GAAG,qBAAqB,CAAC;IAC/C,MAAM,CAAC,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,EAAE;QAAE,UAAU,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,qBAAqB,CAAC;IAC9E,MAAM,IAAI,qBAAqB,CAAC;CACjC;AAED,UAAU,uBAAuB;IAC/B,EAAE,CACA,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,GAAG,EACX,QAAQ,EAAE,CAAC,OAAO,EAAE,GAAG,KAAK,IAAI,GAC/B,uBAAuB,CAAC;IAC3B,SAAS,CAAC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,uBAAuB,CAAC;IACxE,WAAW,IAAI,IAAI,CAAC;CACrB;AAED,UAAU,cAAc;IACtB,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,oBAAoB,CAAC;IAC1C,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,uBAAuB,CAAC;IAC/C,aAAa,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAAC;CACvD;AAwCD,qBAAa,uBAAwB,YAAW,eAAe;IAE3D,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,KAAK;gBADL,MAAM,EAAE,cAAc,EACtB,KAAK,GAAE,MAAgB;IAG3B,KAAK,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,EAAE,CAAC;IAWlF,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,UAAU,CAAA;KAAE,GAAG,IAAI,CAAC;IAYjE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;IAS3D,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IASvC,SAAS,CACP,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,IAAI,EACzC,OAAO,EAAE,CAAC,KAAK,EAAE,GAAG,KAAK,IAAI,GAC5B,WAAW;CAyCf"}
@@ -0,0 +1,126 @@
1
+ // ---------------------------------------------------------------------------
2
+ // Column mapping helpers
3
+ // ---------------------------------------------------------------------------
4
+ /**
5
+ * Table schema:
6
+ * files(id TEXT PK, path TEXT, content TEXT, app TEXT, owner_id TEXT,
7
+ * last_updated BIGINT, created_at BIGINT)
8
+ *
9
+ * CREATE INDEX idx_files_app_owner ON files(app, owner_id);
10
+ */
11
+ function rowToRecord(row) {
12
+ return {
13
+ path: row.path,
14
+ content: row.content,
15
+ app: row.app,
16
+ ownerId: row.owner_id,
17
+ lastUpdated: row.last_updated,
18
+ createdAt: row.created_at ?? undefined,
19
+ };
20
+ }
21
+ function recordToRow(id, record) {
22
+ const row = { id };
23
+ if (record.path !== undefined)
24
+ row.path = record.path;
25
+ if (record.content !== undefined)
26
+ row.content = record.content;
27
+ if (record.app !== undefined)
28
+ row.app = record.app;
29
+ if (record.ownerId !== undefined)
30
+ row.owner_id = record.ownerId;
31
+ if (record.lastUpdated !== undefined)
32
+ row.last_updated = record.lastUpdated;
33
+ if (record.createdAt !== undefined)
34
+ row.created_at = record.createdAt;
35
+ return row;
36
+ }
37
+ // ---------------------------------------------------------------------------
38
+ // Supabase adapter
39
+ // ---------------------------------------------------------------------------
40
+ export class SupabaseFileSyncAdapter {
41
+ client;
42
+ table;
43
+ constructor(client, table = "files") {
44
+ this.client = client;
45
+ this.table = table;
46
+ }
47
+ async query(appId, ownerId) {
48
+ const { data, error } = await this.client
49
+ .from(this.table)
50
+ .select("*")
51
+ .eq("app", appId)
52
+ .eq("owner_id", ownerId);
53
+ if (error)
54
+ throw error;
55
+ return (data ?? []).map((row) => ({ id: row.id, data: rowToRecord(row) }));
56
+ }
57
+ async get(id) {
58
+ const { data, error } = await this.client
59
+ .from(this.table)
60
+ .select("*")
61
+ .eq("id", id)
62
+ .maybeSingle();
63
+ if (error)
64
+ throw error;
65
+ if (!data)
66
+ return null;
67
+ return { id: data.id, data: rowToRecord(data) };
68
+ }
69
+ async set(id, record) {
70
+ const row = recordToRow(id, record);
71
+ const { error } = await this.client
72
+ .from(this.table)
73
+ .upsert(row, { onConflict: "id" });
74
+ if (error)
75
+ throw error;
76
+ }
77
+ async delete(id) {
78
+ const { error } = await this.client
79
+ .from(this.table)
80
+ .delete()
81
+ .eq("id", id);
82
+ if (error)
83
+ throw error;
84
+ }
85
+ subscribe(appId, ownerId, onChange, onError) {
86
+ const channel = this.client
87
+ .channel(`file-sync-${appId}-${ownerId}`)
88
+ .on("postgres_changes", { event: "*", schema: "public", table: this.table, filter: `app=eq.${appId}` }, (payload) => {
89
+ try {
90
+ const row = payload.new ?? payload.old;
91
+ if (!row)
92
+ return;
93
+ // Client-side filter by owner_id (Realtime only supports one filter)
94
+ if (row.owner_id !== ownerId)
95
+ return;
96
+ let type;
97
+ if (payload.eventType === "INSERT")
98
+ type = "added";
99
+ else if (payload.eventType === "UPDATE")
100
+ type = "modified";
101
+ else if (payload.eventType === "DELETE")
102
+ type = "removed";
103
+ else
104
+ return;
105
+ const change = {
106
+ type,
107
+ id: row.id,
108
+ data: rowToRecord(row),
109
+ };
110
+ onChange([change]);
111
+ }
112
+ catch (err) {
113
+ onError(err);
114
+ }
115
+ })
116
+ .subscribe((status) => {
117
+ if (status === "CHANNEL_ERROR") {
118
+ onError(new Error("Supabase realtime channel error"));
119
+ }
120
+ });
121
+ return () => {
122
+ this.client.removeChannel(channel);
123
+ };
124
+ }
125
+ }
126
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../../src/adapters/supabase/adapter.ts"],"names":[],"mappings":"AAmCA,8EAA8E;AAC9E,yBAAyB;AACzB,8EAA8E;AAE9E;;;;;;GAMG;AAEH,SAAS,WAAW,CAAC,GAAQ;IAC3B,OAAO;QACL,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,GAAG,EAAE,GAAG,CAAC,GAAG;QACZ,OAAO,EAAE,GAAG,CAAC,QAAQ;QACrB,WAAW,EAAE,GAAG,CAAC,YAAY;QAC7B,SAAS,EAAE,GAAG,CAAC,UAAU,IAAI,SAAS;KACvC,CAAC;AACJ,CAAC;AAED,SAAS,WAAW,CAAC,EAAU,EAAE,MAA2B;IAC1D,MAAM,GAAG,GAAwB,EAAE,EAAE,EAAE,CAAC;IACxC,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS;QAAE,GAAG,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;IACtD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,GAAG,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;IAC/D,IAAI,MAAM,CAAC,GAAG,KAAK,SAAS;QAAE,GAAG,CAAC,GAAG,GAAG,MAAM,CAAC,GAAG,CAAC;IACnD,IAAI,MAAM,CAAC,OAAO,KAAK,SAAS;QAAE,GAAG,CAAC,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC;IAChE,IAAI,MAAM,CAAC,WAAW,KAAK,SAAS;QAAE,GAAG,CAAC,YAAY,GAAG,MAAM,CAAC,WAAW,CAAC;IAC5E,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS;QAAE,GAAG,CAAC,UAAU,GAAG,MAAM,CAAC,SAAS,CAAC;IACtE,OAAO,GAAG,CAAC;AACb,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,MAAM,OAAO,uBAAuB;IAExB;IACA;IAFV,YACU,MAAsB,EACtB,QAAgB,OAAO;QADvB,WAAM,GAAN,MAAM,CAAgB;QACtB,UAAK,GAAL,KAAK,CAAkB;IAC9B,CAAC;IAEJ,KAAK,CAAC,KAAK,CAAC,KAAa,EAAE,OAAe;QACxC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAO,IAAI,CAAC,MAAM;aACvC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;aAChB,MAAM,CAAC,GAAG,CAAC;aACX,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC;aAChB,EAAE,CAAC,UAAU,EAAE,OAAO,CAAS,CAAC;QAEnC,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,GAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC;IAClF,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU;QAClB,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,MAAO,IAAI,CAAC,MAAM;aACvC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;aAChB,MAAM,CAAC,GAAG,CAAC;aACX,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC;aACZ,WAAW,EAAU,CAAC;QAEzB,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;QACvB,IAAI,CAAC,IAAI;YAAE,OAAO,IAAI,CAAC;QACvB,OAAO,EAAE,EAAE,EAAE,IAAI,CAAC,EAAE,EAAE,IAAI,EAAE,WAAW,CAAC,IAAI,CAAC,EAAE,CAAC;IAClD,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,EAAU,EAAE,MAA2B;QAC/C,MAAM,GAAG,GAAG,WAAW,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACpC,MAAM,EAAE,KAAK,EAAE,GAAG,MAAO,IAAI,CAAC,MAAM;aACjC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;aAChB,MAAM,CAAC,GAAG,EAAE,EAAE,UAAU,EAAE,IAAI,EAAE,CAAS,CAAC;QAE7C,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;IACzB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,EAAU;QACrB,MAAM,EAAE,KAAK,EAAE,GAAG,MAAO,IAAI,CAAC,MAAM;aACjC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC;aAChB,MAAM,EAAE;aACR,EAAE,CAAC,IAAI,EAAE,EAAE,CAAS,CAAC;QAExB,IAAI,KAAK;YAAE,MAAM,KAAK,CAAC;IACzB,CAAC;IAED,SAAS,CACP,KAAa,EACb,OAAe,EACf,QAAyC,EACzC,OAA6B;QAE7B,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM;aACxB,OAAO,CAAC,aAAa,KAAK,IAAI,OAAO,EAAE,CAAC;aACxC,EAAE,CACD,kBAAkB,EAClB,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,KAAK,EAAE,EAAE,EAC9E,CAAC,OAAY,EAAE,EAAE;YACf,IAAI,CAAC;gBACH,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,OAAO,CAAC,GAAG,CAAC;gBACvC,IAAI,CAAC,GAAG;oBAAE,OAAO;gBAEjB,qEAAqE;gBACrE,IAAI,GAAG,CAAC,QAAQ,KAAK,OAAO;oBAAE,OAAO;gBAErC,IAAI,IAAwB,CAAC;gBAC7B,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ;oBAAE,IAAI,GAAG,OAAO,CAAC;qBAC9C,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ;oBAAE,IAAI,GAAG,UAAU,CAAC;qBACtD,IAAI,OAAO,CAAC,SAAS,KAAK,QAAQ;oBAAE,IAAI,GAAG,SAAS,CAAC;;oBACrD,OAAO;gBAEZ,MAAM,MAAM,GAAe;oBACzB,IAAI;oBACJ,EAAE,EAAE,GAAG,CAAC,EAAE;oBACV,IAAI,EAAE,WAAW,CAAC,GAAG,CAAC;iBACvB,CAAC;gBACF,QAAQ,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;YACrB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,CAAC;YACf,CAAC;QACH,CAAC,CACF;aACA,SAAS,CAAC,CAAC,MAAc,EAAE,EAAE;YAC5B,IAAI,MAAM,KAAK,eAAe,EAAE,CAAC;gBAC/B,OAAO,CAAC,IAAI,KAAK,CAAC,iCAAiC,CAAC,CAAC,CAAC;YACxD,CAAC;QACH,CAAC,CAAC,CAAC;QAEL,OAAO,GAAG,EAAE;YACV,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;QACrC,CAAC,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,3 @@
1
+ export { SupabaseFileSyncAdapter } from "./adapter.js";
2
+ export * from "../sync/index.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/adapters/supabase/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,cAAc,kBAAkB,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { SupabaseFileSyncAdapter } from "./adapter.js";
2
+ export * from "../sync/index.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/adapters/supabase/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AACvD,cAAc,kBAAkB,CAAC"}
@@ -13,7 +13,7 @@ export declare function loadSyncConfig(configPath?: string): SyncConfig;
13
13
  */
14
14
  export declare function shouldSyncFile(filePath: string, patterns: string[]): boolean;
15
15
  /**
16
- * Generate a deterministic Firestore doc ID from a file path.
16
+ * Generate a deterministic doc ID from a file path.
17
17
  * Prefixed with the app ID, path separators replaced with `__`.
18
18
  */
19
19
  export declare function getDocId(appId: string, filePath: string): string;