rmapi-js 11.1.2 → 12.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
@@ -62,8 +62,9 @@ Using these apis is a little riskier since they can potentially result in data l
62
62
  // upload with custom line height not avilable through reMarkable
63
63
  await api.putEpub("name", buffer, { lineHeight: 180 })
64
64
 
65
- // fetch an uploaded epub, using the id and hash (from listItems)
66
- const buffer = await api.getEpub(id, hash)
65
+ // fetch an uploaded epub, passing an item reference (from listItems)
66
+ const [entry] = await api.listItems()
67
+ const buffer = await api.getEpub(entry)
67
68
  ```
68
69
 
69
70
  ### Gotchas
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { type BackgroundFilter, type CollectionContent, type Content, type DocumentContent, type Metadata, type Orientation, type RawRemarkableApi, type SimpleEntry, type Tag, type TemplateContent, type TextAlignment, type ZoomMode } from "./raw.js";
1
+ import { type BackgroundFilter, type CollectionContent, type Content, type DocumentContent, type ItemRef, type Metadata, type Orientation, RawRemarkable, type RmPage, type Tag, type TemplateContent, type TextAlignment, type ZoomMode } from "./raw.js";
2
2
  export { type DeviceModel, type DeviceScreen, deviceScreens, } from "./devices.js";
3
3
  export { HashNotFoundError, ValidationError } from "./error.js";
4
- export type { BackgroundFilter, CollectionContent, Content, CPageNumberValue, CPagePage, CPageStringValue, CPages, CPageUUID, DocumentContent, DocumentMetadata, Entries, FileType, KeyboardMetadata, LegacyCollectionContent, LegacyDocumentContent, Metadata, Orientation, PageTag, RawEntry, RawRemarkableApi, SchemaVersion, SimpleEntry, Tag, TemplateContent, TextAlignment, UploadMimeType, ZoomMode, } from "./raw.js";
4
+ export type { BackgroundFilter, CollectionContent, Content, CPageNumberValue, CPagePage, CPageStringValue, CPages, CPageUUID, DocumentContent, DocumentMetadata, Entries, FileType, ItemRef, KeyboardMetadata, LegacyCollectionContent, LegacyDocumentContent, Metadata, Orientation, PageTag, RawEntry, RawRemarkableApi, RmPage, SchemaVersion, Tag, TemplateContent, TextAlignment, UploadMimeType, ZoomMode, } from "./raw.js";
5
+ export type { RmBrush, RmLayer, RmLine, RmPageV5, RmPoint, RmVersion, } from "./rm5.js";
6
+ export { decodeBrush, rmColors } from "./rm5.js";
7
+ export type { AuthorIdsBlock, CrdtId, GlyphRange, LwwValue, MigrationInfoBlock, PageInfoBlock, Rectangle, RmBlock, RmScene, RmSceneItem, RmSceneLayer, RmV6Line, RmV6Point, RmV6Text, RmV6TextValue, RootTextBlock, SceneGlyphItemBlock, SceneGroupItemBlock, SceneInfoBlock, SceneItem, SceneLineItemBlock, SceneTextItemBlock, SceneTombstoneItemBlock, SceneTreeBlock, TreeNodeBlock, UnknownBlock, } from "./rm6.js";
8
+ export { crdtKey, END_MARKER, parseRmScene, ROOT_ID } from "./rm6.js";
5
9
  /** common properties shared by collections and documents */
6
- export interface EntryCommon {
7
- /** the document id, a uuid4 */
8
- id: string;
9
- /** the current hash of the state of this entry */
10
- hash: string;
10
+ export interface EntryCommon extends ItemRef {
11
11
  /** the visible display name of this entry */
12
12
  visibleName: string;
13
13
  /** the last modified timestamp */
@@ -51,21 +51,27 @@ export interface TemplateType extends EntryCommon {
51
51
  }
52
52
  /** a remarkable entry for cloud items */
53
53
  export type Entry = CollectionEntry | DocumentType | TemplateType;
54
- /** the new hash of a modified entry */
55
- export interface HashEntry {
56
- /** the actual hash */
57
- hash: string;
58
- }
59
- /** the mapping from old hashes to new hashes after a bulk modify */
60
- export interface HashesEntry {
61
- /** the mapping from old to new hashes */
62
- hashes: Record<string, string>;
63
- }
64
54
  /** options for creating a folder */
65
55
  export interface FolderOptions {
66
56
  /** the id of the folder's parent directory, "" or omitted for root */
67
57
  parent?: string;
68
58
  }
59
+ /** options for uploading a full document archive */
60
+ export interface PutDocumentOptions {
61
+ /** if true, refresh the root hash before uploading */
62
+ refresh?: boolean;
63
+ /** the parent to place the document under, overriding the archived value */
64
+ parent?: string;
65
+ /** the visible name to use, overriding the archived value */
66
+ visibleName?: string;
67
+ /**
68
+ * reuse this document id instead of generating a fresh one
69
+ *
70
+ * By default a new uuid is generated so re-uploading an archive to the same
71
+ * account doesn't collide with the original. Pass an id to restore in place.
72
+ */
73
+ id?: string;
74
+ }
69
75
  /** An error that gets thrown when the backend while trying to update
70
76
  *
71
77
  * IF you encounter this error, you likely just need to try th request again. If
@@ -201,9 +207,11 @@ export interface PutOptions {
201
207
  * you should be able to use the low level api to work around any restrictive
202
208
  * validation.
203
209
  */
204
- export interface RemarkableApi {
210
+ declare class Remarkable {
211
+ #private;
205
212
  /** scoped access to the raw low-level api */
206
- raw: RawRemarkableApi;
213
+ readonly raw: RawRemarkable;
214
+ constructor(sessionToken: string, rawHost: string, uploadHost: string, cache: Map<string, string | null>, maxGenerationRetries: number, maxTransientRetries: number);
207
215
  /**
208
216
  * list all items
209
217
  *
@@ -229,77 +237,102 @@ export interface RemarkableApi {
229
237
  *
230
238
  * @param refresh - if true, refresh the root hash before listing
231
239
  */
232
- listIds(refresh?: boolean): Promise<SimpleEntry[]>;
240
+ listIds(refresh?: boolean): Promise<ItemRef[]>;
233
241
  /**
234
- * get the content metadata from an item hash
235
- *
236
- * This takes the high level item hash, e.g. the hashes you get from
237
- * {@link listItems | `listItems`} or {@link listIds | `listIds`}.
242
+ * get the content metadata for an item
238
243
  *
239
244
  * @remarks
240
245
  * If this fails validation and you still want to get the content, you can use
241
246
  * the low-level api to get the raw text of the `.content` file in the
242
247
  * `RawEntry` for this hash.
243
248
  *
244
- * @param id - the id of the item (as returned by `listIds`)
245
- * @param hash - the hash of the item to get content for
249
+ * @param ref - a reference to the item (e.g. from `listItems` or `listIds`)
246
250
  * @returns the content
247
251
  */
248
- getContent(id: string, hash: string): Promise<Content>;
252
+ getContent({ id, hash }: ItemRef): Promise<Content>;
249
253
  /**
250
- * get the metadata from an item hash
251
- *
252
- * This takes the high level item hash, e.g. the hashes you get from
253
- * {@link listItems | `listItems`} or {@link listIds | `listIds`}.
254
+ * get the metadata for an item
254
255
  *
255
256
  * @remarks
256
257
  * If this fails validation and you still want to get the content, you can use
257
258
  * the low-level api to get the raw text of the `.metadata` file in the
258
259
  * `RawEntry` for this hash.
259
260
  *
260
- * @param id - the id of the item (as returned by `listIds`)
261
- * @param hash - the hash of the item to get metadata for
261
+ * @param ref - a reference to the item (e.g. from `listItems` or `listIds`)
262
262
  * @returns the metadata
263
263
  */
264
- getMetadata(id: string, hash: string): Promise<Metadata>;
264
+ getMetadata({ id, hash }: ItemRef): Promise<Metadata>;
265
265
  /**
266
- * get the pdf associated with a document hash
266
+ * get the pdf associated with a document
267
267
  *
268
268
  * This returns the raw input pdf, not the rendered pdf with any markup.
269
269
  *
270
- * @param id - the id of the document (as returned by `listIds`)
271
- * @param hash - the hash of the document to get the pdf for (e.g. the hash
272
- * received from `listItems`)
270
+ * @param ref - a reference to the document (e.g. from `listItems`)
273
271
  * @returns the pdf bytes
274
272
  */
275
- getPdf(id: string, hash: string): Promise<Uint8Array>;
273
+ getPdf({ id, hash }: ItemRef): Promise<Uint8Array>;
276
274
  /**
277
- * get the epub associated with a document hash
275
+ * get the epub associated with a document
278
276
  *
279
277
  * This returns the raw input epub if a document was created from an epub.
280
278
  *
281
- * @param id - the id of the document (as returned by `listIds`)
282
- * @param hash - the hash of the document to get the epub for (e.g. the hash
283
- * received from `listItems`)
279
+ * @param ref - a reference to the document (e.g. from `listItems`)
284
280
  * @returns the epub bytes
285
281
  */
286
- getEpub(id: string, hash: string): Promise<Uint8Array>;
282
+ getEpub({ id, hash }: ItemRef): Promise<Uint8Array>;
283
+ /**
284
+ * get a single page's parsed reMarkable lines (`.rm`) drawing
285
+ *
286
+ * @param ref - a reference to the document (e.g. from `listItems`)
287
+ * @param pageId - the id of the page, from the document's `.content` page
288
+ * list (see {@link getRmPages | `getRmPages`} for every page)
289
+ * @returns the parsed page, or `undefined` if the page exists but has no
290
+ * `.rm` drawing (a page you haven't drawn on has no `.rm` file)
291
+ * @throws if `pageId` is not a page of the document
292
+ */
293
+ getRmPage(ref: ItemRef, pageId: string): Promise<RmPage | undefined>;
287
294
  /**
288
- * get the entire contents of a remarkable document
295
+ * get every drawn page of a document, parsed, keyed by page id
296
+ *
297
+ * Returns a map from page id to its parsed {@link RmPage | `RmPage`},
298
+ * iterating in the page order given by the document's `.content`. Pages with
299
+ * no drawing (and soft-deleted pages) are omitted. Version 3, 5, and 6 pages
300
+ * are all supported.
289
301
  *
290
- * This gets every file of associated with a document, and puts them into a
291
- * zip archive.
302
+ * @param ref - a reference to the document (e.g. from `listItems`)
303
+ * @returns the drawn pages, keyed by page id, in document order
304
+ */
305
+ getRmPages(ref: ItemRef): Promise<Map<string, RmPage>>;
306
+ /**
307
+ * get a document's entire contents as a zip archive
308
+ *
309
+ * This gets every file associated with a document and puts them into a zip
310
+ * archive.
311
+ *
312
+ * @remarks
313
+ * This is an experimental feature. The resulting archive round-trips back
314
+ * through {@link putDocumentArchive | `putDocumentArchive`}.
315
+ *
316
+ * @param ref - a reference to the document (e.g. from `listItems`)
317
+ */
318
+ getDocumentArchive({ id, hash }: ItemRef): Promise<Uint8Array>;
319
+ /**
320
+ * upload a document archive produced by {@link getDocumentArchive | `getDocumentArchive`}
321
+ *
322
+ * This explodes the zip archive back into its constituent files, uploads each
323
+ * as a blob, and commits a new document into the root.
292
324
  *
293
325
  * @remarks
294
- * This is an experimental feature, that works for downloading the raw version
295
- * of the document, but this format isn't understood enoguh to reput this on a
296
- * different remarkable, so that functionality is currently disabled.
326
+ * This is an experimental feature. By default a fresh document id is generated
327
+ * so re-uploading to the same account doesn't collide with the original; pass
328
+ * {@link PutDocumentOptions.id | `id`} to keep the original id. Like the other
329
+ * low-level puts, this may throw a {@link GenerationError | `GenerationError`}
330
+ * if the generation is stale, requiring a retry.
297
331
  *
298
- * @param id - the id of the document (as returned by `listIds`)
299
- * @param hash - the hash of the document to get contents for (e.g. the
300
- * hash received from `listItems`)
332
+ * @param buffer - the archive bytes, as returned by `getDocumentArchive`
333
+ * @param options - overrides for parent, visible name, and id
301
334
  */
302
- getDocument(id: string, hash: string): Promise<Uint8Array>;
335
+ putDocumentArchive(buffer: Uint8Array, { refresh, parent, visibleName, id: keepId, }?: PutDocumentOptions): Promise<ItemRef>;
303
336
  /**
304
337
  * use the low-level api to add a pdf document
305
338
  *
@@ -340,7 +373,7 @@ export interface RemarkableApi {
340
373
  * @throws GenerationError if the generation doesn't match the current server generation
341
374
  * @returns the entry for the newly inserted document
342
375
  */
343
- putPdf(visibleName: string, buffer: Uint8Array, opts?: PutOptions): Promise<SimpleEntry>;
376
+ putPdf(visibleName: string, buffer: Uint8Array, opts?: PutOptions): Promise<ItemRef>;
344
377
  /**
345
378
  * use the low-level api to add an epub document
346
379
  *
@@ -356,9 +389,9 @@ export interface RemarkableApi {
356
389
  * @throws GenerationError if the generation doesn't match the current server generation
357
390
  * @returns the entry for the newly inserted document
358
391
  */
359
- putEpub(visibleName: string, buffer: Uint8Array, opts?: PutOptions): Promise<SimpleEntry>;
392
+ putEpub(visibleName: string, buffer: Uint8Array, opts?: PutOptions): Promise<ItemRef>;
360
393
  /** create a folder */
361
- putFolder(visibleName: string, opts?: FolderOptions, refresh?: boolean): Promise<SimpleEntry>;
394
+ putFolder(visibleName: string, { parent }?: FolderOptions, refresh?: boolean): Promise<ItemRef>;
362
395
  /**
363
396
  * upload an epub
364
397
  *
@@ -373,7 +406,7 @@ export interface RemarkableApi {
373
406
  * @param visibleName - the name to show for the uploaded epub
374
407
  * @param buffer - the epub contents
375
408
  */
376
- uploadEpub(visibleName: string, buffer: Uint8Array): Promise<SimpleEntry>;
409
+ uploadEpub(visibleName: string, buffer: Uint8Array): Promise<ItemRef>;
377
410
  /**
378
411
  * upload a pdf
379
412
  *
@@ -388,112 +421,121 @@ export interface RemarkableApi {
388
421
  * @param visibleName - the name to show for the uploaded epub
389
422
  * @param buffer - the epub contents
390
423
  */
391
- uploadPdf(visibleName: string, buffer: Uint8Array): Promise<SimpleEntry>;
424
+ uploadPdf(visibleName: string, buffer: Uint8Array): Promise<ItemRef>;
392
425
  /** create a folder using the simple api */
393
- uploadFolder(visibleName: string): Promise<SimpleEntry>;
426
+ uploadFolder(visibleName: string): Promise<ItemRef>;
394
427
  /**
395
428
  * update content metadata for a document
396
429
  *
397
430
  * @example
398
431
  * ```ts
