cosveti-sync 0.0.1 → 0.0.3

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,6 +1,7 @@
1
1
  # cosveti-sync
2
2
 
3
- Real-time collaborative editing for TipTap in Svelte with Convex synchronization
3
+ Real-time collaborative editing for TipTap in Svelte with Convex synchronization.
4
+ Translated to svelte from [React version](https://github.com/get-convex/prosemirror-sync)
4
5
 
5
6
  ## Features
6
7
 
@@ -26,6 +27,9 @@ yarn add cosveti-sync
26
27
 
27
28
  # pnpm
28
29
  pnpm add cosveti-sync
30
+
31
+ # bun
32
+ bun install cosveti-sync
29
33
  ```
30
34
 
31
35
  This package has the following peer dependencies that you'll also need to install:
@@ -41,119 +45,33 @@ This package has the following peer dependencies that you'll also need to instal
41
45
  First, set up the backend API in your Convex project. Create a file like `convex/tiptapSync.ts`:
42
46
 
43
47
  ```typescript
44
- import { TiptapSyncSvelte } from 'cosveti-sync';
45
- import { defineComponent } from './_generated/server';
46
- import { api } from './_generated/api';
47
-
48
- // Initialize the component
49
- const tiptapSyncComponent = defineComponent('./component');
50
-
51
- // Create the sync instance
52
- const tiptapSyncSvelte = new TiptapSyncSvelte(tiptapSyncComponent);
53
-
54
- // Export the sync API with optional permission checks
55
- export const {
56
- getSnapshot,
57
- submitSnapshot,
58
- latestVersion,
59
- getSteps,
60
- submitSteps
61
- } = tiptapSyncSvelte.syncApi({
62
- // Optional: Add read/write permission checks
63
- checkRead: async (ctx, id) => {
64
- // Add your authorization logic here
65
- },
66
- checkWrite: async (ctx, id) => {
67
- // Add your authorization logic here
68
- },
69
- // Optional: Callback when a new snapshot is available
70
- onSnapshot: async (ctx, id, snapshot, version) => {
71
- // Do something when a new snapshot is saved
72
- }
73
- });
74
-
75
- // Export the API for the client to use
76
- export default {
77
- tiptapSyncSvelte
78
- };
48
+ import { TiptapSyncSvelte } from '../lib/client/index.js';
49
+ import { components } from './_generated/api.js';
50
+
51
+ const tiptapSyncSvelte = new TiptapSyncSvelte(components.tiptapSyncSvelte);
52
+ export const { getSnapshot, submitSnapshot, latestVersion, getSteps, submitSteps } =
53
+ tiptapSyncSvelte.syncApi();
54
+
79
55
  ```
80
56
 
81
- ### 2. Client-Side Usage
57
+ ### 2. Convex Config
82
58
 
83
- In your Svelte component, use the `useTiptapSync` hook:
59
+ First, set up the backend API in your Convex project. Create a file like `convex/convex.config.ts`:
84
60
 
85
- ```svelte
86
- <script lang="ts">
87
- import { useTiptapSync } from 'cosveti-sync';
88
- import { api } from '$convex/_generated/api';
89
- import { useConvexClient } from 'convex-svelte';
90
- import { Editor } from '@tiptap/core';
91
- import { StarterKit } from '@tiptap/starter-kit';
92
- import { onMount } from 'svelte';
93
-
94
- // Get the Convex client (assuming convex-svelte is set up)
95
- const convex = useConvexClient();
96
-
97
- // Initialize the sync functionality
98
- const { isSyncEnabled, extension, isLoading, initialContent, create } = $derived(
99
- useTiptapSync(
100
- convex,
101
- api.tiptapSyncSvelte,
102
- 'your-document-id', // Unique document ID
103
- {
104
- onSyncError: (error) => {
105
- console.error('Sync error:', error);
106
- },
107
- snapshotDebounceMs: 1000, // Debounce snapshot submissions (default: 1000ms)
108
- debug: false // Enable debug logging (default: false)
109
- }
110
- )
111
- );
112
-
113
- let editorContainer: HTMLElement;
114
- let editor: Editor;
115
-
116
- onMount(() => {
117
- if (!$extension) return;
118
-
119
- editor = new Editor({
120
- element: editorContainer,
121
- extensions: [
122
- StarterKit,
123
- $extension // Add the sync extension from useTiptapSync
124
- ],
125
- content: $initialContent
126
- });
127
- });
128
-
129
- function handleCreateDocument() {
130
- create({
131
- type: 'doc',
132
- content: [
133
- { type: 'paragraph', content: [{ type: 'text', text: 'Hello world!' }] }
134
- ]
135
- });
136
- }
137
- </script>
61
+ ```typescript
62
+ import { defineApp } from 'convex/server';
138
63
 
139
- {#if $isLoading}
140
- <div>Loading editor...</div>
141
- {:else if !$initialContent}
142
- <button on:click={handleCreateDocument}>
143
- Create New Document
144
- </button>
145
- {:else if $extension}
146
- <div>
147
- <button
148
- on:click={() => $isSyncEnabled.update(n => !n)}
149
- >
150
- {$isSyncEnabled ? 'Pause Sync' : 'Resume Sync'}
151
- </button>
152
- <div bind:this={editorContainer}></div>
153
- </div>
154
- {/if}
64
+ import tiptapSyncSvelte from '../lib/component/convex.config.js';
65
+
66
+ const app = defineApp();
67
+
68
+ app.use(tiptapSyncSvelte);
69
+
70
+ export default app;
155
71
  ```
156
72
 
73
+
74
+
157
75
  ## API Documentation
158
76
 
159
77
  ### `useTiptapSync()`
@@ -203,68 +121,53 @@ Here's a complete example showing how to integrate the library:
203
121
 
204
122
  ```svelte
205
123
  <script lang="ts">
206
- import { useTiptapSync } from 'cosveti-sync';
207
- import { api } from '$convex/_generated/api';
208
- import { useConvexClient } from 'convex-svelte';
209
- import { Editor } from '@tiptap/core';
210
- import { StarterKit } from '@tiptap/starter-kit';
211
- import { onMount, onDestroy } from 'svelte';
212
-
213
- const convex = useConvexClient();
214
- const documentId = 'my-shared-document';
215
-
216
- const {
217
- isSyncEnabled,
218
- extension,
219
- isLoading,
220
- initialContent,
221
- create
222
- } = $derived(
223
- useTiptapSync(convex, api.tiptapSyncSvelte, documentId)
224
- );
225
-
226
- let editorContainer: HTMLElement;
227
- let editor: Editor;
228
-
229
- $: if ($extension && $initialContent && !editor) {
230
- editor = new Editor({
231
- element: editorContainer,
232
- extensions: [
233
- StarterKit,
234
- $extension
235
- ],
236
- content: $initialContent
237
- });
238
- }
239
-
240
- onDestroy(() => {
241
- editor?.destroy();
242
- });
243
-
244
- function handleCreate() {
245
- create({
246
- type: 'doc',
247
- content: [{ type: 'paragraph', content: [{ type: 'text', text: 'New document' }] }]
248
- });
249
- }
124
+ import { useTiptapSync } from '$lib/index.js';
125
+ import { api } from '$convex/_generated/api.js';
126
+ import type { ConvexClient } from 'convex/browser';
127
+ import { useConvexClient } from 'convex-svelte';
128
+ import Editor from './Editor.svelte';
129
+
130
+ // This is if you have used convex-svelte pakage in +layout.svelte to setup the client
131
+ const convex: ConvexClient = useConvexClient();
132
+
133
+ const { isSyncEnabled, extension, isLoading, initialContent, create } = $derived(
134
+ useTiptapSync(convex, api.tiptapSyncSvelte, 'test-doc-id')
135
+ );
136
+
137
+ let editor = $state<Editor>();
250
138
  </script>
251
139
 
252
- <div class="editor-container">
253
- {#if $isLoading}
254
- <p>Loading...</p>
255
- {:else if !$initialContent}
256
- <button on:click={handleCreate}>Create Document</button>
257
- {:else if $extension}
258
- <div class="controls">
259
- <button
260
- on:click={() => $isSyncEnabled.update(enabled => !enabled)}
261
- >
262
- {$isSyncEnabled ? 'Pause Sync' : 'Resume Sync'}
263
- </button>
264
- </div>
265
- <div bind:this={editorContainer} class="editor"></div>
266
- {/if}
267
- </div>
140
+ {#if $isLoading}
141
+ Loading...
142
+ {:else if !$initialContent}
143
+ <button
144
+ onclick={() => {
145
+ create({ type: 'doc', content: [] });
146
+ }}
147
+ >Create doc
148
+ </button>
149
+ {:else if $extension != undefined}
150
+ <div class="py-4 text-center text-xl font-bold">
151
+ Shadcn Example
152
+ <button
153
+ onclick={() => {
154
+ isSyncEnabled.update((n) => !n);
155
+ console.log($isSyncEnabled);
156
+ }}
157
+ >
158
+ {#if $isSyncEnabled}Pause Sync{:else}Resume Sync{/if}
159
+ </button>
160
+ <div class="z-50 mt-12 size-full w-screen rounded-md border border-dashed bg-background">
161
+ <Editor
162
+ class="h-120 max-h-screen overflow-y-scroll pr-2 pl-6"
163
+ additionalExtensions={$extension}
164
+ content={$initialContent}
165
+ bind:editor
166
+ />
167
+ </div>
168
+ </div>
169
+ {/if}
170
+
268
171
  ```
269
172
 
270
173
  ## License
@@ -3,13 +3,13 @@ import type { ComponentApi } from '../component/_generated/component.js';
3
3
  import { Schema, Node } from '@tiptap/pm/model';
4
4
  import { Transform } from '@tiptap/pm/transform';
5
5
  export type SyncApi = ApiFromModules<{
6
- sync: ReturnType<TiptapSyncSvelte['syncApi']>;
6
+ sync: ReturnType<TiptapSyncClient['syncApi']>;
7
7
  }>['sync'];
8
8
  export type RunMutationCtx = {
9
9
  runMutation: GenericMutationCtx<GenericDataModel>['runMutation'];
10
10
  runQuery: GenericQueryCtx<GenericDataModel>['runQuery'];
11
11
  };
12
- export declare class TiptapSyncSvelte<Id extends string = string> {
12
+ export declare class TiptapSyncClient<Id extends string = string> {
13
13
  component: ComponentApi;
14
14
  /**
15
15
  * Backend API for the ProsemirrorSync component.
@@ -3,7 +3,7 @@ import { v } from 'convex/values';
3
3
  import { vClientId } from '../component/schema.js';
4
4
  import { Schema, Node } from '@tiptap/pm/model';
5
5
  import { Step, Transform } from '@tiptap/pm/transform';
6
- export class TiptapSyncSvelte {
6
+ export class TiptapSyncClient {
7
7
  component;
8
8
  /**
9
9
  * Backend API for the ProsemirrorSync component.
@@ -1,2 +1 @@
1
- declare const _default: import("convex/server").ComponentDefinition<any>;
2
- export default _default;
1
+ export declare const tiptapSyncConfig: import("convex/server").ComponentDefinition<any>;
@@ -1,2 +1,2 @@
1
1
  import { defineComponent } from 'convex/server';
2
- export default defineComponent('tiptapSyncSvelte');
2
+ export const tiptapSyncConfig = defineComponent('tiptapSyncSvelte');
package/dist/index.d.ts CHANGED
@@ -1,3 +1,5 @@
1
1
  export { useTiptapSync } from './tiptap/index.js';
2
+ export { TiptapSyncClient } from './client/index.js';
3
+ export { tiptapSyncConfig } from './component/convex.config.js';
2
4
  export type { UseSyncOptions, InitialState, SyncContext } from './tiptap/types.js';
3
5
  export type { SyncApi } from './client/index.js';
package/dist/index.js CHANGED
@@ -1,3 +1,5 @@
1
1
  // Reexport your entry components here
2
- // Main entry point for @feavel/svelte-convex-tiptap-sync package
2
+ // Main entry point for cosveti-sync package
3
3
  export { useTiptapSync } from './tiptap/index.js';
4
+ export { TiptapSyncClient } from './client/index.js';
5
+ export { tiptapSyncConfig } from './component/convex.config.js';
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "cosveti-sync",
3
3
  "description": "A convex component for syncing tiptap in a svelte project",
4
- "version": "0.0.1",
4
+ "version": "0.0.3",
5
5
  "scripts": {
6
6
  "dev": "vite dev",
7
7
  "build": "vite build && npm run prepack",