rmapi-js 9.0.3 → 10.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/dist/index.d.ts +12 -7
- package/dist/index.js +32 -32
- package/dist/raw.d.ts +18 -10
- package/dist/raw.js +15 -19
- package/dist/rmapi-js.esm.min.js +12 -12
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -228,10 +228,11 @@ export interface RemarkableApi {
|
|
|
228
228
|
* the low-level api to get the raw text of the `.content` file in the
|
|
229
229
|
* `RawEntry` for this hash.
|
|
230
230
|
*
|
|
231
|
+
* @param id - the id of the item (as returned by `listIds`)
|
|
231
232
|
* @param hash - the hash of the item to get content for
|
|
232
233
|
* @returns the content
|
|
233
234
|
*/
|
|
234
|
-
getContent(hash: string): Promise<Content>;
|
|
235
|
+
getContent(id: string, hash: string): Promise<Content>;
|
|
235
236
|
/**
|
|
236
237
|
* get the metadata from an item hash
|
|
237
238
|
*
|
|
@@ -243,30 +244,33 @@ export interface RemarkableApi {
|
|
|
243
244
|
* the low-level api to get the raw text of the `.metadata` file in the
|
|
244
245
|
* `RawEntry` for this hash.
|
|
245
246
|
*
|
|
247
|
+
* @param id - the id of the item (as returned by `listIds`)
|
|
246
248
|
* @param hash - the hash of the item to get metadata for
|
|
247
249
|
* @returns the metadata
|
|
248
250
|
*/
|
|
249
|
-
getMetadata(hash: string): Promise<Metadata>;
|
|
251
|
+
getMetadata(id: string, hash: string): Promise<Metadata>;
|
|
250
252
|
/**
|
|
251
253
|
* get the pdf associated with a document hash
|
|
252
254
|
*
|
|
253
255
|
* This returns the raw input pdf, not the rendered pdf with any markup.
|
|
254
256
|
*
|
|
257
|
+
* @param id - the id of the document (as returned by `listIds`)
|
|
255
258
|
* @param hash - the hash of the document to get the pdf for (e.g. the hash
|
|
256
259
|
* received from `listItems`)
|
|
257
260
|
* @returns the pdf bytes
|
|
258
261
|
*/
|
|
259
|
-
getPdf(hash: string): Promise<Uint8Array>;
|
|
262
|
+
getPdf(id: string, hash: string): Promise<Uint8Array>;
|
|
260
263
|
/**
|
|
261
264
|
* get the epub associated with a document hash
|
|
262
265
|
*
|
|
263
266
|
* This returns the raw input epub if a document was created from an epub.
|
|
264
267
|
*
|
|
265
|
-
* @param
|
|
268
|
+
* @param id - the id of the document (as returned by `listIds`)
|
|
269
|
+
* @param hash - the hash of the document to get the epub for (e.g. the hash
|
|
266
270
|
* received from `listItems`)
|
|
267
271
|
* @returns the epub bytes
|
|
268
272
|
*/
|
|
269
|
-
getEpub(hash: string): Promise<Uint8Array>;
|
|
273
|
+
getEpub(id: string, hash: string): Promise<Uint8Array>;
|
|
270
274
|
/**
|
|
271
275
|
* get the entire contents of a remarkable document
|
|
272
276
|
*
|
|
@@ -278,10 +282,11 @@ export interface RemarkableApi {
|
|
|
278
282
|
* of the document, but this format isn't understood enoguh to reput this on a
|
|
279
283
|
* different remarkable, so that functionality is currently disabled.
|
|
280
284
|
*
|
|
281
|
-
* @param
|
|
285
|
+
* @param id - the id of the document (as returned by `listIds`)
|
|
286
|
+
* @param hash - the hash of the document to get contents for (e.g. the
|
|
282
287
|
* hash received from `listItems`)
|
|
283
288
|
*/
|
|
284
|
-
getDocument(hash: string): Promise<Uint8Array>;
|
|
289
|
+
getDocument(id: string, hash: string): Promise<Uint8Array>;
|
|
285
290
|
/**
|
|
286
291
|
* use the low-level api to add a pdf document
|
|
287
292
|
*
|
package/dist/index.js
CHANGED
|
@@ -180,18 +180,18 @@ class Remarkable {
|
|
|
180
180
|
}
|
|
181
181
|
}
|
|
182
182
|
async #convertEntry({ hash, id }) {
|
|
183
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
183
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
184
184
|
const metaEnt = entries.find((ent) => ent.id.endsWith(".metadata"));
|
|
185
185
|
const contentEnt = entries.find((ent) => ent.id.endsWith(".content"));
|
|
186
186
|
if (metaEnt === undefined) {
|
|
187
187
|
throw new Error(`couldn't find metadata for hash ${hash}`);
|
|
188
188
|
}
|
|
189
189
|
const [{ visibleName, lastModified, pinned, parent, lastOpened, new: isNew, source, }, content,] = await Promise.all([
|
|
190
|
-
this.raw.getMetadata(metaEnt.hash),
|
|
190
|
+
this.raw.getMetadata(metaEnt.id, metaEnt.hash),
|
|
191
191
|
// collections don't always have content, since content only lists tags
|
|
192
192
|
contentEnt === undefined
|
|
193
193
|
? Promise.resolve({ fileType: undefined, tags: undefined })
|
|
194
|
-
: this.raw.getContent(contentEnt.hash),
|
|
194
|
+
: this.raw.getContent(contentEnt.id, contentEnt.hash),
|
|
195
195
|
]);
|
|
196
196
|
if ("templateVersion" in content) {
|
|
197
197
|
return {
|
|
@@ -240,55 +240,55 @@ class Remarkable {
|
|
|
240
240
|
}
|
|
241
241
|
async listIds(refresh = false) {
|
|
242
242
|
const [hash] = await this.#getRootHash(refresh);
|
|
243
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
243
|
+
const { entries } = await this.raw.getEntries("root.docSchema", hash);
|
|
244
244
|
return entries.map(({ id, hash }) => ({ id, hash }));
|
|
245
245
|
}
|
|
246
|
-
async getContent(hash) {
|
|
247
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
246
|
+
async getContent(id, hash) {
|
|
247
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
248
248
|
const [cont] = entries.filter((e) => e.id.endsWith(".content"));
|
|
249
249
|
if (cont === undefined) {
|
|
250
250
|
throw new Error(`couldn't find contents for hash ${hash}`);
|
|
251
251
|
}
|
|
252
252
|
else {
|
|
253
|
-
return await this.raw.getContent(cont.hash);
|
|
253
|
+
return await this.raw.getContent(cont.id, cont.hash);
|
|
254
254
|
}
|
|
255
255
|
}
|
|
256
|
-
async getMetadata(hash) {
|
|
257
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
256
|
+
async getMetadata(id, hash) {
|
|
257
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
258
258
|
const [meta] = entries.filter((e) => e.id.endsWith(".metadata"));
|
|
259
259
|
if (meta === undefined) {
|
|
260
260
|
throw new Error(`couldn't find metadata for hash ${hash}`);
|
|
261
261
|
}
|
|
262
262
|
else {
|
|
263
|
-
return await this.raw.getMetadata(meta.hash);
|
|
263
|
+
return await this.raw.getMetadata(meta.id, meta.hash);
|
|
264
264
|
}
|
|
265
265
|
}
|
|
266
|
-
async getPdf(hash) {
|
|
267
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
266
|
+
async getPdf(id, hash) {
|
|
267
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
268
268
|
const [pdf] = entries.filter((e) => e.id.endsWith(".pdf"));
|
|
269
269
|
if (pdf === undefined) {
|
|
270
270
|
throw new Error(`couldn't find pdf for hash ${hash}`);
|
|
271
271
|
}
|
|
272
272
|
else {
|
|
273
|
-
return await this.raw.getHash(pdf.hash);
|
|
273
|
+
return await this.raw.getHash(pdf.id, pdf.hash);
|
|
274
274
|
}
|
|
275
275
|
}
|
|
276
|
-
async getEpub(hash) {
|
|
277
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
276
|
+
async getEpub(id, hash) {
|
|
277
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
278
278
|
const [epub] = entries.filter((e) => e.id.endsWith(".epub"));
|
|
279
279
|
if (epub === undefined) {
|
|
280
280
|
throw new Error(`couldn't find epub for hash ${hash}`);
|
|
281
281
|
}
|
|
282
282
|
else {
|
|
283
|
-
return await this.raw.getHash(epub.hash);
|
|
283
|
+
return await this.raw.getHash(epub.id, epub.hash);
|
|
284
284
|
}
|
|
285
285
|
}
|
|
286
|
-
async getDocument(hash) {
|
|
287
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
286
|
+
async getDocument(id, hash) {
|
|
287
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
288
288
|
const zip = new JSZip();
|
|
289
289
|
for (const entry of entries) {
|
|
290
290
|
// TODO if this is .metadata we might want to assert type === "DocumentType"
|
|
291
|
-
zip.file(entry.id, this.raw.getHash(entry.hash));
|
|
291
|
+
zip.file(entry.id, this.raw.getHash(entry.id, entry.hash));
|
|
292
292
|
}
|
|
293
293
|
return zip.generateAsync({ type: "uint8array" });
|
|
294
294
|
}
|
|
@@ -344,7 +344,7 @@ class Remarkable {
|
|
|
344
344
|
// now fetch root entries and upload this file entry
|
|
345
345
|
const [[collectionEntry, uploadCollection], { entries: rootEntries }] = await Promise.all([
|
|
346
346
|
this.raw.putEntries(id, [contentEntry, metadataEntry, pagedataEntry, fileEntry], schemaVersion),
|
|
347
|
-
this.raw.getEntries(rootHash),
|
|
347
|
+
this.raw.getEntries("root.docSchema", rootHash),
|
|
348
348
|
]);
|
|
349
349
|
// now upload a new root entry
|
|
350
350
|
rootEntries.push(collectionEntry);
|
|
@@ -398,7 +398,7 @@ class Remarkable {
|
|
|
398
398
|
// now fetch root entries and upload this file entry
|
|
399
399
|
const [[collectionEntry, uploadCollection], { entries: rootEntries }] = await Promise.all([
|
|
400
400
|
this.raw.putEntries(id, [contentEntry, metadataEntry], schemaVersion),
|
|
401
|
-
this.raw.getEntries(rootHash),
|
|
401
|
+
this.raw.getEntries("root.docSchema", rootHash),
|
|
402
402
|
]);
|
|
403
403
|
// now upload a new root entry
|
|
404
404
|
rootEntries.push(collectionEntry);
|
|
@@ -428,13 +428,13 @@ class Remarkable {
|
|
|
428
428
|
}
|
|
429
429
|
/** edit just a content entry */
|
|
430
430
|
async #editContentRaw(id, hash, update, schemaVersion) {
|
|
431
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
431
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
432
432
|
const contInd = entries.findIndex((ent) => ent.id.endsWith(".content"));
|
|
433
433
|
const contEntry = entries[contInd];
|
|
434
434
|
if (contEntry === undefined) {
|
|
435
435
|
throw new Error("internal error: couldn't find content in entry hash");
|
|
436
436
|
}
|
|
437
|
-
const cont = await this.raw.getContent(contEntry.hash);
|
|
437
|
+
const cont = await this.raw.getContent(contEntry.id, contEntry.hash);
|
|
438
438
|
Object.assign(cont, update);
|
|
439
439
|
const [newContEntry, uploadCont] = await this.raw.putContent(contEntry.id, cont);
|
|
440
440
|
entries[contInd] = newContEntry;
|
|
@@ -445,7 +445,7 @@ class Remarkable {
|
|
|
445
445
|
/** fully sync a content edit */
|
|
446
446
|
async #editContent(hash, update, expectedType, refresh) {
|
|
447
447
|
const [rootHash, generation, schemaVersion] = await this.#getRootHash(refresh);
|
|
448
|
-
const { entries } = await this.raw.getEntries(rootHash);
|
|
448
|
+
const { entries } = await this.raw.getEntries("root.docSchema", rootHash);
|
|
449
449
|
const hashInd = entries.findIndex((ent) => ent.hash === hash);
|
|
450
450
|
const hashEnt = entries[hashInd];
|
|
451
451
|
if (hashEnt === undefined) {
|
|
@@ -453,7 +453,7 @@ class Remarkable {
|
|
|
453
453
|
}
|
|
454
454
|
const [[newEnt, uploadEnt], meta] = await Promise.all([
|
|
455
455
|
this.#editContentRaw(hashEnt.id, hash, update, schemaVersion),
|
|
456
|
-
this.getMetadata(hash),
|
|
456
|
+
this.getMetadata(hashEnt.id, hash),
|
|
457
457
|
]);
|
|
458
458
|
if (meta.type !== expectedType) {
|
|
459
459
|
throw new Error(`expected type ${expectedType} but got ${meta.type} for hash ${hash}`);
|
|
@@ -477,13 +477,13 @@ class Remarkable {
|
|
|
477
477
|
return await this.#editContent(hash, content, "TemplateType", refresh);
|
|
478
478
|
}
|
|
479
479
|
async #editMetaRaw(id, hash, update, schemaVersion) {
|
|
480
|
-
const { entries } = await this.raw.getEntries(hash);
|
|
480
|
+
const { entries } = await this.raw.getEntries(`${id}.docSchema`, hash);
|
|
481
481
|
const metaInd = entries.findIndex((ent) => ent.id.endsWith(".metadata"));
|
|
482
482
|
const metaEntry = entries[metaInd];
|
|
483
483
|
if (metaEntry === undefined) {
|
|
484
484
|
throw new Error("internal error: couldn't find metadata in entry hash");
|
|
485
485
|
}
|
|
486
|
-
const meta = await this.raw.getMetadata(metaEntry.hash);
|
|
486
|
+
const meta = await this.raw.getMetadata(metaEntry.id, metaEntry.hash);
|
|
487
487
|
Object.assign(meta, update);
|
|
488
488
|
const [newMetaEntry, uploadMeta] = await this.raw.putMetadata(metaEntry.id, meta);
|
|
489
489
|
entries[metaInd] = newMetaEntry;
|
|
@@ -493,7 +493,7 @@ class Remarkable {
|
|
|
493
493
|
}
|
|
494
494
|
async #editMeta(hash, update, refresh = false) {
|
|
495
495
|
const [rootHash, generation, schemaVersion] = await this.#getRootHash(refresh);
|
|
496
|
-
const { entries } = await this.raw.getEntries(rootHash);
|
|
496
|
+
const { entries } = await this.raw.getEntries("root.docSchema", rootHash);
|
|
497
497
|
const hashInd = entries.findIndex((ent) => ent.hash === hash);
|
|
498
498
|
const hashEnt = entries[hashInd];
|
|
499
499
|
if (hashEnt === undefined) {
|
|
@@ -531,7 +531,7 @@ class Remarkable {
|
|
|
531
531
|
throw new ValidationError(parent, idReg, "parent must be a valid document id");
|
|
532
532
|
}
|
|
533
533
|
const [rootHash, generation, schemaVersion] = await this.#getRootHash(refresh);
|
|
534
|
-
const { entries } = await this.raw.getEntries(rootHash);
|
|
534
|
+
const { entries } = await this.raw.getEntries("root.docSchema", rootHash);
|
|
535
535
|
const hashSet = new Set(hashes);
|
|
536
536
|
const toUpdate = [];
|
|
537
537
|
const newEntries = [];
|
|
@@ -568,15 +568,15 @@ class Remarkable {
|
|
|
568
568
|
// should only go one step) to track all hashes encountered
|
|
569
569
|
// NOTE that we could increase the cache in this process, or it's possible
|
|
570
570
|
// for other calls to increase the cache with misc values.
|
|
571
|
-
const base = await this.raw.getEntries(rootHash);
|
|
571
|
+
const base = await this.raw.getEntries("root.docSchema", rootHash);
|
|
572
572
|
let entries = [base.entries];
|
|
573
573
|
let nextEntries = [];
|
|
574
574
|
while (entries.length) {
|
|
575
575
|
for (const entryList of entries) {
|
|
576
|
-
for (const { hash, type } of entryList) {
|
|
576
|
+
for (const { hash, type, id } of entryList) {
|
|
577
577
|
toDelete.add(hash);
|
|
578
578
|
if (type === 80000000) {
|
|
579
|
-
nextEntries.push(this.raw.getEntries(hash));
|
|
579
|
+
nextEntries.push(this.raw.getEntries(`${id}.docSchema`, hash));
|
|
580
580
|
}
|
|
581
581
|
}
|
|
582
582
|
}
|
package/dist/raw.d.ts
CHANGED
|
@@ -431,50 +431,58 @@ export interface RawRemarkableApi {
|
|
|
431
431
|
/**
|
|
432
432
|
* get the raw binary data associated with a hash
|
|
433
433
|
*
|
|
434
|
+
* @param fileName - the logical file name (`<id>.<ext>` for files, or
|
|
435
|
+
* `<id>.docSchema` / `"root.docSchema"` for entry indexes). reMarkable
|
|
436
|
+
* validates this against the rm-filename header.
|
|
434
437
|
* @param hash - the hash to get the data for
|
|
435
438
|
* @returns the data
|
|
436
439
|
*/
|
|
437
|
-
getHash(hash: string): Promise<Uint8Array>;
|
|
440
|
+
getHash(fileName: string, hash: string): Promise<Uint8Array>;
|
|
438
441
|
/**
|
|
439
442
|
* get raw text data associated with a hash
|
|
440
443
|
*
|
|
441
444
|
* We assume text data are small, and so cache the entire text. If you want to
|
|
442
445
|
* avoid this, use {@link getHash | `getHash`} combined with a TextDecoder.
|
|
443
446
|
|
|
447
|
+
* @param fileName - the logical file name (see {@link getHash})
|
|
444
448
|
* @param hash - the hash to get text for
|
|
445
449
|
* @returns the text
|
|
446
450
|
*/
|
|
447
|
-
getText(hash: string): Promise<string>;
|
|
451
|
+
getText(fileName: string, hash: string): Promise<string>;
|
|
448
452
|
/**
|
|
449
453
|
* get the entries associated with a list hash
|
|
450
454
|
*
|
|
451
455
|
* A list hash is the root hash, or any hash with the type 80000000. NOTE
|
|
452
456
|
* these are hashed differently than files.
|
|
453
457
|
|
|
458
|
+
* @param fileName - `"root.docSchema"` for the root, or `"<id>.docSchema"`
|
|
459
|
+
* for a sub-document's entry index
|
|
454
460
|
* @param hash - the hash to get entries for
|
|
455
461
|
* @returns the entries
|
|
456
462
|
*/
|
|
457
|
-
getEntries(hash: string): Promise<Entries>;
|
|
463
|
+
getEntries(fileName: string, hash: string): Promise<Entries>;
|
|
458
464
|
/**
|
|
459
465
|
* get the parsed and validated `Content` of a content hash
|
|
460
466
|
*
|
|
461
467
|
* Use {@link getText | `getText`} combined with `JSON.parse` to bypass
|
|
462
468
|
* validation
|
|
463
469
|
|
|
470
|
+
* @param fileName - typically `"<id>.content"`
|
|
464
471
|
* @param hash - the hash to get Content for
|
|
465
472
|
* @returns the content
|
|
466
473
|
*/
|
|
467
|
-
getContent(hash: string): Promise<Content>;
|
|
474
|
+
getContent(fileName: string, hash: string): Promise<Content>;
|
|
468
475
|
/**
|
|
469
476
|
* get the parsed and validated `Metadata` of a metadata hash
|
|
470
477
|
*
|
|
471
478
|
* Use {@link getText | `getText`} combined with `JSON.parse` to bypass
|
|
472
479
|
* validation
|
|
473
480
|
|
|
481
|
+
* @param fileName - typically `"<id>.metadata"`
|
|
474
482
|
* @param hash - the hash to get Metadata for
|
|
475
483
|
* @returns the metadata
|
|
476
484
|
*/
|
|
477
|
-
getMetadata(hash: string): Promise<Metadata>;
|
|
485
|
+
getMetadata(fileName: string, hash: string): Promise<Metadata>;
|
|
478
486
|
/**
|
|
479
487
|
* update the current root hash
|
|
480
488
|
*
|
|
@@ -564,11 +572,11 @@ export declare class RawRemarkable implements RawRemarkableApi {
|
|
|
564
572
|
constructor(authedFetch: AuthedFetch, cache: Map<string, string | null>, rawHost: string, uploadHost: string);
|
|
565
573
|
/** make an authorized request to remarkable */
|
|
566
574
|
getRootHash(): Promise<[string, number, SchemaVersion]>;
|
|
567
|
-
getHash(hash: string): Promise<Uint8Array>;
|
|
568
|
-
getText(hash: string): Promise<string>;
|
|
569
|
-
getEntries(hash: string): Promise<Entries>;
|
|
570
|
-
getContent(hash: string): Promise<Content>;
|
|
571
|
-
getMetadata(hash: string): Promise<Metadata>;
|
|
575
|
+
getHash(fileName: string, hash: string): Promise<Uint8Array>;
|
|
576
|
+
getText(fileName: string, hash: string): Promise<string>;
|
|
577
|
+
getEntries(fileName: string, hash: string): Promise<Entries>;
|
|
578
|
+
getContent(fileName: string, hash: string): Promise<Content>;
|
|
579
|
+
getMetadata(fileName: string, hash: string): Promise<Metadata>;
|
|
572
580
|
putRootHash(hash: string, generation: number, broadcast?: boolean): Promise<[string, number]>;
|
|
573
581
|
putFile(id: string, bytes: Uint8Array): Promise<[RawEntry, Promise<void>]>;
|
|
574
582
|
putText(id: string, text: string): Promise<[RawEntry, Promise<void>]>;
|
package/dist/raw.js
CHANGED
|
@@ -222,23 +222,23 @@ export class RawRemarkable {
|
|
|
222
222
|
return [hash, generation, schemaVersion];
|
|
223
223
|
}
|
|
224
224
|
}
|
|
225
|
-
async #getHash(hash) {
|
|
225
|
+
async #getHash(fileName, hash) {
|
|
226
226
|
if (!hashReg.test(hash)) {
|
|
227
227
|
throw new ValidationError(hash, hashReg, "hash was not a valid hash");
|
|
228
228
|
}
|
|
229
|
-
const resp = await this.#authedFetch("GET", `${this.#rawHost}/sync/v3/files/${hash}
|
|
229
|
+
const resp = await this.#authedFetch("GET", `${this.#rawHost}/sync/v3/files/${hash}`, { headers: { "rm-filename": fileName } });
|
|
230
230
|
// TODO switch to `.bytes()`.
|
|
231
231
|
const raw = await resp.arrayBuffer();
|
|
232
232
|
return new Uint8Array(raw);
|
|
233
233
|
}
|
|
234
|
-
async getHash(hash) {
|
|
234
|
+
async getHash(fileName, hash) {
|
|
235
235
|
const cached = this.#cache.get(hash);
|
|
236
236
|
if (cached != null) {
|
|
237
237
|
const enc = new TextEncoder();
|
|
238
238
|
return enc.encode(cached);
|
|
239
239
|
}
|
|
240
240
|
else {
|
|
241
|
-
const res = await this.#getHash(hash);
|
|
241
|
+
const res = await this.#getHash(fileName, hash);
|
|
242
242
|
// mark that we know hash exists
|
|
243
243
|
const cacheVal = this.#cache.get(hash);
|
|
244
244
|
if (cacheVal === undefined) {
|
|
@@ -247,22 +247,22 @@ export class RawRemarkable {
|
|
|
247
247
|
return res;
|
|
248
248
|
}
|
|
249
249
|
}
|
|
250
|
-
async getText(hash) {
|
|
250
|
+
async getText(fileName, hash) {
|
|
251
251
|
const cached = this.#cache.get(hash);
|
|
252
252
|
if (cached != null) {
|
|
253
253
|
return cached;
|
|
254
254
|
}
|
|
255
255
|
else {
|
|
256
256
|
// NOTE two simultaneous requests will fetch twice
|
|
257
|
-
const raw = await this.#getHash(hash);
|
|
257
|
+
const raw = await this.#getHash(fileName, hash);
|
|
258
258
|
const dec = new TextDecoder();
|
|
259
259
|
const res = dec.decode(raw);
|
|
260
260
|
this.#cache.set(hash, res);
|
|
261
261
|
return res;
|
|
262
262
|
}
|
|
263
263
|
}
|
|
264
|
-
async getEntries(hash) {
|
|
265
|
-
const rawFile = await this.getText(hash);
|
|
264
|
+
async getEntries(fileName, hash) {
|
|
265
|
+
const rawFile = await this.getText(fileName, hash);
|
|
266
266
|
const [version, ...rest] = rawFile.slice(0, -1).split("\n");
|
|
267
267
|
if (version === "3") {
|
|
268
268
|
return { entries: rest.map(parseRawEntryLine) };
|
|
@@ -290,8 +290,8 @@ export class RawRemarkable {
|
|
|
290
290
|
throw new Error(`schema version ${version} not supported`);
|
|
291
291
|
}
|
|
292
292
|
}
|
|
293
|
-
async getContent(hash) {
|
|
294
|
-
const raw = await this.getText(hash);
|
|
293
|
+
async getContent(fileName, hash) {
|
|
294
|
+
const raw = await this.getText(fileName, hash);
|
|
295
295
|
const loaded = JSON.parse(raw);
|
|
296
296
|
// jtd can't verify non-discriminated unions, in this case, we have fileType
|
|
297
297
|
// defined or not. As a result, we try each, and concatenate the errors at the end
|
|
@@ -313,8 +313,8 @@ export class RawRemarkable {
|
|
|
313
313
|
const joined = errors.join("\n\nor\n\n");
|
|
314
314
|
throw new Error(`invalid content: ${joined}`);
|
|
315
315
|
}
|
|
316
|
-
async getMetadata(hash) {
|
|
317
|
-
const raw = await this.getText(hash);
|
|
316
|
+
async getMetadata(fileName, hash) {
|
|
317
|
+
const raw = await this.getText(fileName, hash);
|
|
318
318
|
const loaded = JSON.parse(raw);
|
|
319
319
|
if (!metadata.guardAssert(loaded))
|
|
320
320
|
throw Error("invalid metadata");
|
|
@@ -345,7 +345,7 @@ export class RawRemarkable {
|
|
|
345
345
|
throw new Error(`new generation ${newGen} was not a safe integer; please file a bug report`);
|
|
346
346
|
}
|
|
347
347
|
}
|
|
348
|
-
async #putFile(
|
|
348
|
+
async #putFile(fileName, hash, bytes) {
|
|
349
349
|
// if the hash is already in the cache, writing is pointless
|
|
350
350
|
if (!this.#cache.has(hash)) {
|
|
351
351
|
const crc = CRC32C.buf(bytes, 0);
|
|
@@ -376,7 +376,7 @@ export class RawRemarkable {
|
|
|
376
376
|
subfiles: 0,
|
|
377
377
|
size: bytes.length,
|
|
378
378
|
};
|
|
379
|
-
return [res, this.#putFile(
|
|
379
|
+
return [res, this.#putFile(id, hash, bytes)];
|
|
380
380
|
}
|
|
381
381
|
async putText(id, text) {
|
|
382
382
|
const enc = new TextEncoder();
|
|
@@ -444,11 +444,7 @@ export class RawRemarkable {
|
|
|
444
444
|
subfiles: entries.length,
|
|
445
445
|
size,
|
|
446
446
|
};
|
|
447
|
-
return [
|
|
448
|
-
res,
|
|
449
|
-
// NOTE when monitoring requests, this had the extension .docSchema appended, but I'm not entirely sure why
|
|
450
|
-
this.#putFile(hash, `${id}.docSchema`, entryBuff),
|
|
451
|
-
];
|
|
447
|
+
return [res, this.#putFile(`${id}.docSchema`, hash, entryBuff)];
|
|
452
448
|
}
|
|
453
449
|
async uploadFile(visibleName, bytes, mime) {
|
|
454
450
|
const enc = new TextEncoder();
|