@automerge/automerge-repo-svelte-store 2.0.0-collectionsync-alpha.1 → 2.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.
package/README.md CHANGED
@@ -1,54 +1,204 @@
1
1
  # Svelte store for Automerge Repo
2
2
 
3
+ A reactive Svelte store for Automerge documents. Compatible with Svelte 3, 4, and 5.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @automerge/automerge-repo-svelte-store
9
+ ```
10
+
3
11
  ## Example Usage
4
12
 
5
- For a working example, see the [Svelte counter demo](../automerge-repo-demo-counter-svelte/).
13
+ ### Basic Usage
14
+
15
+ ```svelte
16
+ <script>
17
+ import { Repo } from "@automerge/automerge-repo"
18
+ import { createAutomergeStore } from "@automerge/automerge-repo-svelte-store"
6
19
 
7
- `App.svelte`
20
+ // Create a repo
21
+ const repo = new Repo({
22
+ // Configuration...
23
+ })
24
+
25
+ // Create a store from the repo
26
+ const automergeStore = createAutomergeStore(repo)
27
+
28
+ // Load or create a document
29
+ let documentStore = null
30
+
31
+ async function loadDocument(url) {
32
+ documentStore = await automergeStore.find(url)
33
+ }
34
+
35
+ async function createDocument() {
36
+ documentStore = await automergeStore.create({ count: 0 })
37
+ }
38
+
39
+ // Update the document
40
+ function incrementCounter() {
41
+ if (documentStore) {
42
+ documentStore.change(doc => {
43
+ doc.count = (doc.count || 0) + 1
44
+ })
45
+ }
46
+ }
47
+ </script>
48
+ ```
49
+
50
+ ### Using with Svelte Context (recommended)
8
51
 
9
52
  ```svelte
10
- <script lang="ts">
53
+ <!-- App.svelte -->
54
+ <script>
11
55
  import { Repo } from "@automerge/automerge-repo"
12
- import Counter from './lib/Counter.svelte'
13
56
  import { setContextRepo } from "@automerge/automerge-repo-svelte-store"
57
+ import Counter from './Counter.svelte'
14
58
 
15
- const repo = new Repo({ /* repo config */ })
59
+ const repo = new Repo({
60
+ // Configuration...
61
+ })
16
62
 
17
- // Make the `Repo` available to child components (via Svelte's `setContext`).
63
+ // Make repo available to child components
18
64
  setContextRepo(repo)
19
65
 
20
- const docId = repo.create()
66
+ // Create a document asynchronously
67
+ let docUrl = null
68
+
69
+ async function setupDoc() {
70
+ const handle = await repo.create({ count: 0 })
71
+ docUrl = handle.url
72
+ }
73
+
74
+ setupDoc()
21
75
  </script>
22
76
 