399
- * await api.updateDocument(doc.hash, { textAlignment: "left" });
432
+ * const next = await api.updateDocument(doc, { textAlignment: "left" });
400
433
  * ```
401
434
  *
402
- * @param hash - the hash of the file to update
435
+ * @param ref - a reference to the file to update
403
436
  * @param content - the fields of content to update
437
+ * @returns a reference to the updated entry, with its new hash
404
438
  */
405
- updateDocument(hash: string, content: Partial<DocumentContent>, refresh?: boolean): Promise<HashEntry>;
439
+ updateDocument(ref: ItemRef, content: Partial<DocumentContent>, refresh?: boolean): Promise<ItemRef>;
406
440
  /**
407
441
  * update content metadata for a collection
408
442
  *
409
443
  * @example
410
444
  * ```ts
411
- * await api.updateCollection(doc.hash, { textAlignment: "left" });
445
+ * const next = await api.updateCollection(dir, { textAlignment: "left" });
412
446
  * ```
413
447
  *
414
- * @param hash - the hash of the file to update
448
+ * @param ref - a reference to the collection to update
415
449
  * @param content - the fields of content to update
450
+ * @returns a reference to the updated entry, with its new hash
416
451
  */
417
- updateCollection(hash: string, content: Partial<CollectionContent>, refresh?: boolean): Promise<HashEntry>;
452
+ updateCollection(ref: ItemRef, content: Partial<CollectionContent>, refresh?: boolean): Promise<ItemRef>;
418
453
  /**
419
454
  * update content metadata for a template
420
455
  *
421
456
  * @example
422
457
  * ```ts
