@abraca/dabra 1.0.0 → 1.0.2

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/dist/index.d.ts CHANGED
@@ -391,6 +391,23 @@ declare class AbracadabraClient {
391
391
  revokeInvite(code: string): Promise<void>;
392
392
  /** Redeem an invite code for the currently authenticated user. */
393
393
  redeemInvite(code: string): Promise<void>;
394
+ /** List spaces visible to the caller. No auth required for public spaces. */
395
+ listSpaces(): Promise<SpaceMeta[]>;
396
+ /** Get a single space by ID. */
397
+ getSpace(spaceId: string): Promise<SpaceMeta>;
398
+ /** Get the hub space, or null if none is configured. */
399
+ getHubSpace(): Promise<SpaceMeta | null>;
400
+ /** Create a new space (auth required). */
401
+ createSpace(opts: {
402
+ name: string;
403
+ description?: string;
404
+ visibility?: SpaceMeta["visibility"];
405
+ id?: string;
406
+ }): Promise<SpaceMeta>;
407
+ /** Update an existing space (Owner or admin required). */
408
+ updateSpace(spaceId: string, opts: Partial<Pick<SpaceMeta, "name" | "description" | "visibility" | "is_hub">>): Promise<SpaceMeta>;
409
+ /** Delete a space and its root document (Owner or admin required). */
410
+ deleteSpace(spaceId: string): Promise<void>;
394
411
  /** Health check — no auth required. */
395
412
  health(): Promise<HealthStatus>;
396
413
  /**
@@ -964,6 +981,17 @@ interface SearchResult {
964
981
  /** Number of matching trigrams — higher is better. */
965
982
  score: number;
966
983
  }
