@verdant-web/tiptap 5.0.2 → 6.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.
@@ -1,7 +1,15 @@
1
- import type { Server } from '@verdant-web/server';
1
+ import type { LibraryApi } from '@verdant-web/server';
2
2
  export { VerdantMediaRendererExtension } from '../extensions/VerdantMediaRenderer.js';
3
3
  /**
4
4
  * Attaches file URLs to all Verdant media nodes in the document, according
5
5
  * to the file service attached to your Verdant server.
6
6
  */
7
- export declare function attachFileUrls(document: any, libraryId: string, server: Server): Promise<any>;
7
+ export declare function attachFileUrls(document: any, libraryId: string, libraryApi: LibraryApi): Promise<any>;
8
+ declare global {
9
+ interface WebSocket {
10
+ close(): void;
11
+ send(data: string | ArrayBuffer | SharedArrayBuffer | Blob | ArrayBufferView): void;
12
+ addEventListener(type: string, listener: (this: WebSocket, ev: any) => any, options?: any): void;
13
+ removeEventListener(type: string, listener: (this: WebSocket, ev: any) => any, options?: any): void;
14
+ }
15
+ }
@@ -4,15 +4,15 @@ export { VerdantMediaRendererExtension } from '../extensions/VerdantMediaRendere
4
4
  * Attaches file URLs to all Verdant media nodes in the document, according
5
5
  * to the file service attached to your Verdant server.
6
6
  */