423
- * await api.updateTemplate(doc.hash, { textAlignment: "left" });
458
+ * const next = await api.updateTemplate(tmpl, { textAlignment: "left" });
424
459
  * ```
425
460
  *
426
- * @param hash - the hash of the file to update
461
+ * @param ref - a reference to the template to update
427
462
  * @param content - the fields of content to update
463
+ * @returns a reference to the updated entry, with its new hash
428
464
  */
429
- updateTemplate(hash: string, content: Partial<TemplateContent>, refresh?: boolean): Promise<HashEntry>;
465
+ updateTemplate(ref: ItemRef, content: Partial<TemplateContent>, refresh?: boolean): Promise<ItemRef>;
430
466
  /**
431
467
  * move an entry
432
468
  *
433
469
  * @example
434
470
  * ```ts
435
- * await api.move(doc.hash, dir.id);
471
+ * const next = await api.move(doc, dir.id);
436
472
  * ```
437
473
  *
438
- * @param hash - the hash of the file to move
474
+ * @param ref - a reference to the entry to move
439
475
  * @param parent - the id of the directory to move the entry to, "" (root) and "trash" are special parents
476
+ * @returns a reference to the moved entry, with its new hash
440
477
  */
441
- move(hash: string, parent: string, refresh?: boolean): Promise<HashEntry>;
478
+ move(ref: ItemRef, parent: string, refresh?: boolean): Promise<ItemRef>;
442
479
  /**
443
480
  * delete an entry
444
481
  *
445
482
  * @example
446
483
  * ```ts