23
- <main>
24
- <div class="card">
25
- <Counter {docId}/>
26
- </div>
27
- </main>
77
+ {#if docUrl}
78
+ <Counter {docUrl} />
79
+ {:else}
80
+ <p>Creating document...</p>
81
+ {/if}
28
82
  ```
29
83
 
30
- `Counter.svelte`
84
+ ```svelte
85
+ <!-- Counter.svelte -->
86
+ <script>
87
+ import { document } from "@automerge/automerge-repo-svelte-store"
88
+ import { onMount } from "svelte"
89
+
90
+ export let docUrl
91
+
92
+ // The document store - initially null
93
+ let docStore = null
94
+
95
+ // Load the document on mount
96
+ onMount(async () => {
97
+ // document() is async and returns a Promise
98
+ docStore = await document(docUrl)
99
+ })
100
+
101
+ function increment() {
102
+ if (!docStore) return
103
+
104
+ // Access the document using the Svelte store $ syntax
105
+ docStore.change(doc => {
106
+ doc.count = (doc.count || 0) + 1
107
+ })
108
+ }
109
+ </script>
110
+
111
+ {#if docStore}
112
+ <button on:click={increment}>
113
+ Count: {$docStore.count || 0}
114
+ </button>
115
+ {:else}
116
+ <p>Loading document...</p>
117
+ {/if}
118
+ ```
119
+
120
+ ### Using with Svelte 5 Runes
121
+
122
+ With Svelte 5, you can use the store with runes syntax for a more ergonomic experience:
31
123
 
32
124
  ```svelte
33
- <script lang="ts">
34
- import type { DocumentId } from "@automerge/automerge-repo"
125
+ <script>
35
126
  import { document } from "@automerge/automerge-repo-svelte-store"
36
127
 
37
- export let docId: DocumentId
128
+ export let docUrl
129
+
130
+ // Initialize state
131
+ let docStore = $state(null)
132
+ let loading = $state(true)
133
+ let error = $state(null)
134
+ let count = $derived(docStore?.$doc?.count || 0)
135
+
136
+ // Load document when component initializes
137
+ $effect(() => {
138
+ async function loadDocument() {
139
+ try {
140
+ loading = true
141
+ docStore = await document(docUrl)
142
+ loading = false
143
+ } catch (err) {
144
+ console.error("Failed to load document:", err)
145
+ error = err
146
+ loading = false
147
+ }
148
+ }
149
+
150
+ loadDocument()
151
+ })
38
152
 
39
- // `document` calls `getContextRepo` internally to access the closest `Repo`.
40
- // alternatively, you may pass in a specific repo as the second parameter
41
- const doc = document<{count?: number}>(docId)
42
- const increment = () => {
43
- doc.change((d) => d.count = (d.count || 0) + 1)
153
+ function increment() {
154
+ if (docStore) {
155
+ docStore.change(doc => {
156
+ doc.count = (doc.count || 0) + 1
157
+ })
158
+ }
44
159
  }
45
160
  </script>
46
161
 
47
- <button on:click={increment}>
48
- count is {$doc?.count || 0}
49
- </button>
162
+ {#if loading}
163
+ <p>Loading document...</p>
164
+ {:else if error}
165
+ <p>Error: {error.message}</p>
166
+ {:else}
167
+ <button on:click={increment}>
168
+ Count: {count}
169
+ </button>
170
+ {/if}
50
171
  ```
51
172
 
173
+ ## API Reference
174
+
175
+ ### `createAutomergeStore(repo)`
176
+
177
+ Creates an Automerge store factory from a repo instance.
178
+
179
+ ### `setContextRepo(repo)`
180
+
181
+ Sets the Automerge repo in the current component's context.
182
+
183
+ ### `getContextRepo()`
184
+
185
+ Gets the Automerge repo from the current component's context.
186
+
187
+ ### `document(docIdOrUrl, repoInstance?)`
188
+
189
+ Convenience method to load a document from the repo in context or a provided repo.
190
+ **Important:** This function returns a Promise that resolves to the document store.
191
+
192
+ ## Store API
193
+
194
+ The document store returned by `find()` and `create()` implements Svelte's writable store contract with these additional methods:
195
+
196
+ - `change(fn)`: Make changes to the document
197
+ - `url`: Get the document URL
198
+ - `documentId`: Get the document ID
199
+ - `handle`: Access the underlying Automerge document handle
200
+
52
201
  ## Contributors
53
202
 
54
- Originally written by Dylan MacKenzie ([@ecstatic-morse](https://github.com/ecstatic-morse)).
203
+ Originally written by Dylan MacKenzie (@ecstatic-morse).
204
+ Updated for Svelte 5 compatibility by the Automerge team.
package/dist/index.d.ts CHANGED
@@ -1,74 +1,53 @@
1
+ import type { AutomergeUrl, ChangeFn, Doc, DocHandle, DocumentId, Repo } from "@automerge/automerge-repo/slim";
2
+ import { type Writable } from "svelte/store";
1
3
  /**
2
- * # Svelte store for Automerge Repo
3
- *
4
- * ## Example Usage
5
- *
6
- * For a working example, see the [Svelte counter demo](../automerge-repo-demo-counter-svelte/).
7
- *
8
- * @example
9
- *
10
- * ```svelte
11
- * // App.svelte
12
- * <script lang="ts">
13
- * import { Repo } from "@automerge/automerge-repo"
14
- * import Counter from './lib/Counter.svelte'
15
- * import { setContextRepo } from "@automerge/automerge-repo-svelte-store"
16
- *
17
- * const repo = new Repo({storage: new SomeStorage() })
18
- *
19
- * // Make the `Repo` available to child components (via Svelte's `setContext`).
20
- * setContextRepo(repo)
21
- *
22
- * const docId = repo.create()
23
- * </script>
24
- *
25
- * <main>
26
- * <div class="card">
27
- * <Counter {docId}/>
28
- * </div>
29
- * </main>
30
- * ```
31
- *
32
- *
33
- * ```svelte
34
- * // Counter.svelte`
35
- * <script lang="ts">
36
- * import type { DocumentId } from "@automerge/automerge-repo"
37
- * import { document } from "@automerge/automerge-repo-svelte-store"
38
- *
39
- * export let docId: DocumentId
40
- *
41
- * // `document` calls `getContextRepo` internally to access the closest `Repo`.
42
- * // alternatively, you may pass in a specific repo as the second parameter
43
- * const doc = document<{count?: number}>(docId)
44
- * const increment = () => {
45
- * doc.change((d) => d.count = (d.count || 0) + 1)
46
- * }
47
- * </script>
48
- *
49
- * <button on:click={increment}>
50
- * count is {$doc?.count || 0}
51
- * </button>
52
- * ```
53
- *
54
- * ## Contributors
55
- * Originally written by Dylan MacKenzie ([@ecstatic-morse](https://github.com/ecstatic-morse)).
56
- * * @packageDocumentation
57
- **/
58
- import type { ChangeFn, Doc } from "@automerge/automerge/slim/next";
59
- import { AutomergeUrl, Repo } from "@automerge/automerge-repo/slim";
60
- export declare function getContextRepo(): Repo;
4
+ * Set the Automerge Repo in the Svelte context
5
+ * @param repo The Automerge Repo instance
6
+ */
61
7
  export declare function setContextRepo(repo: Repo): void;
62
8
  /**
63
- * A Svelte store for an Automerge document.
64
- *
65
- * @param {AutomergeUrl} documentId - The Automerge document ID
66
- * @param {Repo=} repo - (Optional) The Automerge repo to use. If not provided, the repo will be retrieved from context.
67
- *
68
- * @returns A Svelte store for the Automerge document.
9
+ * Get the Automerge Repo from the Svelte context
10
+ * @returns The Automerge Repo instance
11
+ */
12
+ export declare function getContextRepo(): Repo;
13
+ /**
14
+ * The Automerge document store interface
69
15
  */
70
- export declare function document<T>(documentId: AutomergeUrl, repo?: Repo): {
71
- subscribe: (this: void, run: import("svelte/store").Subscriber<Doc<T>>, invalidate?: import("svelte/store").Invalidator<Doc<T>> | undefined) => import("svelte/store").Unsubscriber;
72
- change: (fn: ChangeFn<T>) => void;
16
+ export interface AutomergeDocumentStore<T> extends Writable<Doc<T> | null> {
17
+ /**
18
+ * Make changes to the document
19
+ * @param changeFn Function that modifies the document
20
+ */
21
+ change(changeFn: ChangeFn<T>): void;
22
+ /**
23
+ * The URL of the document
24
+ */
25
+ readonly url: AutomergeUrl;
26
+ /**
27
+ * The ID of the document
28
+ */
29
+ readonly documentId: DocumentId;
30
+ /**
31
+ * The underlying Automerge document handle
32
+ */
33
+ readonly handle: DocHandle<T>;
34
+ }
35
+ /**
36
+ * Creates an Automerge-repo store using standard Svelte stores
37
+ * @param repo A configured Automerge Repo instance
38
+ * @returns API for interacting with Automerge-repo
39
+ */
40
+ export declare function createAutomergeStore(repo: Repo): {
41
+ find: <T>(automergeUrl: AutomergeUrl) => Promise<AutomergeDocumentStore<T> | null>;
42
+ create: <T>(initialContent?: any) => Promise<AutomergeDocumentStore<T>>;
43
+ delete: (automergeUrl: AutomergeUrl) => Promise<void>;
44
+ getRepo: () => Repo;
73
45
  };
74
- //# sourceMappingURL=index.d.ts.map
46
+ /**
47
+ * Create a document store from a document ID or URL
48
+ * Uses the repo from context if no repo is provided
49
+ * @param docIdOrUrl The document ID or URL
50
+ * @param repoInstance Optional Automerge Repo instance
51
+ * @returns A promise resolving to the document store
52
+ */
53
+ export declare function document<T>(docIdOrUrl: DocumentId | AutomergeUrl, repoInstance?: Repo): Promise<AutomergeDocumentStore<T> | null>;
package/dist/index.js CHANGED
@@ -1,89 +1,112 @@
1
- /**
2
- * # Svelte store for Automerge Repo
3
- *
4
- * ## Example Usage
5
- *
6
- * For a working example, see the [Svelte counter demo](../automerge-repo-demo-counter-svelte/).
7
- *
8
- * @example
9
- *
10
- * ```svelte
11
- * // App.svelte
12
- * <script lang="ts">
13
- * import { Repo } from "@automerge/automerge-repo"
14
- * import Counter from './lib/Counter.svelte'
15
- * import { setContextRepo } from "@automerge/automerge-repo-svelte-store"
16
- *
17
- * const repo = new Repo({storage: new SomeStorage() })
18
- *
19
- * // Make the `Repo` available to child components (via Svelte's `setContext`).
20
- * setContextRepo(repo)
21
- *
22
- * const docId = repo.create()
23
- * </script>
24
- *
25
- * <main>
26
- * <div class="card">
27
- * <Counter {docId}/>
28
- * </div>
29
- * </main>
30
- * ```
31
- *
32
- *
33
- * ```svelte
34
- * // Counter.svelte`
35
- * <script lang="ts">
36
- * import type { DocumentId } from "@automerge/automerge-repo"
37
- * import { document } from "@automerge/automerge-repo-svelte-store"
38
- *
39
- * export let docId: DocumentId
40
- *
41
- * // `document` calls `getContextRepo` internally to access the closest `Repo`.
42
- * // alternatively, you may pass in a specific repo as the second parameter
43
- * const doc = document<{count?: number}>(docId)
44
- * const increment = () => {
45
- * doc.change((d) => d.count = (d.count || 0) + 1)
46
- * }
47
- * </script>
48
- *
49
- * <button on:click={increment}>
50
- * count is {$doc?.count || 0}
51
- * </button>
52
- * ```
53
- *
54
- * ## Contributors
55
- * Originally written by Dylan MacKenzie ([@ecstatic-morse](https://github.com/ecstatic-morse)).
56
- * * @packageDocumentation
57
- **/
58
1
  import { getContext, setContext } from "svelte";
59
2
  import { writable } from "svelte/store";
60
- const ContextRepoKey = Symbol("svelte-context-automerge-repo");
61
- export function getContextRepo() {
62
- return getContext(ContextRepoKey);
63
- }
3
+ // Store the repo in context for easy access
4
+ const REPO_CONTEXT_KEY = Symbol("automerge-repo");
5
+ /**
6
+ * Set the Automerge Repo in the Svelte context
7
+ * @param repo The Automerge Repo instance
8
+ */
64
9
  export function setContextRepo(repo) {
65
- setContext(ContextRepoKey, repo);
10
+ setContext(REPO_CONTEXT_KEY, repo);
66
11
  }
67
12
  /**
68
- * A Svelte store for an Automerge document.
69
- *
70
- * @param {AutomergeUrl} documentId - The Automerge document ID
71
- * @param {Repo=} repo - (Optional) The Automerge repo to use. If not provided, the repo will be retrieved from context.
72
- *
73
- * @returns A Svelte store for the Automerge document.
13
+ * Get the Automerge Repo from the Svelte context
14
+ * @returns The Automerge Repo instance
74
15
  */
75
- export function document(documentId, repo) {
76
- repo = repo ?? getContextRepo();
77
- const handle = repo.find(documentId);
78
- const { set, subscribe } = writable(handle.docSync(), () => {
79
- const onChange = (h) => set(h.doc);
80
- handle.addListener("change", onChange);
81
- return () => handle.removeListener("change", onChange);
82
- });
16
+ export function getContextRepo() {
17
+ const repo = getContext(REPO_CONTEXT_KEY);
18
+ if (!repo) {
19
+ throw new Error("No Automerge Repo found in context. Did you call setContextRepo?");
20
+ }
21
+ return repo;
22
+ }
23
+ /**
24
+ * Creates an Automerge-repo store using standard Svelte stores
25
+ * @param repo A configured Automerge Repo instance
26
+ * @returns API for interacting with Automerge-repo
27
+ */
28
+ export function createAutomergeStore(repo) {
29
+ if (!repo) {
30
+ throw new Error("A Repo instance is required");
31
+ }
32
+ /**
33
+ * Find a document by URL and create a reactive wrapper
34
+ */
35
+ const find = async (automergeUrl) => {
36
+ const handle = await repo.find(automergeUrl);
37
+ if (!handle)
38
+ return null;
39
+ return createDocumentStore(handle);
40
+ };
41
+ /**
42
+ * Create a new document and wrap it with reactive state
43
+ */
44
+ const create = async (initialContent = {}) => {
45
+ const handle = await repo.create(initialContent);
46
+ return createDocumentStore(handle);
47
+ };
48
+ /**
49
+ * Delete a document
50
+ */
51
+ const deleteDocument = async (automergeUrl) => {
52
+ repo.delete(automergeUrl);
53
+ };
54
+ /**
55
+ * Create a reactive document store for a handle
56
+ */
57
+ function createDocumentStore(handle) {
58
+ // Create a writable store with the current document
59
+ const { subscribe, set } = writable(handle.doc());
60
+ // Set up change listener
61
+ const onChange = ({ doc }) => {
62
+ set(doc);
63
+ };
64
+ // Subscribe to changes
65
+ handle.on("change", onChange);
66
+ // Create the store implementation
67
+ const store = {
68
+ subscribe,
69
+ set,
70
+ update: updater => {
71
+ const currentDoc = handle.doc();
72
+ const newValue = updater(currentDoc);
73
+ set(newValue);
74
+ },
75
+ // Method to make changes to the document
76
+ change(changeFn) {
77
+ return handle.change(changeFn);
78
+ },
79
+ // Metadata accessors
80
+ get url() {
81
+ return handle.url;
82
+ },
83
+ get documentId() {
84
+ return handle.documentId;
85
+ },
86
+ // Access to the underlying handle
87
+ get handle() {
88
+ return handle;
89
+ },
90
+ };
91
+ return store;
92
+ }
93
+ // Return the store API
83
94
  return {
84
- subscribe,
85
- change: (fn) => {
86
- handle.change(fn);
87
- },
95
+ find,
96
+ create,
97
+ delete: deleteDocument,
98
+ getRepo: () => repo,
88
99
  };
89
100
  }
101
+ /**
102
+ * Create a document store from a document ID or URL
103
+ * Uses the repo from context if no repo is provided
104
+ * @param docIdOrUrl The document ID or URL
105
+ * @param repoInstance Optional Automerge Repo instance
106
+ * @returns A promise resolving to the document store
107
+ */
108
+ export function document(docIdOrUrl, repoInstance) {
109
+ const repo = repoInstance || getContextRepo();
110
+ const store = createAutomergeStore(repo);
111
+ return store.find(docIdOrUrl);
112
+ }
package/package.json CHANGED
@@ -1,21 +1,35 @@
1
1
  {
2
2
  "name": "@automerge/automerge-repo-svelte-store",
3
- "version": "2.0.0-collectionsync-alpha.1",
4
- "description": "A Svelte store containing your automerge documentsj",
3
+ "version": "2.0.0",
4
+ "description": "A Svelte store containing your automerge documents",
5
5
  "repository": "https://github.com/automerge/automerge-repo/tree/master/packages/automerge-repo-svelte-store",
6
6
  "license": "MIT",
7
7
  "type": "module",
8
8
  "main": "dist/index.js",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "svelte": "./dist/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "src"
19
+ ],
9
20
  "scripts": {
10
- "build": "tsc",
11
- "watch": "npm-watch build"
21
+ "build": "svelte-package",
22
+ "watch": "svelte-package --watch"
12
23
  },
13
24
  "peerDependencies": {
14
- "@automerge/automerge": "^2.2.8",
15
- "svelte": "^3.0.0 || ^4.0.0"
25
+ "svelte": "^3.0.0 || ^4.0.0 || ^5.0.0"
16
26
  },
17
27
  "dependencies": {
18
- "@automerge/automerge-repo": "2.0.0-collectionsync-alpha.1"
28
+ "@automerge/automerge-repo": "2.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "@sveltejs/package": "^2.3.11",
32
+ "typescript": "^5.0.0"
19
33
  },
20
34
  "watch": {
21
35
  "build": {
@@ -28,5 +42,5 @@
28
42
  "publishConfig": {
29
43
  "access": "public"
30
44
  },
31
- "gitHead": "0a639a7d57bcee4e0a87890e6592b9582c2a5d6f"
45
+ "gitHead": "670d9e0d9d52451453e60a6b64e74c146f1f959c"
32
46
  }
@@ -0,0 +1,175 @@
1
+ import type {
2
+ AutomergeUrl,
3
+ ChangeFn,
4
+ Doc,
5
+ DocHandle,
6
+ DocumentId,
7
+ Repo,
8
+ } from "@automerge/automerge-repo/slim"
9
+
10
+ import { getContext, setContext } from "svelte"
11
+ import { writable, type Writable } from "svelte/store"
12
+
13
+ // Store the repo in context for easy access
14
+ const REPO_CONTEXT_KEY = Symbol("automerge-repo")
15
+
16
+ /**
17
+ * Set the Automerge Repo in the Svelte context
18
+ * @param repo The Automerge Repo instance
19
+ */
20
+ export function setContextRepo(repo: Repo): void {
21
+ setContext(REPO_CONTEXT_KEY, repo)
22
+ }
23
+
24
+ /**
25
+ * Get the Automerge Repo from the Svelte context
26
+ * @returns The Automerge Repo instance
27
+ */
28
+ export function getContextRepo(): Repo {
29
+ const repo = getContext<Repo>(REPO_CONTEXT_KEY)
30
+ if (!repo) {
31
+ throw new Error(
32
+ "No Automerge Repo found in context. Did you call setContextRepo?"
33
+ )
34
+ }
35
+ return repo
36
+ }
37
+
38
+ /**
39
+ * The Automerge document store interface
40
+ */
41
+ export interface AutomergeDocumentStore<T> extends Writable<Doc<T> | null> {
42
+ /**
43
+ * Make changes to the document
44
+ * @param changeFn Function that modifies the document
45
+ */
46
+ change(changeFn: ChangeFn<T>): void
47
+
48
+ /**
49
+ * The URL of the document
50
+ */
51
+ readonly url: AutomergeUrl
52
+
53
+ /**
54
+ * The ID of the document
55
+ */
56
+ readonly documentId: DocumentId
57
+
58
+ /**
59
+ * The underlying Automerge document handle
60
+ */
61
+ readonly handle: DocHandle<T>
62
+ }
63
+
64
+ /**
65
+ * Creates an Automerge-repo store using standard Svelte stores
66
+ * @param repo A configured Automerge Repo instance
67
+ * @returns API for interacting with Automerge-repo
68
+ */
69
+ export function createAutomergeStore(repo: Repo) {
70
+ if (!repo) {
71
+ throw new Error("A Repo instance is required")
72
+ }
73
+
74
+ /**
75
+ * Find a document by URL and create a reactive wrapper
76
+ */
77
+ const find = async <T>(
78
+ automergeUrl: AutomergeUrl
79
+ ): Promise<AutomergeDocumentStore<T> | null> => {
80
+ const handle = await repo.find<T>(automergeUrl)
81
+ if (!handle) return null
82
+ return createDocumentStore<T>(handle)
83
+ }
84
+
85
+ /**
86
+ * Create a new document and wrap it with reactive state
87
+ */
88
+ const create = async <T>(
89
+ initialContent: any = {}
90
+ ): Promise<AutomergeDocumentStore<T>> => {
91
+ const handle = await repo.create<T>(initialContent)
92
+ return createDocumentStore<T>(handle)
93
+ }
94
+
95
+ /**
96
+ * Delete a document
97
+ */
98
+ const deleteDocument = async (automergeUrl: AutomergeUrl) => {
99
+ repo.delete(automergeUrl)
100
+ }
101
+
102
+ /**
103
+ * Create a reactive document store for a handle
104
+ */
105
+ function createDocumentStore<T>(
106
+ handle: DocHandle<T>
107
+ ): AutomergeDocumentStore<T> {
108
+ // Create a writable store with the current document
109
+ const { subscribe, set } = writable<Doc<T> | null>(handle.doc())
110
+
111
+ // Set up change listener
112
+ const onChange = ({ doc }: { doc: Doc<T> }) => {
113
+ set(doc)
114
+ }
115
+
116
+ // Subscribe to changes
117
+ handle.on("change", onChange)
118
+
119
+ // Create the store implementation
120
+ const store: AutomergeDocumentStore<T> = {
121
+ subscribe,
122
+ set,
123
+ update: updater => {
124
+ const currentDoc = handle.doc()
125
+ const newValue = updater(currentDoc)
126
+ set(newValue)
127
+ },
128
+
129
+ // Method to make changes to the document
130
+ change(changeFn: ChangeFn<T>) {
131
+ return handle.change(changeFn)
132
+ },
133
+
134
+ // Metadata accessors
135
+ get url() {
136
+ return handle.url
137
+ },
138
+
139
+ get documentId() {
140
+ return handle.documentId
141
+ },
142
+
143
+ // Access to the underlying handle
144
+ get handle() {
145
+ return handle
146
+ },
147
+ }
148
+
149
+ return store
150
+ }
151
+
152
+ // Return the store API
153
+ return {
154
+ find,
155
+ create,
156
+ delete: deleteDocument,
157
+ getRepo: () => repo,
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Create a document store from a document ID or URL
163
+ * Uses the repo from context if no repo is provided
164
+ * @param docIdOrUrl The document ID or URL
165
+ * @param repoInstance Optional Automerge Repo instance
166
+ * @returns A promise resolving to the document store
167
+ */
168
+ export function document<T>(
169
+ docIdOrUrl: DocumentId | AutomergeUrl,
170
+ repoInstance?: Repo
171
+ ): Promise<AutomergeDocumentStore<T> | null> {
172
+ const repo = repoInstance || getContextRepo()
173
+ const store = createAutomergeStore(repo)
174
+ return store.find<T>(docIdOrUrl as AutomergeUrl)
175
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwDI;AAEJ,OAAO,KAAK,EAAE,QAAQ,EAAE,GAAG,EAAE,MAAM,gCAAgC,CAAA;AACnE,OAAO,EACL,YAAY,EAEZ,IAAI,EACL,MAAM,gCAAgC,CAAA;AAMvC,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,IAAI,QAExC;AAED;;;;;;;GAOG;AAEH,wBAAgB,QAAQ,CAAC,CAAC,EAAE,UAAU,EAAE,YAAY,EAAE,IAAI,CAAC,EAAE,IAAI;;iBAWhD,QAAQ,CAAC,CAAC,CAAC;EAI3B"}
package/src/index.ts DELETED
@@ -1,102 +0,0 @@
1
- /**
2
- * # Svelte store for Automerge Repo
3
- *
4
- * ## Example Usage
5
- *
6
- * For a working example, see the [Svelte counter demo](../automerge-repo-demo-counter-svelte/).
7
- *
8
- * @example
9
- *
10
- * ```svelte
11
- * // App.svelte
12
- * <script lang="ts">
13
- * import { Repo } from "@automerge/automerge-repo"
14
- * import Counter from './lib/Counter.svelte'
15
- * import { setContextRepo } from "@automerge/automerge-repo-svelte-store"
16
- *
17
- * const repo = new Repo({storage: new SomeStorage() })
18
- *
19
- * // Make the `Repo` available to child components (via Svelte's `setContext`).
20
- * setContextRepo(repo)
21
- *
22
- * const docId = repo.create()
23
- * </script>
24
- *
25
- * <main>
26
- * <div class="card">
27
- * <Counter {docId}/>
28
- * </div>
29
- * </main>
30
- * ```
31
- *
32
- *
33
- * ```svelte
34
- * // Counter.svelte`
35
- * <script lang="ts">
36
- * import type { DocumentId } from "@automerge/automerge-repo"
37
- * import { document } from "@automerge/automerge-repo-svelte-store"
38
- *
39
- * export let docId: DocumentId
40
- *
41
- * // `document` calls `getContextRepo` internally to access the closest `Repo`.
42
- * // alternatively, you may pass in a specific repo as the second parameter
43
- * const doc = document<{count?: number}>(docId)
44
- * const increment = () => {
45
- * doc.change((d) => d.count = (d.count || 0) + 1)
46
- * }
47
- * </script>
48
- *
49
- * <button on:click={increment}>
50
- * count is {$doc?.count || 0}
51
- * </button>
52
- * ```
53
- *
54
- * ## Contributors
55
- * Originally written by Dylan MacKenzie ([@ecstatic-morse](https://github.com/ecstatic-morse)).
56
- * * @packageDocumentation
57
- **/
58
-
59
- import type { ChangeFn, Doc } from "@automerge/automerge/slim/next"
60
- import {
61
- AutomergeUrl,
62
- DocHandleChangePayload,
63
- Repo,
64
- } from "@automerge/automerge-repo/slim"
65
- import { getContext, setContext } from "svelte"
66
- import { writable } from "svelte/store"
67
-
68
- const ContextRepoKey = Symbol("svelte-context-automerge-repo")
69
-
70
- export function getContextRepo(): Repo {
71
- return getContext<Repo>(ContextRepoKey)
72
- }
73
-
74
- export function setContextRepo(repo: Repo) {
75
- setContext(ContextRepoKey, repo)
76
- }
77
-
78
- /**
79
- * A Svelte store for an Automerge document.
80
- *
81
- * @param {AutomergeUrl} documentId - The Automerge document ID
82
- * @param {Repo=} repo - (Optional) The Automerge repo to use. If not provided, the repo will be retrieved from context.
83
- *
84
- * @returns A Svelte store for the Automerge document.
85
- */
86
-
87
- export function document<T>(documentId: AutomergeUrl, repo?: Repo) {
88
- repo = repo ?? getContextRepo()
89
- const handle = repo.find<T>(documentId)
90
- const { set, subscribe } = writable<Doc<T>>(handle.docSync(), () => {
91
- const onChange = (h: DocHandleChangePayload<T>) => set(h.doc)
92
- handle.addListener("change", onChange)
93
- return () => handle.removeListener("change", onChange)
94
- })
95
-
96
- return {
97
- subscribe,
98
- change: (fn: ChangeFn<T>) => {
99
- handle.change(fn)
100
- },
101
- }
102
- }
package/tsconfig.json DELETED
@@ -1,16 +0,0 @@
1
- {
2
- "compilerOptions": {
3
- "target": "ESNext",
4
- "jsx": "react",
5
- "module": "NodeNext",
6
- "moduleResolution": "Node16",
7
- "declaration": true,
8
- "declarationMap": true,
9
- "outDir": "./dist",
10
- "esModuleInterop": true,
11
- "forceConsistentCasingInFileNames": true,
12
- "strict": true,
13
- "skipLibCheck": true
14
- },
15
- "include": ["src/**/*.ts"]
16
- }
package/typedoc.json DELETED
@@ -1,5 +0,0 @@
1
- {
2
- "extends": ["../../typedoc.base.json"],
3
- "entryPoints": ["src/index.ts"],
4
- "readme": "none"
5
- }