7
- export async function attachFileUrls(document, libraryId, server) {
8
- await visitNode(document, libraryId, server);
7
+ export async function attachFileUrls(document, libraryId, libraryApi) {
8
+ await visitNode(document, libraryId, libraryApi);
9
9
  return document;
10
10
  }
11
11
  async function visitNode(node, libraryId, server) {
12
12
  if (node.type === 'verdant-media') {
13
13
  const fileId = node.attrs[fileIdAttribute];
14
14
  if (fileId) {
15
- const file = await server.getFileData(libraryId, fileId);
15
+ const file = await server.getFileInfo(fileId);
16
16
  if (file) {
17
17
  node.attrs.src = file.url;
18
18
  node.attrs[fileTypeAttribute] = file.type;
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,QAAa,EACb,SAAiB,EACjB,MAAc;IAEd,MAAM,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;IAC7C,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAS,EAAE,SAAiB,EAAE,MAAc;IACpE,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;YACzD,IAAI,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;YACvC,CAAC;QACF,CAAC;IACF,CAAC;SAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,OAAO,CAAC,GAAG,CAChB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CACrE,CAAC;IACH,CAAC;AACF,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AACA,OAAO,EACN,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GACjB,MAAM,6BAA6B,CAAC;AAErC,OAAO,EAAE,6BAA6B,EAAE,MAAM,uCAAuC,CAAC;AAEtF;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CACnC,QAAa,EACb,SAAiB,EACjB,UAAsB;IAEtB,MAAM,SAAS,CAAC,QAAQ,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IACjD,OAAO,QAAQ,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,SAAS,CAAC,IAAS,EAAE,SAAiB,EAAE,MAAkB;IACxE,IAAI,IAAI,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;QACnC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,CAAC;QAC3C,IAAI,MAAM,EAAE,CAAC;YACZ,MAAM,IAAI,GAAG,MAAM,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;YAC9C,IAAI,IAAI,EAAE,CAAC;gBACV,IAAI,CAAC,KAAK,CAAC,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC;gBAC1B,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,iBAAiB,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC;gBAC1C,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC;YACvC,CAAC;QACF,CAAC;IACF,CAAC;SAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACzB,MAAM,OAAO,CAAC,GAAG,CAChB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAU,EAAE,EAAE,CAAC,SAAS,CAAC,KAAK,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC,CACrE,CAAC;IACH,CAAC;AACF,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Recursively removes null values from an object snapshot. This can
3
+ * be used to delete empty subfields from a document field to conform
4
+ * to TipTap's schema.
5
+ */
6
+ export declare function removeNulls<TObject extends object>(obj: TObject): WithoutNulls<TObject>;
7
+ export type WithoutNulls<TObject> = TObject extends object ? {
8
+ [P in keyof TObject]: WithoutNulls<TObject[P]>;
9
+ } : TObject extends null ? Exclude<TObject, null> | undefined : TObject;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Recursively removes null values from an object snapshot. This can
3
+ * be used to delete empty subfields from a document field to conform
4
+ * to TipTap's schema.
5
+ */
6
+ export function removeNulls(obj) {
7
+ const newObj = {};
8
+ if (Array.isArray(obj)) {
9
+ return obj.map((item) => removeNulls(item));
10
+ }
11
+ for (const key in obj) {
12
+ if (obj[key] !== null) {
13
+ if (typeof obj[key] === 'object') {
14
+ newObj[key] = removeNulls(obj[key]);
15
+ }
16
+ else {
17
+ newObj[key] = obj[key];
18
+ }
19
+ }
20
+ }
21
+ return newObj;
22
+ }
23
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/utils.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAC1B,GAAY;IAEZ,MAAM,MAAM,GAAG,EAAS,CAAC;IACzB,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;QACxB,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,WAAW,CAAC,IAAI,CAAC,CAAQ,CAAC;IACpD,CAAC;IACD,KAAK,MAAM,GAAG,IAAI,GAAG,EAAE,CAAC;QACvB,IAAI,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,EAAE,CAAC;YACvB,IAAI,OAAO,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ,EAAE,CAAC;gBAClC,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;YACrC,CAAC;iBAAM,CAAC;gBACP,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;YACxB,CAAC;QACF,CAAC;IACF,CAAC;IACD,OAAO,MAAM,CAAC;AACf,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@verdant-web/tiptap",
3
- "version": "5.0.2",
3
+ "version": "6.0.0",
4
4
  "access": "public",
5
5
  "type": "module",
6
6
  "main": "dist/esm/index.js",
@@ -30,8 +30,8 @@
30
30
  "@tiptap/pm": "^2.11.5",
31
31
  "@tiptap/react": "^2.11.5",
32
32
  "react": "^19.0.0",
33
- "@verdant-web/react": "42.1.0",
34
- "@verdant-web/store": "4.5.2"
33
+ "@verdant-web/react": "42.1.1",
34
+ "@verdant-web/store": "4.6.0"
35
35
  },
36
36
  "peerDependenciesMeta": {
37
37
  "@verdant-web/store": {
@@ -48,7 +48,7 @@
48
48
  }
49
49
  },
50
50
  "dependencies": {
51
- "@verdant-web/common": "2.9.1"
51
+ "@verdant-web/common": "3.0.0"
52
52
  },
53
53
  "devDependencies": {
54
54
  "@hono/node-server": "1.14.0",
@@ -57,23 +57,23 @@
57
57
  "@tiptap/pm": "^2.11.5",
58
58
  "@tiptap/react": "^2.11.5",
59
59
  "@tiptap/starter-kit": "^2.11.5",
60
- "@types/react": "19.0.10",
61
- "@types/react-dom": "19.0.4",
60
+ "@types/react": "19.1.16",
61
+ "@types/react-dom": "19.1.9",
62
62
  "@vitejs/plugin-basic-ssl": "2.0.0",
63
- "@vitejs/plugin-react": "4.3.4",
64
- "@vitest/browser": "3.2.0",
63
+ "@vitejs/plugin-react": "5.0.4",
64
+ "@vitest/browser": "3.2.4",
65
65
  "hono": "4.7.5",
66
- "playwright": "1.52.0",
67
- "react": "19.0.0",
68
- "react-dom": "19.0.0",
69
- "typescript": "5.7.3",
70
- "vite": "6.1.1",
71
- "vitest": "3.2.0",
72
- "vitest-browser-react": "0.1.1",
73
- "@verdant-web/cli": "4.8.2",
74
- "@verdant-web/react": "42.1.0",
75
- "@verdant-web/server": "3.3.11",
76
- "@verdant-web/store": "4.5.2"
66
+ "playwright": "1.55.1",
67
+ "react": "19.1.1",
68
+ "react-dom": "19.1.1",
69
+ "typescript": "5.9.3",
70
+ "vite": "7.1.7",
71
+ "vitest": "3.2.4",
72
+ "vitest-browser-react": "1.0.1",
73
+ "@verdant-web/cli": "4.8.3",
74
+ "@verdant-web/react": "42.1.1",
75
+ "@verdant-web/server": "4.0.0",
76
+ "@verdant-web/store": "4.6.0"
77
77
  },
78
78
  "scripts": {
79
79
  "test": "vitest",
@@ -1,4 +1,4 @@
1
- import type { Server } from '@verdant-web/server';
1
+ import type { LibraryApi } from '@verdant-web/server';
2
2
  import {
3
3
  fileIdAttribute,
4
4
  fileNameAttribute,
@@ -14,17 +14,17 @@ export { VerdantMediaRendererExtension } from '../extensions/VerdantMediaRendere
14
14
  export async function attachFileUrls(
15
15
  document: any,
16
16
  libraryId: string,
17
- server: Server,
17
+ libraryApi: LibraryApi,
18
18
  ) {
19
- await visitNode(document, libraryId, server);
19
+ await visitNode(document, libraryId, libraryApi);
20
20
  return document;
21
21
  }
22
22
 
23
- async function visitNode(node: any, libraryId: string, server: Server) {
23
+ async function visitNode(node: any, libraryId: string, server: LibraryApi) {
24
24
  if (node.type === 'verdant-media') {
25
25
  const fileId = node.attrs[fileIdAttribute];
26
26
  if (fileId) {
27
- const file = await server.getFileData(libraryId, fileId);
27
+ const file = await server.getFileInfo(fileId);
28
28
  if (file) {
29
29
  node.attrs.src = file.url;
30
30
  node.attrs[fileTypeAttribute] = file.type;
@@ -38,3 +38,26 @@ async function visitNode(node: any, libraryId: string, server: Server) {
38
38
  );
39
39
  }
40
40
  }
41
+
42
+ // provide minimal WebSocket typings for Node.js environment
43
+ // so we can use the same codebase for both Cloudflare and Node.js
44
+ // without running into typing issues
45
+ // (these are just the methods we actually use)
46
+ declare global {
47
+ interface WebSocket {
48
+ close(): void;
49
+ send(
50
+ data: string | ArrayBuffer | SharedArrayBuffer | Blob | ArrayBufferView,
51
+ ): void;
52
+ addEventListener(
53
+ type: string,
54
+ listener: (this: WebSocket, ev: any) => any,
55
+ options?: any,
56
+ ): void;
57
+ removeEventListener(
58
+ type: string,
59
+ listener: (this: WebSocket, ev: any) => any,
60
+ options?: any,
61
+ ): void;
62
+ }
63
+ }
package/src/utils.ts ADDED
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Recursively removes null values from an object snapshot. This can
3
+ * be used to delete empty subfields from a document field to conform
4
+ * to TipTap's schema.
5
+ */
6
+ export function removeNulls<TObject extends object>(
7
+ obj: TObject,
8
+ ): WithoutNulls<TObject> {
9
+ const newObj = {} as any;
10
+ if (Array.isArray(obj)) {
11
+ return obj.map((item) => removeNulls(item)) as any;
12
+ }
13
+ for (const key in obj) {
14
+ if (obj[key] !== null) {
15
+ if (typeof obj[key] === 'object') {
16
+ newObj[key] = removeNulls(obj[key]);
17
+ } else {
18
+ newObj[key] = obj[key];
19
+ }
20
+ }
21
+ }
22
+ return newObj;
23
+ }
24
+
25
+ export type WithoutNulls<TObject> = TObject extends object
26
+ ? {
27
+ [P in keyof TObject]: WithoutNulls<TObject[P]>;
28
+ }
29
+ : TObject extends null
30
+ ? Exclude<TObject, null> | undefined
31
+ : TObject;