447
- * await api.delete(file.hash);
484
+ * await api.delete(file);
448
485
  * ```
449
- * @param hash - the hash of the entry to delete
486
+ * @param ref - a reference to the entry to delete
487
+ * @returns a reference to the deleted entry, with its new hash
450
488
  */
451
- delete(hash: string, refresh?: boolean): Promise<HashEntry>;
489
+ delete(ref: ItemRef, refresh?: boolean): Promise<ItemRef>;
452
490
  /**
453
491
  * rename an entry
454
492
  *
455
493
  * @example
456
494
  * ```ts
457
- * await api.rename(file.hash, "new name");
495
+ * const next = await api.rename(file, "new name");
458
496
  * ```
459
- * @param hash - the hash of the entry to rename
497
+ * @param ref - a reference to the entry to rename
460
498
  * @param visibleName - the new name to assign
499
+ * @returns a reference to the renamed entry, with its new hash
461
500
  */
462
- rename(hash: string, visibleName: string, refresh?: boolean): Promise<HashEntry>;
501
+ rename(ref: ItemRef, visibleName: string, refresh?: boolean): Promise<ItemRef>;
463
502
  /**
464
- * set if an entry is stared
503
+ * star or unstar an entry
465
504
  *
466
505
  * @example
467
506
  * ```ts
