@fileverse-dev/ddoc 6.0.0-drop-in.2 → 6.0.0-drop-in.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.
@@ -3,7 +3,7 @@ var Wr = (t, e, O) => e in t ? Vr(t, e, { enumerable: !0, configurable: !0, writ
3
3
  var gt = (t, e, O) => Wr(t, typeof e != "symbol" ? e + "" : e, O);
4
4
  import { jsx as Cr } from "react/jsx-runtime";
5
5
  import { useRef as pe, useEffect as St } from "react";
6
- import { s as y, A as pO, T as dO, a as Gr, S as et, b as Lr, P as fO, E as j, i as QO, c as _, D as le, k as tt, F as Ar, M as Pt, W as Er, R as Ur, d as mO, N as oe, e as V, f as Mr, g as Ot, h as ce, p as $O, j as Y, t as h, l as Ir, I as rt, L as at, m as ye, n as ue, o as Qe, q as gO, r as te, u as SO, v as Br, w as Nr, x as PO, y as kO, z as Dr, B as Fr, C as Kr, G as Oe, H as ZO, J as Jr, K as kt, O as Hr, Q as ea, U as ta, V as Oa, X as ra, Y as aa, Z as ia, _ as sa, $ as na, a0 as la, a1 as oa, a2 as ca } from "./index-8MQH4TSF.mjs";
6
+ import { s as y, A as pO, T as dO, a as Gr, S as et, b as Lr, P as fO, E as j, i as QO, c as _, D as le, k as tt, F as Ar, M as Pt, W as Er, R as Ur, d as mO, N as oe, e as V, f as Mr, g as Ot, h as ce, p as $O, j as Y, t as h, l as Ir, I as rt, L as at, m as ye, n as ue, o as Qe, q as gO, r as te, u as SO, v as Br, w as Nr, x as PO, y as kO, z as Dr, B as Fr, C as Kr, G as Oe, H as ZO, J as Jr, K as kt, O as Hr, Q as ea, U as ta, V as Oa, X as ra, Y as aa, Z as ia, _ as sa, $ as na, a0 as la, a1 as oa, a2 as ca } from "./index-eP_xxZsk.mjs";
7
7
  class ua {
8
8
  /**
9
9
  Create a new completion context. (Mostly useful for testing
@@ -1,11 +1,13 @@
1
+ import { SchemaStampGuardEvent } from '../types';
1
2
  import * as Y from 'yjs';
2
3
  interface UseDocSchemaVersionArgs {
3
4
  ydoc: Y.Doc;
4
5
  isNewDdoc: boolean;
5
6
  isContentResolved: boolean;
6
7
  preferredSchemaVersion?: number;
8
+ onSchemaStampGuard?: (event: SchemaStampGuardEvent) => void;
7
9
  }
8
- export declare const useDocSchemaVersion: ({ ydoc, isNewDdoc, isContentResolved, preferredSchemaVersion, }: UseDocSchemaVersionArgs) => {
10
+ export declare const useDocSchemaVersion: ({ ydoc, isNewDdoc, isContentResolved, preferredSchemaVersion, onSchemaStampGuard, }: UseDocSchemaVersionArgs) => {
9
11
  docSchemaVersion: number;
10
12
  isSchemaUnsupported: boolean;
11
13
  };
@@ -0,0 +1,26 @@
1
+ import type * as ucans from '@ucans/ucans';
2
+ /**
3
+ * The collab server's clock, learned from its handshake. The server checks auth UCAN nbf/exp
4
+ * against its own clock, so tokens built from a skewed device clock get a 401.
5
+ */
6
+ export declare class ServerClock {
7
+ private readonly wallNow;
8
+ private readonly monoNow;
9
+ private anchor;
10
+ constructor(wallNow?: () => number, monoNow?: (() => number) | null);
11
+ /**
12
+ * Time since the handshake is measured on the monotonic clock, so a device clock change
13
+ * mid-session cannot skew it. A missing or implausible stamp (older server) falls back to the
14
+ * device clock. Delivery delay and sleep only make the estimate trail the server, which the
15
+ * token window absorbs.
16
+ */
17
+ sync(serverTimeMs: unknown): void;
18
+ nowSeconds(): number;
19
+ ucanWindow(): {
20
+ notBefore: number;
21
+ expiration: number;
22
+ };
23
+ /** Whether a cached UCAN can still be presented: active, and not expiring within the margin. */
24
+ isUsable(ucan: ucans.Ucan): boolean;
25
+ private elapsedBase;
26
+ }
@@ -74,6 +74,7 @@ export declare class SocketClient {
74
74
  private contractAddress?;
75
75
  private ownerUcan?;
76
76
  private collaborationUcan?;
77
+ private serverClock;
77
78
  private ownerAddress?;
78
79
  private ddocId?;
79
80
  private editLock?;
@@ -130,7 +131,6 @@ export declare class SocketClient {
130
131
  terminateSession: () => Promise<void>;
131
132
  flushBeacon(mergedUpdate: string): void;
132
133
  private getCollaborationKeyPair;
133
- private isUcanValid;
134
134
  private getOwnerToken;
135
135
  private buildSessionToken;
136
136
  private _authenticate;
@@ -143,6 +143,15 @@ export interface DdocProps extends CommentAccountProps {
143
143
  };
144
144
  tabSectionContainer?: HTMLElement;
145
145
  isCollabDocumentPublished?: boolean;
146
+ /**
147
+ * Storage-agnostic image fetch function. Receives the stored location of an
148
+ * encrypted image (`url` + `contentRef`, e.g. an IPFS gateway URL + CID or a
149
+ * Swarm URL + reference) along with its decryption parameters, and returns
150
+ * the decrypted image. Preferred over the deprecated `ipfsImageFetchFn`;
151
+ * when both are provided, `imageFetchFn` wins.
152
+ */
153
+ imageFetchFn?: ImageFetchFn;
154
+ /** @deprecated Use the storage-agnostic `imageFetchFn` instead. */
146
155
  ipfsImageFetchFn?: (_data: IpfsImageFetchPayload) => Promise<{
147
156
  url: string;
148
157
  file: File;
@@ -191,6 +200,15 @@ export interface DdocProps extends CommentAccountProps {
191
200
  isPreviewMode?: boolean;
192
201
  viewerMode?: 'suggest' | 'view-only';
193
202
  ensResolutionUrl?: string;
203
+ /**
204
+ * Storage-agnostic image upload function. Encrypts and stores the file on
205
+ * the host's storage backend (IPFS, Swarm, ...) and returns its location
206
+ * (`url` + `contentRef`) plus the decryption parameters. Preferred over the
207
+ * deprecated `ipfsImageUploadFn`; when both are provided, `imageUploadFn`
208
+ * wins.
209
+ */
210
+ imageUploadFn?: ImageUploadFn;
211
+ /** @deprecated Use the storage-agnostic `imageUploadFn` instead. */
194
212
  ipfsImageUploadFn?: (file: File) => Promise<IpfsImageUploadResponse>;
195
213
  enableIndexeddbSync?: boolean;
196
214
  ddocId?: string;
@@ -298,7 +316,19 @@ export interface DdocProps extends CommentAccountProps {
298
316
  * @description Called when the IndexedDB persistence provider fails to initialize (e.g., private browsing, quota exceeded, corrupted DB). The editor will continue to function without local persistence.
299
317
  */
300
318
  onIndexedDbError?: (error: Error) => void;
319
+ /**
320
+ * Called when the schema-version stamp was refused or reverted
321
+ * @description The editor stamps brand-new docs with the preferred schema. If the host passed an empty body for a doc that turns out to hold v1 content, the stamp is blocked (or reverted when the content arrived late). Hosts report these to see how often an existing doc is mounted without its body.
322
+ */
323
+ onSchemaStampGuard?: (event: SchemaStampGuardEvent) => void;
301
324
  }
325
+ export type SchemaStampGuardEvent = {
326
+ kind: 'blocked';
327
+ preferredSchemaVersion: number;
328
+ } | {
329
+ kind: 'reverted';
330
+ preferredSchemaVersion: number;
331
+ };
302
332
  export interface IEditorSelectionData {
303
333
  from: number;
304
334
  to: number;
@@ -314,6 +344,39 @@ export interface IUser {
314
344
  isEns: boolean;
315
345
  }
316
346
  export { type IComment };
347
+ /**
348
+ * Storage-agnostic result of an image upload. The editor treats both fields
349
+ * as opaque: `url` is a fetchable location of the encrypted blob (e.g. an
350
+ * IPFS gateway URL or a Swarm `/bytes` URL) and `contentRef` is the backend's
351
+ * content address (IPFS CID, Swarm reference, ...). Both are stored in the
352
+ * document and handed back verbatim to `imageFetchFn`.
353
+ */
354
+ export interface StorageImageUploadResponse {
355
+ encryptionKey: string;
356
+ nonce: string;
357
+ authTag: string;
358
+ url: string;
359
+ contentRef: string;
360
+ }
361
+ /**
362
+ * Storage-agnostic payload handed to `imageFetchFn`: the `url`/`contentRef`
363
+ * returned by `imageUploadFn` at upload time, plus the parameters needed to
364
+ * decrypt the blob.
365
+ */
366
+ export interface StorageImageFetchPayload {
367
+ encryptionKey: string;
368
+ nonce: string;
369
+ authTag: string;
370
+ mimeType: string;
371
+ url: string;
372
+ contentRef: string;
373
+ }
374
+ export type ImageUploadFn = (file: File) => Promise<StorageImageUploadResponse>;
375
+ export type ImageFetchFn = (_data: StorageImageFetchPayload) => Promise<{
376
+ url: string;
377
+ file: File;
378
+ }>;
379
+ /** @deprecated Use the storage-agnostic {@link StorageImageUploadResponse} instead. */
317
380
  export interface IpfsImageUploadResponse {
318
381
  encryptionKey: string;
319
382
  nonce: string;
@@ -321,6 +384,7 @@ export interface IpfsImageUploadResponse {
321
384
  ipfsHash: string;
322
385
  authTag: string;
323
386
  }
387
+ /** @deprecated Use the storage-agnostic {@link StorageImageFetchPayload} instead. */
324
388
  export interface IpfsImageFetchPayload {
325
389
  encryptionKey: string;
326
390
  nonce: string;
@@ -3,7 +3,7 @@ import { Editor } from '@tiptap/react';
3
3
  import { DBlockRuntimeState } from './extensions/d-block/dblock-runtime';
4
4
  import { EditorWidthStore } from './utils/editor-width-store';
5
5
 
6
- export declare const useDdocEditor: ({ isPreviewMode, viewerMode, initialContent, versionHistoryState, collaboration, onChange, onCollaboratorChange, onCommentInteraction, onError, setCharacterCount, setWordCount, setSelectedWordCount, setPageCount, onStatsChange, ipfsImageUploadFn, ddocId, enableIndexeddbSync, unFocused, isFocusMode, theme, zoomLevel, onInvalidContentError, ignoreCorruptedData, isPresentationMode, metadataProxyUrl, extensions: externalExtensions, onCopyHeadingLink, ipfsImageFetchFn, fetchV1ImageFn, isConnected, activeModel, maxTokens, isAIAgentEnabled, onIndexedDbError, disableInlineComment, initialCommentAnchors, isPreviewEditor, fonts, preferredSchemaVersion, editorWidthStore, ...rest }: Partial<DdocProps> & {
6
+ export declare const useDdocEditor: ({ isPreviewMode, viewerMode, initialContent, versionHistoryState, collaboration, onChange, onCollaboratorChange, onCommentInteraction, onError, setCharacterCount, setWordCount, setSelectedWordCount, setPageCount, onStatsChange, ipfsImageUploadFn, ddocId, enableIndexeddbSync, unFocused, isFocusMode, theme, zoomLevel, onInvalidContentError, ignoreCorruptedData, isPresentationMode, metadataProxyUrl, extensions: externalExtensions, onCopyHeadingLink, ipfsImageFetchFn, fetchV1ImageFn, isConnected, activeModel, maxTokens, isAIAgentEnabled, onIndexedDbError, disableInlineComment, initialCommentAnchors, isPreviewEditor, fonts, preferredSchemaVersion, editorWidthStore, onSchemaStampGuard, ...rest }: Partial<DdocProps> & {
7
7
  isFocusMode?: boolean;
8
8
  isPreviewEditor?: boolean;
9
9
  editorWidthStore?: EditorWidthStore;
@@ -0,0 +1,2 @@
1
+ /** Whether a focus-mode mousedown landed on the bare canvas around the page. */
2
+ export declare const isFocusModeCanvasClick: (target: Element, editorContent: Element | null) => boolean;
@@ -4,3 +4,5 @@ export declare const SCHEMA_VERSION_META_KEY = "schemaVersion";
4
4
  export declare const SUPPORTED_SCHEMA_VERSION = 2;
5
5
  export declare const getDocSchemaVersion: (doc: Y.Doc) => number;
6
6
  export declare const isDocSchemaSupported: (doc: Y.Doc) => boolean;
7
+ export declare const docHasBlockContent: (doc: Y.Doc) => boolean;
8
+ export declare const docHasV1Blocks: (doc: Y.Doc) => boolean;
@@ -0,0 +1,30 @@
1
+ import { ImageFetchFn, ImageUploadFn, IpfsImageFetchPayload, IpfsImageUploadResponse } from '../types';
2
+
3
+ /**
4
+ * Boundary adapters between the storage-agnostic public props
5
+ * (`imageUploadFn` / `imageFetchFn`) and the IPFS-shaped interface the editor
6
+ * internals still use. Internals are untouched: a storage-agnostic host
7
+ * function is wrapped here, at the prop boundary, so that downstream code
8
+ * keeps seeing the legacy `ipfsUrl` / `ipfsHash` field names regardless of
9
+ * which backend the host actually stores on.
10
+ */
11
+ type LegacyImageUploadFn = (file: File) => Promise<IpfsImageUploadResponse>;
12
+ type LegacyImageFetchFn = (_data: IpfsImageFetchPayload) => Promise<{
13
+ url: string;
14
+ file: File;
15
+ }>;
16
+ /**
17
+ * Resolve the upload function to use internally. The storage-agnostic
18
+ * `imageUploadFn` wins over the deprecated `ipfsImageUploadFn`; its response
19
+ * is mapped onto the legacy field names (`url` → `ipfsUrl`,
20
+ * `contentRef` → `ipfsHash`).
21
+ */
22
+ export declare const resolveImageUploadFn: (imageUploadFn?: ImageUploadFn, ipfsImageUploadFn?: LegacyImageUploadFn) => LegacyImageUploadFn | undefined;
23
+ /**
24
+ * Resolve the fetch function to use internally. The storage-agnostic
25
+ * `imageFetchFn` wins over the deprecated `ipfsImageFetchFn`; the legacy
26
+ * payload built by the internals is mapped onto the agnostic field names
27
+ * (`ipfsUrl` → `url`, `ipfsHash` → `contentRef`).
28
+ */
29
+ export declare const resolveImageFetchFn: (imageFetchFn?: ImageFetchFn, ipfsImageFetchFn?: LegacyImageFetchFn) => LegacyImageFetchFn | undefined;
30
+ export {};
@@ -1,7 +1,7 @@
1
1
  import { jsx as m, jsxs as L } from "react/jsx-runtime";
2
2
  import { useRef as D, useState as E, useEffect as A } from "react";
3
3
  import { DynamicDropdown as P, Tooltip as O, IconButton as T } from "@fileverse/ui";
4
- import { a3 as _, a4 as w, c as R } from "./index-8MQH4TSF.mjs";
4
+ import { a3 as _, a4 as w, c as R } from "./index-eP_xxZsk.mjs";
5
5
  const p = (e, n, o = n) => {
6
6
  const { state: i } = e, l = i.changeByRange((t) => {
7
7
  const d = i.sliceDoc(t.from, t.to), r = i.sliceDoc(