984
+ interface SpaceMeta {
985
+ id: string;
986
+ doc_id: string;
987
+ name: string;
988
+ description: string | null;
989
+ visibility: "public" | "private" | "invite";
990
+ is_hub: boolean;
991
+ owner_id: string | null;
992
+ created_at: number;
993
+ updated_at: number;
994
+ }
967
995
  interface InviteRow {
968
996
  code: string;
969
997
  createdBy: string | null;
@@ -1329,6 +1357,12 @@ declare class FileBlobStore extends EventEmitter {
1329
1357
  * URL.createObjectURL is unavailable (e.g. Node.js / SSR).
1330
1358
  */
1331
1359
  getBlobUrl(docId: string, uploadId: string): Promise<string | null>;
1360
+ /**
1361
+ * Store a blob directly into the cache under the given (docId, uploadId) key
1362
+ * and return its object URL. Use this to pre-populate the cache for files
1363
+ * that haven't been uploaded to the server yet (e.g. offline upload queue).
1364
+ */
1365
+ putBlob(docId: string, uploadId: string, blob: Blob, filename: string): Promise<string>;
1332
1366
  /** Revoke the object URL and remove the blob from cache. */
1333
1367
  evictBlob(docId: string, uploadId: string): Promise<void>;
1334
1368
  /**
@@ -1557,4 +1591,4 @@ declare class BackgroundSyncManager extends EventEmitter {
1557
1591
  private _walkXml;
1558
1592
  }
1559
1593
  //#endregion
1560
- export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, CryptoIdentity, CryptoIdentityKeystore, type DocEncryptionInfo, DocKeyManager, type DocSyncState, DocumentCache, type DocumentCacheOptions, DocumentMeta, E2EAbracadabraProvider, E2EOfflineStore, EffectiveRole, EncryptedYMap, EncryptedYText, FileBlobStore, Forbidden, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, InviteRow, MessageTooBig, MessageType, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, ServerInfo, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, attachUpdatedAtObserver, awarenessStatesToArray, decryptField, encryptField, makeEncryptedYMap, makeEncryptedYText, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
1594
+ export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, CryptoIdentity, CryptoIdentityKeystore, type DocEncryptionInfo, DocKeyManager, type DocSyncState, DocumentCache, type DocumentCacheOptions, DocumentMeta, E2EAbracadabraProvider, E2EOfflineStore, EffectiveRole, EncryptedYMap, EncryptedYText, FileBlobStore, Forbidden, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, InviteRow, MessageTooBig, MessageType, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, ServerInfo, SpaceMeta, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, attachUpdatedAtObserver, awarenessStatesToArray, decryptField, encryptField, makeEncryptedYMap, makeEncryptedYText, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abraca/dabra",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": "abracadabra provider",
5
5
  "keywords": [
6
6
  "abracadabra",
@@ -8,6 +8,7 @@ import type {
8
8
  HealthStatus,
9
9
  ServerInfo,
10
10
  InviteRow,
11
+ SpaceMeta,
11
12
  } from "./types.ts";
12
13
  import type { DocEncryptionInfo } from "./types.ts";
13
14
  import type { DocumentCache } from "./DocumentCache.ts";
@@ -472,6 +473,54 @@ export class AbracadabraClient {
472
473
  await this.request("POST", "/invites/redeem", { body: { code } });
473
474
  }
474
475
 
476
+ // ── Spaces ───────────────────────────────────────────────────────────────
477
+
478
+ /** List spaces visible to the caller. No auth required for public spaces. */
479
+ async listSpaces(): Promise<SpaceMeta[]> {
480
+ const res = await this.request<{ spaces: SpaceMeta[] }>("GET", "/spaces", { auth: false });
481
+ return res.spaces;
482
+ }
483
+
484
+ /** Get a single space by ID. */
485
+ async getSpace(spaceId: string): Promise<SpaceMeta> {
486
+ return this.request<SpaceMeta>("GET", `/spaces/${encodeURIComponent(spaceId)}`, { auth: false });
487
+ }
488
+
489
+ /** Get the hub space, or null if none is configured. */
490
+ async getHubSpace(): Promise<SpaceMeta | null> {
491
+ try {
492
+ return await this.request<SpaceMeta>("GET", "/spaces/hub", { auth: false });
493
+ } catch (e: unknown) {
494
+ if (typeof e === "object" && e !== null && "status" in e && (e as { status: number }).status === 404) {
495
+ return null;
496
+ }
497
+ throw e;
498
+ }
499
+ }
500
+
501
+ /** Create a new space (auth required). */
502
+ async createSpace(opts: {
503
+ name: string;
504
+ description?: string;
505
+ visibility?: SpaceMeta["visibility"];
506
+ id?: string;
507
+ }): Promise<SpaceMeta> {
508
+ return this.request<SpaceMeta>("POST", "/spaces", { body: opts });
509
+ }
510
+
511
+ /** Update an existing space (Owner or admin required). */
512
+ async updateSpace(
513
+ spaceId: string,
514
+ opts: Partial<Pick<SpaceMeta, "name" | "description" | "visibility" | "is_hub">>,
515
+ ): Promise<SpaceMeta> {
516
+ return this.request<SpaceMeta>("PATCH", `/spaces/${encodeURIComponent(spaceId)}`, { body: opts });
517
+ }
518
+
519
+ /** Delete a space and its root document (Owner or admin required). */
520
+ async deleteSpace(spaceId: string): Promise<void> {
521
+ await this.request("DELETE", `/spaces/${encodeURIComponent(spaceId)}`);
522
+ }
523
+
475
524
  // ── System ───────────────────────────────────────────────────────────────
476
525
 
477
526
  /** Health check — no auth required. */
@@ -160,6 +160,42 @@ export class FileBlobStore extends EventEmitter {
160
160
  return url;
161
161
  }
162
162
 
163
+ /**
164
+ * Store a blob directly into the cache under the given (docId, uploadId) key
165
+ * and return its object URL. Use this to pre-populate the cache for files
166
+ * that haven't been uploaded to the server yet (e.g. offline upload queue).
167
+ */
168
+ async putBlob(
169
+ docId: string,
170
+ uploadId: string,
171
+ blob: Blob,
172
+ filename: string,
173
+ ): Promise<string> {
174
+ if (typeof window === "undefined") return URL.createObjectURL(blob);
175
+
176
+ const key = this.blobKey(docId, uploadId);
177
+
178
+ // Return existing URL if already cached in-memory
179
+ const existing = this.objectUrls.get(key);
180
+ if (existing) return existing;
181
+
182
+ const db = await this.getDb();
183
+ if (db) {
184
+ const entry: BlobCacheEntry = {
185
+ blob,
186
+ mime_type: blob.type || "application/octet-stream",
187
+ filename,
188
+ cachedAt: Date.now(),
189
+ };
190
+ const tx = db.transaction("blobs", "readwrite");
191
+ tx.objectStore("blobs").put(entry, key);
192
+ }
193
+
194
+ const url = URL.createObjectURL(blob);
195
+ this.objectUrls.set(key, url);
196
+ return url;
197
+ }
198
+
163
199
  /** Revoke the object URL and remove the blob from cache. */
164
200
  async evictBlob(docId: string, uploadId: string): Promise<void> {
165
201
  const key = this.blobKey(docId, uploadId);
package/src/types.ts CHANGED
@@ -223,6 +223,20 @@ export interface SearchResult {
223
223
  score: number;
224
224
  }
225
225
 
226
+ // ── Spaces ───────────────────────────────────────────────────────────────────
227
+
228
+ export interface SpaceMeta {
229
+ id: string;
230
+ doc_id: string;
231
+ name: string;
232
+ description: string | null;
233
+ visibility: "public" | "private" | "invite";
234
+ is_hub: boolean;
235
+ owner_id: string | null;
236
+ created_at: number;
237
+ updated_at: number;
238
+ }
239
+
226
240
  // ── Invites ──────────────────────────────────────────────────────────────────
227
241
 
228
242
  export interface InviteRow {