468
- * await api.stared(file.hash, true);
507
+ * const next = await api.star(file, true);
469
508
  * ```
470
- * @param hash - the hash of the entry to rename
471
- * @param stared - whether the entry should be stared or not
509
+ * @param ref - a reference to the entry to star
510
+ * @param starred - whether the entry should be starred or not
511
+ * @returns a reference to the updated entry, with its new hash
472
512
  */
473
- stared(hash: string, stared: boolean, refresh?: boolean): Promise<HashEntry>;
513
+ star(ref: ItemRef, starred: boolean, refresh?: boolean): Promise<ItemRef>;
474
514
  /**
475
515
  * move many entries
476
516
  *
477
517
  * @example
478
518
  * ```ts
479
- * await api.bulkMove([file.hash], dir.id);
519
+ * const next = await api.bulkMove([file], dir.id);
480
520
  * ```
481
521
  *
482
- * @param hashes - an array of entry hashes to move
522
+ * @param refs - references to the entries to move
483
523
  * @param parent - the directory id to move the entries to, "" (root) and "trash" are special ids
524
+ * @returns references to the moved entries, each with its new hash
484
525
  */
485
- bulkMove(hashes: readonly string[], parent: string, refresh?: boolean): Promise<HashesEntry>;
526
+ bulkMove(refs: readonly ItemRef[], parent: string, refresh?: boolean): Promise<ItemRef[]>;
486
527
  /**
487
528
  * delete many entries
488
529
  *
489
530
  * @example
490
531
  * ```ts
491
- * await api.bulkDelete([file.hash]);
532
+ * await api.bulkDelete([file]);
492
533
  * ```
493
534
  *
494
- * @param hashes - the hashes of the entries to delete
535
+ * @param refs - references to the entries to delete
536
+ * @returns references to the deleted entries, each with its new hash
495
537
  */
496
- bulkDelete(hashes: readonly string[], refresh?: boolean): Promise<HashesEntry>;
538
+ bulkDelete(refs: readonly ItemRef[], refresh?: boolean): Promise<ItemRef[]>;
497
539
  /**
498
540
  * get the current cache value as a string
499
541
  *
@@ -525,6 +567,7 @@ export interface RemarkableApi {
525
567
  */
526
568
  clearCache(): void;
527
569
  }
570
+ export type { Remarkable as RemarkableApi };
528
571
  /** configuration for exchanging a device token */
529
572
  export interface AuthOptions {
530
573
  /**
@@ -565,6 +608,26 @@ export interface RemarkableSessionOptions {
565
608
  * @defaultValue Infinity
566
609
  */
567
610
  maxCacheSize?: number;
611
+ /**
612
+ * how many times to retry updating the root hash after a generation conflict
613
+ *
614
+ * High-level mutators re-fetch the latest root and re-apply their change on a
615
+ * {@link GenerationError | `GenerationError`} up to this many times. Because
616
+ * the document id and uploaded blobs are stable across attempts, retries
617
+ * reuse the cache and don't orphan blobs. Set to `0` to surface the error
618
+ * immediately, matching the previous behavior.
619
+ *
620
+ * @defaultValue 10
621
+ */
622
+ maxGenerationRetries?: number;
623
+ /**
624
+ * how many times to retry a request after a transient network or 5xx error
625
+ *
626
+ * Applies to every request; generation conflicts are not counted here.
627
+ *
628
+ * @defaultValue 3
629
+ */
630
+ maxTransientRetries?: number;
568
631
  }
569
632
  /** options for a remarkable instance */
570
633
  export interface RemarkableOptions extends AuthOptions, RemarkableSessionOptions {
@@ -586,7 +649,7 @@ export declare function auth(deviceToken: string, { authHost }?: AuthOptions): P
586
649
  * @param sessionToken - the session token used for authorization
587
650
  * @returns an api instance
588
651
  */
589
- export declare function session(sessionToken: string, { rawHost, uploadHost, cache, maxCacheSize, }?: RemarkableSessionOptions): RemarkableApi;
652
+ export declare function session(sessionToken: string, { rawHost, uploadHost, cache, maxCacheSize, maxGenerationRetries, maxTransientRetries, }?: RemarkableSessionOptions): Remarkable;
590
653
  /**
591
654
  * create an instance of the api
592
655
  *
@@ -597,4 +660,4 @@ export declare function session(sessionToken: string, { rawHost, uploadHost, cac
597
660
  * registered. Create one with {@link register}.
598
661
  * @returns an api instance
599
662
  */
600
- export declare function remarkable(deviceToken: string, options?: RemarkableOptions): Promise<RemarkableApi>;
663
+ export declare function remarkable(deviceToken: string, options?: RemarkableOptions): Promise<Remarkable>;