@peerbit/please-lib 0.0.6 → 0.0.8

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,71 +1,99 @@
1
1
  import { Program } from "@peerbit/program";
2
- import { Documents, Role } from "@peerbit/document";
3
- import { ProgramClient } from "@peerbit/program";
4
- declare abstract class AbstractFile {
2
+ import { Documents, RoleOptions } from "@peerbit/document";
3
+ import { PublicSignKey } from "@peerbit/crypto";
4
+ import { TrustedNetwork } from "@peerbit/trusted-network";
5
+ export declare abstract class AbstractFile {
5
6
  abstract id: string;
6
7
  abstract name: string;
7
- abstract getFile(files: Files): Promise<Uint8Array | undefined>;
8
+ abstract size: number;
9
+ abstract parentId?: string;
10
+ abstract getFile<OutputType extends "chunks" | "joined" = "joined", Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array>(files: Files, properties?: {
11
+ as: OutputType;
12
+ timeout?: number;
13
+ progress?: (progress: number) => any;
14
+ }): Promise<Output>;
15
+ abstract delete(files: Files): Promise<void>;
8
16
  }
9
17
  export declare class TinyFile extends AbstractFile {
10
18
  id: string;
11
19
  name: string;
12
20
  file: Uint8Array;
21
+ parentId?: string;
22
+ get size(): number;
13
23
  constructor(properties: {
24
+ id?: string;
14
25
  name: string;
15
26
  file: Uint8Array;
27
+ parentId?: string;
16
28
  });
17
- getFile(_files: Files): Promise<Uint8Array>;
18
- }
19
- export declare class SmallFile extends AbstractFile {
20
- id: string;
21
- name: string;
22
- cid: string;
23
- constructor(properties: {
24
- name: string;
25
- cid: string;
26
- });
27
- static create(node: ProgramClient, name: string, file: Uint8Array): Promise<SmallFile>;
28
- getFile(files: Files): Promise<Uint8Array | undefined>;
29
+ getFile<OutputType extends "chunks" | "joined" = "joined", Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array>(_files: Files, properties?: {
30
+ as: OutputType;
31
+ progress?: (progress: number) => any;
32
+ }): Promise<Output>;
33
+ delete(): Promise<void>;
29
34
  }
30
35
  export declare class LargeFile extends AbstractFile {
31
36
  id: string;
32
37
  name: string;
33
38
  fileIds: string[];
39
+ size: number;
34
40
  constructor(properties: {
35
41
  id: string;
36
42
  name: string;
37
43
  fileIds: string[];
44
+ size: number;
38
45
  });
39
- static create(name: string, file: Uint8Array, files: Files): Promise<LargeFile>;
40
- getFile(files: Files): Promise<Uint8Array>;
46
+ static create(name: string, file: Uint8Array, files: Files, progress?: (progress: number) => void): Promise<LargeFile>;
47
+ get parentId(): undefined;
48
+ fetchChunks(files: Files): Promise<AbstractFile[]>;
49
+ delete(files: Files): Promise<void>;
50
+ getFile<OutputType extends "chunks" | "joined" = "joined", Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array>(files: Files, properties?: {
51
+ as: OutputType;
52
+ timeout?: number;
53
+ progress?: (progress: number) => any;
54
+ }): Promise<Output>;
41
55
  }
42
56
  type Args = {
43
- role: Role;
57
+ role: RoleOptions;
44
58
  };
45
59
  export declare class Files extends Program<Args> {
46
60
  id: Uint8Array;
61
+ name: string;
62
+ trustGraph?: TrustedNetwork;
47
63
  files: Documents<AbstractFile>;
48
- constructor(id?: Uint8Array);
49
- create(name: string, file: Uint8Array): Promise<string>;
64
+ constructor(properties?: {
65
+ id?: Uint8Array;
66
+ name?: string;
67
+ rootKey?: PublicSignKey;
68
+ });
69
+ add(name: string, file: Uint8Array, parentId?: string, progress?: (progress: number) => void): Promise<string>;
70
+ removeById(id: string): Promise<void>;
71
+ removeByName(name: string): Promise<void>;
72
+ list(): Promise<AbstractFile[]>;
73
+ listLocalChunks(parent: LargeFile): Promise<AbstractFile[]>;
50
74
  /**
51
75
  * Get by name
52
76
  * @param id
53
77
  * @returns
54
78
  */
55
- getById(id: string): Promise<{
79
+ getById<OutputType extends "chunks" | "joined" = "joined", Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array>(id: string, properties?: {
80
+ as: OutputType;
81
+ }): Promise<{
56
82
  id: string;
57
83
  name: string;
58
- bytes: Uint8Array;
84
+ bytes: Output;
59
85
  } | undefined>;
60
86
  /**
61
87
  * Get by name
62
88
  * @param name
63
89
  * @returns
64
90
  */
65
- getByName(name: string): Promise<{
91
+ getByName<OutputType extends "chunks" | "joined" = "joined", Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array>(name: string, properties?: {
92
+ as: OutputType;
93
+ }): Promise<{
66
94
  id: string;
67
95
  name: string;
68
- bytes: Uint8Array;
96
+ bytes: Output;
69
97
  } | undefined>;
70
98
  open(args?: Args): Promise<void>;
71
99
  }
package/lib/esm/index.js CHANGED
@@ -7,30 +7,42 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
7
7
  var __metadata = (this && this.__metadata) || function (k, v) {
8
8
  if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
9
9
  };
10
- var SmallFile_1, LargeFile_1;
11
- import { field, variant, vec } from "@dao-xyz/borsh";
10
+ var LargeFile_1;
11
+ import { field, variant, vec, option } from "@dao-xyz/borsh";
12
12
  import { Program } from "@peerbit/program";
13
- import { Documents, SearchRequest, StringMatch } from "@peerbit/document";
13
+ import { Documents, SearchRequest, StringMatch, StringMatchMethod, Or, MissingField, } from "@peerbit/document";
14
14
  import { sha256Base64Sync, randomBytes } from "@peerbit/crypto";
15
15
  import { concat } from "uint8arrays";
16
- class AbstractFile {
16
+ import { sha256Sync } from "@peerbit/crypto";
17
+ import { TrustedNetwork } from "@peerbit/trusted-network";
18
+ import PQueue from "p-queue";
19
+ export class AbstractFile {
17
20
  }
18
- const TINY_FILE_SIZE_LIMIT = 1e3;
19
- export let TinyFile = class TinyFile extends AbstractFile {
21
+ const TINY_FILE_SIZE_LIMIT = 5 * 1e6; // 6mb
22
+ let TinyFile = class TinyFile extends AbstractFile {
20
23
  id;
21
24
  name;
22
25
  file; // 10 mb imit
26
+ parentId;
27
+ get size() {
28
+ return this.file.byteLength;
29
+ }
23
30
  constructor(properties) {
24
31
  super();
25
- this.id = sha256Base64Sync(properties.file);
32
+ this.id = properties.id || sha256Base64Sync(properties.file);
26
33
  this.name = properties.name;
27
34
  this.file = properties.file;
35
+ this.parentId = properties.parentId;
28
36
  }
29
- async getFile(_files) {
37
+ async getFile(_files, properties) {
30
38
  if (sha256Base64Sync(this.file) !== this.id) {
31
39
  throw new Error("Hash does not match the file content");
32
40
  }
33
- return Promise.resolve(this.file);
41
+ properties?.progress?.(1);
42
+ return Promise.resolve(properties?.as == "chunks" ? [this.file] : this.file);
43
+ }
44
+ async delete() {
45
+ // Do nothing, since no releated files where created
34
46
  }
35
47
  };
36
48
  __decorate([
@@ -45,98 +57,113 @@ __decorate([
45
57
  field({ type: Uint8Array }),
46
58
  __metadata("design:type", Uint8Array)
47
59
  ], TinyFile.prototype, "file", void 0);
60
+ __decorate([
61
+ field({ type: option("string") }),
62
+ __metadata("design:type", String)
63
+ ], TinyFile.prototype, "parentId", void 0);
48
64
  TinyFile = __decorate([
49
65
  variant(0) // for versioning purposes
50
66
  ,
51
67
  __metadata("design:paramtypes", [Object])
52
68
  ], TinyFile);
53
- const SMALL_FILE_SIZE_LIMIT = 1e6 * 9;
54
- export let SmallFile = SmallFile_1 = class SmallFile extends AbstractFile {
55
- id; // cid
56
- name;
57
- cid; // store file separately in a block store, like IPFS
58
- constructor(properties) {
59
- super();
60
- this.id = properties.cid;
61
- this.name = properties.name;
62
- this.cid = properties.cid;
63
- }
64
- static async create(node, name, file) {
65
- if (file.length > SMALL_FILE_SIZE_LIMIT) {
66
- throw new Error("To large file for SmallFile");
67
- }
68
- const cid = await node.services.blocks.put(file);
69
- return new SmallFile_1({ name, cid });
70
- }
71
- async getFile(files) {
72
- // Load the file from the block store
73
- return await files.node.services.blocks.get(this.id);
74
- }
75
- };
76
- __decorate([
77
- field({ type: "string" }),
78
- __metadata("design:type", String)
79
- ], SmallFile.prototype, "id", void 0);
80
- __decorate([
81
- field({ type: "string" }),
82
- __metadata("design:type", String)
83
- ], SmallFile.prototype, "name", void 0);
84
- __decorate([
85
- field({ type: "string" }),
86
- __metadata("design:type", String)
87
- ], SmallFile.prototype, "cid", void 0);
88
- SmallFile = SmallFile_1 = __decorate([
89
- variant(1) // for versioning purposes
90
- ,
91
- __metadata("design:paramtypes", [Object])
92
- ], SmallFile);
93
- export let LargeFile = LargeFile_1 = class LargeFile extends AbstractFile {
69
+ export { TinyFile };
70
+ let LargeFile = LargeFile_1 = class LargeFile extends AbstractFile {
94
71
  id; // hash
95
72
  name;
96
73
  fileIds;
74
+ size;
97
75
  constructor(properties) {
98
76
  super();
99
77
  this.id = properties.id;
100
78
  this.name = properties.name;
101
79
  this.fileIds = properties.fileIds;
80
+ this.size = properties.size;
102
81
  }
103
- static async create(name, file, files) {
104
- const segmetSize = SMALL_FILE_SIZE_LIMIT / 10; // 10% of the small size limit
82
+ static async create(name, file, files, progress) {
83
+ const segmetSize = TINY_FILE_SIZE_LIMIT / 10; // 10% of the small size limit
105
84
  const fileIds = [];
106
85
  const id = sha256Base64Sync(file);
107
- for (let i = 0; i < Math.ceil(file.byteLength / segmetSize); i++) {
108
- fileIds.push(await files.create(id + "/" + name, file.subarray(i * segmetSize, Math.min((i + 1) * segmetSize, file.length))));
86
+ const fileSize = file.byteLength;
87
+ progress?.(0);
88
+ const end = Math.ceil(file.byteLength / segmetSize);
89
+ for (let i = 0; i < end; i++) {
90
+ progress?.((i + 1) / end);
91
+ fileIds.push(await files.add(name + "/" + i, file.subarray(i * segmetSize, Math.min((i + 1) * segmetSize, file.byteLength)), id));
109
92
  }
110
- return new LargeFile_1({ id, name, fileIds });
93
+ progress?.(1);
94
+ return new LargeFile_1({ id, name, fileIds: fileIds, size: fileSize });
111
95
  }
112
- async getFile(files) {
113
- // Get all sub files (SmallFiles) and concatinate them in the right order (the order of this.fileIds)
96
+ get parentId() {
97
+ // Large file can never have a parent
98
+ return undefined;
99
+ }
100
+ async fetchChunks(files) {
114
101
  const expectedIds = new Set(this.fileIds);
115
- const chunks = new Map();
116
- const results = await files.files.index.search(new SearchRequest({
102
+ const allFiles = await files.files.index.search(new SearchRequest({
117
103
  query: [
118
- new StringMatch({
119
- key: "name",
120
- value: this.id + "/" + this.name,
121
- }),
104
+ new Or([...expectedIds].map((x) => new StringMatch({ key: "id", value: x }))),
122
105
  ],
123
- }), {
124
- local: true,
125
- remote: true,
106
+ }));
107
+ return allFiles;
108
+ }
109
+ async delete(files) {
110
+ await Promise.all((await this.fetchChunks(files)).map((x) => x.delete(files)));
111
+ }
112
+ async getFile(files, properties) {
113
+ // Get all sub files (SmallFiles) and concatinate them in the right order (the order of this.fileIds)
114
+ properties?.progress?.(0);
115
+ console.log("LISTS CHUNKS!");
116
+ const allChunks = await this.fetchChunks(files);
117
+ console.log("RECEIVED CHUNKS: " + allChunks);
118
+ console.log("FETCH CHUNKS");
119
+ const fetchQueue = new PQueue({ concurrency: 10 });
120
+ let fetchError = undefined;
121
+ fetchQueue.on("error", (err) => {
122
+ fetchError = err;
126
123
  });
127
- if (results.length > 0) {
128
- for (const r of results) {
124
+ const chunks = new Map();
125
+ const expectedIds = new Set(this.fileIds);
126
+ if (allChunks.length > 0) {
127
+ let c = 0;
128
+ for (const r of allChunks) {
129
129
  if (chunks.has(r.id)) {
130
130
  // chunk already added;
131
131
  }
132
132
  if (!expectedIds.has(r.id)) {
133
133
  // chunk is not part of this file
134
134
  }
135
- chunks.set(r.id, r.getFile(files));
135
+ fetchQueue
136
+ .add(async () => {
137
+ let lastError = undefined;
138
+ for (let i = 0; i < 3; i++) {
139
+ try {
140
+ const chunk = await r.getFile(files, {
141
+ as: "joined",
142
+ timeout: properties?.timeout,
143
+ });
144
+ if (!chunk) {
145
+ throw new Error("Failed to fetch chunk");
146
+ }
147
+ chunks.set(r.id, chunk);
148
+ c++;
149
+ properties?.progress?.(c / allChunks.length);
150
+ return;
151
+ }
152
+ catch (error) {
153
+ // try 3 times
154
+ lastError = error;
155
+ }
156
+ }
157
+ throw lastError;
158
+ })
159
+ .catch(() => {
160
+ fetchQueue.clear(); // Dont do anything more since we failed to fetch one block
161
+ });
136
162
  }
137
163
  }
138
- if (chunks.size !== expectedIds.size) {
139
- throw new Error("Failed to resolve file");
164
+ await fetchQueue.onIdle();
165
+ if (fetchError || chunks.size !== expectedIds.size) {
166
+ throw new Error(`Failed to resolve file. Recieved ${chunks.size}/${expectedIds.size} chunks`);
140
167
  }
141
168
  const chunkContentResolved = await Promise.all(this.fileIds.map(async (x) => {
142
169
  const chunkValue = await chunks.get(x);
@@ -145,7 +172,10 @@ export let LargeFile = LargeFile_1 = class LargeFile extends AbstractFile {
145
172
  }
146
173
  return chunkValue;
147
174
  }));
148
- return concat(chunkContentResolved);
175
+ console.log("FETCH DONE");
176
+ return (properties?.as == "chunks"
177
+ ? chunkContentResolved
178
+ : concat(chunkContentResolved));
149
179
  }
150
180
  };
151
181
  __decorate([
@@ -160,40 +190,99 @@ __decorate([
160
190
  field({ type: vec("string") }),
161
191
  __metadata("design:type", Array)
162
192
  ], LargeFile.prototype, "fileIds", void 0);
193
+ __decorate([
194
+ field({ type: "u32" }),
195
+ __metadata("design:type", Number)
196
+ ], LargeFile.prototype, "size", void 0);
163
197
  LargeFile = LargeFile_1 = __decorate([
164
- variant(2) // for versioning purposes
198
+ variant(1) // for versioning purposes
165
199
  ,
166
200
  __metadata("design:paramtypes", [Object])
167
201
  ], LargeFile);
168
- export let Files = class Files extends Program {
202
+ export { LargeFile };
203
+ let Files = class Files extends Program {
169
204
  id;
205
+ name;
206
+ trustGraph;
170
207
  files;
171
- constructor(id = randomBytes(32)) {
208
+ constructor(properties = {}) {
172
209
  super();
173
- this.id = id;
174
- this.files = new Documents({ id: this.id });
210
+ this.id = properties.id || randomBytes(32);
211
+ this.name = properties.name || "";
212
+ this.trustGraph = properties.rootKey
213
+ ? new TrustedNetwork({ id: this.id, rootTrust: properties.rootKey })
214
+ : undefined;
215
+ this.files = new Documents({
216
+ id: sha256Sync(concat([
217
+ this.id,
218
+ new TextEncoder().encode(this.name),
219
+ properties.rootKey?.bytes || new Uint8Array(0),
220
+ ])),
221
+ });
175
222
  }
176
- async create(name, file) {
223
+ async add(name, file, parentId, progress) {
177
224
  let toPut;
225
+ progress?.(0);
178
226
  if (file.byteLength <= TINY_FILE_SIZE_LIMIT) {
179
- toPut = new TinyFile({ name, file });
180
- }
181
- else if (file.byteLength > TINY_FILE_SIZE_LIMIT &&
182
- file.byteLength <= SMALL_FILE_SIZE_LIMIT) {
183
- toPut = await SmallFile.create(this.node, name, file);
227
+ toPut = new TinyFile({ name, file, parentId });
184
228
  }
185
229
  else {
186
- toPut = await LargeFile.create(name, file, this);
230
+ if (parentId) {
231
+ throw new Error("Unexpected that a LargeFile to have a parent");
232
+ }
233
+ toPut = await LargeFile.create(name, file, this, progress);
187
234
  }
188
235
  await this.files.put(toPut);
236
+ progress?.(1);
189
237
  return toPut.id;
190
238
  }
239
+ async removeById(id) {
240
+ const file = await this.files.index.get(id);
241
+ if (file) {
242
+ await file.delete(this);
243
+ await this.files.del(file.id);
244
+ }
245
+ }
246
+ async removeByName(name) {
247
+ const files = await this.files.index.search(new SearchRequest({
248
+ query: new StringMatch({
249
+ key: ["name"],
250
+ value: name,
251
+ caseInsensitive: false,
252
+ method: StringMatchMethod.exact,
253
+ }),
254
+ }));
255
+ for (const file of files) {
256
+ await file.delete(this);
257
+ await this.files.del(file.id);
258
+ }
259
+ }
260
+ async list() {
261
+ // only root files (don't fetch fetch chunks here)
262
+ const files = await this.files.index.search(new SearchRequest({ query: new MissingField({ key: "parentId" }) }), {
263
+ local: true,
264
+ remote: {
265
+ throwOnMissing: true,
266
+ sync: true, // sync here because this, because we might want to access it offline, even though we are not replicators
267
+ },
268
+ });
269
+ return files;
270
+ }
271
+ async listLocalChunks(parent) {
272
+ const files = await this.files.index.search(new SearchRequest({
273
+ query: new StringMatch({ key: "parentId", value: parent.id }),
274
+ }), {
275
+ local: true,
276
+ remote: false,
277
+ });
278
+ return files;
279
+ }
191
280
  /**
192
281
  * Get by name
193
282
  * @param id
194
283
  * @returns
195
284
  */
196
- async getById(id) {
285
+ async getById(id, properties) {
197
286
  const results = await this.files.index.search(new SearchRequest({
198
287
  query: [new StringMatch({ key: "id", value: id })],
199
288
  }), {
@@ -203,9 +292,13 @@ export let Files = class Files extends Program {
203
292
  },
204
293
  });
205
294
  for (const result of results) {
206
- const file = await result.getFile(this);
295
+ const file = await result.getFile(this, properties);
207
296
  if (file) {
208
- return { id: result.id, name: result.name, bytes: file };
297
+ return {
298
+ id: result.id,
299
+ name: result.name,
300
+ bytes: file,
301
+ };
209
302
  }
210
303
  }
211
304
  }
@@ -214,7 +307,7 @@ export let Files = class Files extends Program {
214
307
  * @param name
215
308
  * @returns
216
309
  */
217
- async getByName(name) {
310
+ async getByName(name, properties) {
218
311
  const results = await this.files.index.search(new SearchRequest({
219
312
  query: [new StringMatch({ key: "name", value: name })],
220
313
  }), {
@@ -224,18 +317,47 @@ export let Files = class Files extends Program {
224
317
  },
225
318
  });
226
319
  for (const result of results) {
227
- const file = await result.getFile(this);
320
+ const file = await result.getFile(this, properties);
228
321
  if (file) {
229
- return { id: result.id, name: result.name, bytes: file };
322
+ return {
323
+ id: result.id,
324
+ name: result.name,
325
+ bytes: file,
326
+ };
230
327
  }
231
328
  }
232
329
  }
233
330
  // Setup lifecycle, will be invoked on 'open'
234
331
  async open(args) {
332
+ await this.trustGraph?.open({
333
+ role: args?.role,
334
+ });
235
335
  await this.files.open({
236
336
  type: AbstractFile,
237
337
  // TODO add ACL
238
338
  role: args?.role,
339
+ replicas: { min: 3 },
340
+ canPerform: async (operation, context) => {
341
+ if (!this.trustGraph) {
342
+ return true;
343
+ }
344
+ for (const key of await context.entry.getPublicKeys()) {
345
+ if (await this.trustGraph.isTrusted(key)) {
346
+ return true;
347
+ }
348
+ }
349
+ return false;
350
+ },
351
+ index: {
352
+ fields: (doc) => {
353
+ return {
354
+ id: doc.id,
355
+ name: doc.name,
356
+ size: doc.size,
357
+ parentId: doc.parentId,
358
+ };
359
+ },
360
+ },
239
361
  });
240
362
  }
241
363
  };
@@ -243,12 +365,21 @@ __decorate([
243
365
  field({ type: Uint8Array }),
244
366
  __metadata("design:type", Uint8Array)
245
367
  ], Files.prototype, "id", void 0);
368
+ __decorate([
369
+ field({ type: "string" }),
370
+ __metadata("design:type", String)
371
+ ], Files.prototype, "name", void 0);
372
+ __decorate([
373
+ field({ type: option(TrustedNetwork) }),
374
+ __metadata("design:type", TrustedNetwork)
375
+ ], Files.prototype, "trustGraph", void 0);
246
376
  __decorate([
247
377
  field({ type: Documents }),
248
378
  __metadata("design:type", Documents)
249
379
  ], Files.prototype, "files", void 0);
250
380
  Files = __decorate([
251
381
  variant("files"),
252
- __metadata("design:paramtypes", [Uint8Array])
382
+ __metadata("design:paramtypes", [Object])
253
383
  ], Files);
384
+ export { Files };
254
385
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@peerbit/please-lib",
3
- "version": "0.0.6",
3
+ "version": "0.0.8",
4
4
  "author": "dao.xyz",
5
5
  "repository": "https://github.com/@dao-xyz/peerbit-examples",
6
6
  "license": "Apache-2.0",
@@ -34,13 +34,14 @@
34
34
  "test:integration": "node ../../../node_modules/.bin/jest test -c ../../../jest.config.integration.ts --runInBand --forceExit"
35
35
  },
36
36
  "devDependencies": {
37
- "@peerbit/test-utils": "^1",
38
- "typescript": "^5.1.3"
37
+ "@peerbit/test-utils": "^2",
38
+ "typescript": "^5.3.3"
39
39
  },
40
40
  "dependencies": {
41
- "@peerbit/document": "^3",
42
- "peerbit": "^1",
41
+ "@peerbit/document": "^6",
42
+ "@peerbit/trusted-network": "^3",
43
+ "peerbit": "^4",
43
44
  "uuid": "^9.0.0"
44
45
  },
45
- "gitHead": "61243721632f276a5b6109e147ec375947da9afd"
46
+ "gitHead": "158537c6f6818e35e766329a6b4a5ccf7ae57ea0"
46
47
  }
package/src/index.ts CHANGED
@@ -1,17 +1,41 @@
1
- import { field, variant, vec } from "@dao-xyz/borsh";
1
+ import { field, variant, vec, option } from "@dao-xyz/borsh";
2
2
  import { Program } from "@peerbit/program";
3
- import { Documents, SearchRequest, StringMatch, Role } from "@peerbit/document";
4
- import { sha256Base64Sync, randomBytes } from "@peerbit/crypto";
3
+ import {
4
+ Documents,
5
+ SearchRequest,
6
+ StringMatch,
7
+ StringMatchMethod,
8
+ Or,
9
+ RoleOptions,
10
+ MissingField,
11
+ } from "@peerbit/document";
12
+ import { PublicSignKey, sha256Base64Sync, randomBytes } from "@peerbit/crypto";
5
13
  import { ProgramClient } from "@peerbit/program";
6
14
  import { concat } from "uint8arrays";
15
+ import { sha256Sync } from "@peerbit/crypto";
16
+ import { TrustedNetwork } from "@peerbit/trusted-network";
17
+ import PQueue from "p-queue";
7
18
 
8
- abstract class AbstractFile {
19
+ export abstract class AbstractFile {
9
20
  abstract id: string;
10
21
  abstract name: string;
11
- abstract getFile(files: Files): Promise<Uint8Array | undefined>;
22
+ abstract size: number;
23
+ abstract parentId?: string;
24
+ abstract getFile<
25
+ OutputType extends "chunks" | "joined" = "joined",
26
+ Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array
27
+ >(
28
+ files: Files,
29
+ properties?: {
30
+ as: OutputType;
31
+ timeout?: number;
32
+ progress?: (progress: number) => any;
33
+ }
34
+ ): Promise<Output>;
35
+ abstract delete(files: Files): Promise<void>;
12
36
  }
13
37
 
14
- const TINY_FILE_SIZE_LIMIT = 1e3;
38
+ const TINY_FILE_SIZE_LIMIT = 5 * 1e6; // 6mb
15
39
 
16
40
  @variant(0) // for versioning purposes
17
41
  export class TinyFile extends AbstractFile {
@@ -24,56 +48,48 @@ export class TinyFile extends AbstractFile {
24
48
  @field({ type: Uint8Array })
25
49
  file: Uint8Array; // 10 mb imit
26
50
 
27
- constructor(properties: { name: string; file: Uint8Array }) {
28
- super();
29
- this.id = sha256Base64Sync(properties.file);
30
- this.name = properties.name;
31
- this.file = properties.file;
32
- }
51
+ @field({ type: option("string") })
52
+ parentId?: string;
33
53
 
34
- async getFile(_files: Files) {
35
- if (sha256Base64Sync(this.file) !== this.id) {
36
- throw new Error("Hash does not match the file content");
37
- }
38
- return Promise.resolve(this.file);
54
+ get size() {
55
+ return this.file.byteLength;
39
56
  }
40
- }
41
57
 
42
- const SMALL_FILE_SIZE_LIMIT = 1e6 * 9;
43
-
44
- @variant(1) // for versioning purposes
45
- export class SmallFile extends AbstractFile {
46
- @field({ type: "string" })
47
- id: string; // cid
48
-
49
- @field({ type: "string" })
50
- name: string;
51
-
52
- @field({ type: "string" })
53
- cid: string; // store file separately in a block store, like IPFS
54
-
55
- constructor(properties: { name: string; cid: string }) {
58
+ constructor(properties: {
59
+ id?: string;
60
+ name: string;
61
+ file: Uint8Array;
62
+ parentId?: string;
63
+ }) {
56
64
  super();
57
- this.id = properties.cid;
65
+ this.id = properties.id || sha256Base64Sync(properties.file);
58
66
  this.name = properties.name;
59
- this.cid = properties.cid;
67
+ this.file = properties.file;
68
+ this.parentId = properties.parentId;
60
69
  }
61
70
 
62
- static async create(node: ProgramClient, name: string, file: Uint8Array) {
63
- if (file.length > SMALL_FILE_SIZE_LIMIT) {
64
- throw new Error("To large file for SmallFile");
71
+ async getFile<
72
+ OutputType extends "chunks" | "joined" = "joined",
73
+ Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array
74
+ >(
75
+ _files: Files,
76
+ properties?: { as: OutputType; progress?: (progress: number) => any }
77
+ ): Promise<Output> {
78
+ if (sha256Base64Sync(this.file) !== this.id) {
79
+ throw new Error("Hash does not match the file content");
65
80
  }
66
- const cid = await node.services.blocks.put(file);
67
- return new SmallFile({ name, cid });
81
+ properties?.progress?.(1);
82
+ return Promise.resolve(
83
+ properties?.as == "chunks" ? [this.file] : this.file
84
+ ) as Output;
68
85
  }
69
86
 
70
- async getFile(files: Files) {
71
- // Load the file from the block store
72
- return await files.node.services.blocks.get(this.id);
87
+ async delete(): Promise<void> {
88
+ // Do nothing, since no releated files where created
73
89
  }
74
90
  }
75
91
 
76
- @variant(2) // for versioning purposes
92
+ @variant(1) // for versioning purposes
77
93
  export class LargeFile extends AbstractFile {
78
94
  @field({ type: "string" })
79
95
  id: string; // hash
@@ -84,68 +100,151 @@ export class LargeFile extends AbstractFile {
84
100
  @field({ type: vec("string") })
85
101
  fileIds: string[];
86
102
 
87
- constructor(properties: { id: string; name: string; fileIds: string[] }) {
103
+ @field({ type: "u32" })
104
+ size: number;
105
+
106
+ constructor(properties: {
107
+ id: string;
108
+ name: string;
109
+ fileIds: string[];
110
+ size: number;
111
+ }) {
88
112
  super();
89
113
  this.id = properties.id;
90
114
  this.name = properties.name;
91
115
  this.fileIds = properties.fileIds;
116
+ this.size = properties.size;
92
117
  }
93
118
 
94
- static async create(name: string, file: Uint8Array, files: Files) {
95
- const segmetSize = SMALL_FILE_SIZE_LIMIT / 10; // 10% of the small size limit
119
+ static async create(
120
+ name: string,
121
+ file: Uint8Array,
122
+ files: Files,
123
+ progress?: (progress: number) => void
124
+ ) {
125
+ const segmetSize = TINY_FILE_SIZE_LIMIT / 10; // 10% of the small size limit
96
126
  const fileIds: string[] = [];
97
127
  const id = sha256Base64Sync(file);
98
- for (let i = 0; i < Math.ceil(file.byteLength / segmetSize); i++) {
128
+ const fileSize = file.byteLength;
129
+ progress?.(0);
130
+ const end = Math.ceil(file.byteLength / segmetSize);
131
+ for (let i = 0; i < end; i++) {
132
+ progress?.((i + 1) / end);
99
133
  fileIds.push(
100
- await files.create(
101
- id + "/" + name,
134
+ await files.add(
135
+ name + "/" + i,
102
136
  file.subarray(
103
137
  i * segmetSize,
104
- Math.min((i + 1) * segmetSize, file.length)
105
- )
138
+ Math.min((i + 1) * segmetSize, file.byteLength)
139
+ ),
140
+ id
106
141
  )
107
142
  );
108
143
  }
144
+ progress?.(1);
145
+ return new LargeFile({ id, name, fileIds: fileIds, size: fileSize });
146
+ }
109
147
 
110
- return new LargeFile({ id, name, fileIds });
148
+ get parentId() {
149
+ // Large file can never have a parent
150
+ return undefined;
111
151
  }
112
152
 
113
- async getFile(files: Files) {
114
- // Get all sub files (SmallFiles) and concatinate them in the right order (the order of this.fileIds)
153
+ async fetchChunks(files: Files) {
115
154
  const expectedIds = new Set(this.fileIds);
116
- const chunks: Map<string, Promise<Uint8Array | undefined>> = new Map();
117
-
118
- const results = await files.files.index.search(
155
+ const allFiles = await files.files.index.search(
119
156
  new SearchRequest({
120
157
  query: [
121
- new StringMatch({
122
- key: "name",
123
- value: this.id + "/" + this.name,
124
- }),
158
+ new Or(
159
+ [...expectedIds].map(
160
+ (x) => new StringMatch({ key: "id", value: x })
161
+ )
162
+ ),
125
163
  ],
126
- }),
127
- {
128
- local: true,
129
- remote: true,
130
- }
164
+ })
131
165
  );
166
+ return allFiles;
167
+ }
168
+ async delete(files: Files) {
169
+ await Promise.all(
170
+ (await this.fetchChunks(files)).map((x) => x.delete(files))
171
+ );
172
+ }
173
+
174
+ async getFile<
175
+ OutputType extends "chunks" | "joined" = "joined",
176
+ Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array
177
+ >(
178
+ files: Files,
179
+ properties?: {
180
+ as: OutputType;
181
+ timeout?: number;
182
+ progress?: (progress: number) => any;
183
+ }
184
+ ): Promise<Output> {
185
+ // Get all sub files (SmallFiles) and concatinate them in the right order (the order of this.fileIds)
186
+
187
+ properties?.progress?.(0);
188
+
189
+ console.log("LISTS CHUNKS!");
190
+ const allChunks = await this.fetchChunks(files);
191
+ console.log("RECEIVED CHUNKS: " + allChunks);
192
+ console.log("FETCH CHUNKS");
193
+
194
+ const fetchQueue = new PQueue({ concurrency: 10 });
195
+ let fetchError: Error | undefined = undefined;
196
+ fetchQueue.on("error", (err) => {
197
+ fetchError = err;
198
+ });
132
199
 
133
- if (results.length > 0) {
134
- for (const r of results) {
200
+ const chunks: Map<string, Uint8Array | undefined> = new Map();
201
+ const expectedIds = new Set(this.fileIds);
202
+ if (allChunks.length > 0) {
203
+ let c = 0;
204
+ for (const r of allChunks) {
135
205
  if (chunks.has(r.id)) {
136
206
  // chunk already added;
137
207
  }
138
208
  if (!expectedIds.has(r.id)) {
139
209
  // chunk is not part of this file
140
210
  }
141
-
142
- chunks.set(r.id, r.getFile(files));
211
+ fetchQueue
212
+ .add(async () => {
213
+ let lastError: Error | undefined = undefined;
214
+ for (let i = 0; i < 3; i++) {
215
+ try {
216
+ const chunk = await r.getFile(files, {
217
+ as: "joined",
218
+ timeout: properties?.timeout,
219
+ });
220
+ if (!chunk) {
221
+ throw new Error("Failed to fetch chunk");
222
+ }
223
+ chunks.set(r.id, chunk);
224
+ c++;
225
+ properties?.progress?.(c / allChunks.length);
226
+ return;
227
+ } catch (error: any) {
228
+ // try 3 times
229
+
230
+ lastError = error;
231
+ }
232
+ }
233
+ throw lastError;
234
+ })
235
+ .catch(() => {
236
+ fetchQueue.clear(); // Dont do anything more since we failed to fetch one block
237
+ });
143
238
  }
144
239
  }
240
+ await fetchQueue.onIdle();
145
241
 
146
- if (chunks.size !== expectedIds.size) {
147
- throw new Error("Failed to resolve file");
242
+ if (fetchError || chunks.size !== expectedIds.size) {
243
+ throw new Error(
244
+ `Failed to resolve file. Recieved ${chunks.size}/${expectedIds.size} chunks`
245
+ );
148
246
  }
247
+
149
248
  const chunkContentResolved: Uint8Array[] = await Promise.all(
150
249
  this.fileIds.map(async (x) => {
151
250
  const chunkValue = await chunks.get(x);
@@ -155,50 +254,141 @@ export class LargeFile extends AbstractFile {
155
254
  return chunkValue;
156
255
  })
157
256
  );
158
- return concat(chunkContentResolved);
257
+ console.log("FETCH DONE");
258
+ return (
259
+ properties?.as == "chunks"
260
+ ? chunkContentResolved
261
+ : concat(chunkContentResolved)
262
+ ) as Output;
159
263
  }
160
264
  }
161
265
 
162
- type Args = { role: Role };
266
+ type Args = { role: RoleOptions };
163
267
 
164
268
  @variant("files")
165
269
  export class Files extends Program<Args> {
166
270
  @field({ type: Uint8Array })
167
271
  id: Uint8Array;
168
272
 
273
+ @field({ type: "string" })
274
+ name: string;
275
+
276
+ @field({ type: option(TrustedNetwork) })
277
+ trustGraph?: TrustedNetwork;
278
+
169
279
  @field({ type: Documents })
170
280
  files: Documents<AbstractFile>;
171
281
 
172
- constructor(id: Uint8Array = randomBytes(32)) {
282
+ constructor(
283
+ properties: {
284
+ id?: Uint8Array;
285
+ name?: string;
286
+ rootKey?: PublicSignKey;
287
+ } = {}
288
+ ) {
173
289
  super();
174
- this.id = id;
175
- this.files = new Documents({ id: this.id });
290
+ this.id = properties.id || randomBytes(32);
291
+ this.name = properties.name || "";
292
+ this.trustGraph = properties.rootKey
293
+ ? new TrustedNetwork({ id: this.id, rootTrust: properties.rootKey })
294
+ : undefined;
295
+ this.files = new Documents({
296
+ id: sha256Sync(
297
+ concat([
298
+ this.id,
299
+ new TextEncoder().encode(this.name),
300
+ properties.rootKey?.bytes || new Uint8Array(0),
301
+ ])
302
+ ),
303
+ });
176
304
  }
177
305
 
178
- async create(name: string, file: Uint8Array) {
306
+ async add(
307
+ name: string,
308
+ file: Uint8Array,
309
+ parentId?: string,
310
+ progress?: (progress: number) => void
311
+ ) {
179
312
  let toPut: AbstractFile;
313
+ progress?.(0);
180
314
  if (file.byteLength <= TINY_FILE_SIZE_LIMIT) {
181
- toPut = new TinyFile({ name, file });
182
- } else if (
183
- file.byteLength > TINY_FILE_SIZE_LIMIT &&
184
- file.byteLength <= SMALL_FILE_SIZE_LIMIT
185
- ) {
186
- toPut = await SmallFile.create(this.node, name, file);
315
+ toPut = new TinyFile({ name, file, parentId });
187
316
  } else {
188
- toPut = await LargeFile.create(name, file, this);
317
+ if (parentId) {
318
+ throw new Error("Unexpected that a LargeFile to have a parent");
319
+ }
320
+ toPut = await LargeFile.create(name, file, this, progress);
189
321
  }
190
322
  await this.files.put(toPut);
323
+ progress?.(1);
191
324
  return toPut.id;
192
325
  }
193
326
 
327
+ async removeById(id: string) {
328
+ const file = await this.files.index.get(id);
329
+ if (file) {
330
+ await file.delete(this);
331
+ await this.files.del(file.id);
332
+ }
333
+ }
334
+
335
+ async removeByName(name: string) {
336
+ const files = await this.files.index.search(
337
+ new SearchRequest({
338
+ query: new StringMatch({
339
+ key: ["name"],
340
+ value: name,
341
+ caseInsensitive: false,
342
+ method: StringMatchMethod.exact,
343
+ }),
344
+ })
345
+ );
346
+ for (const file of files) {
347
+ await file.delete(this);
348
+ await this.files.del(file.id);
349
+ }
350
+ }
351
+
352
+ async list() {
353
+ // only root files (don't fetch fetch chunks here)
354
+ const files = await this.files.index.search(
355
+ new SearchRequest({ query: new MissingField({ key: "parentId" }) }),
356
+ {
357
+ local: true,
358
+ remote: {
359
+ throwOnMissing: true,
360
+ sync: true, // sync here because this, because we might want to access it offline, even though we are not replicators
361
+ },
362
+ }
363
+ );
364
+ return files;
365
+ }
366
+
367
+ async listLocalChunks(parent: LargeFile) {
368
+ const files = await this.files.index.search(
369
+ new SearchRequest({
370
+ query: new StringMatch({ key: "parentId", value: parent.id }),
371
+ }),
372
+ {
373
+ local: true,
374
+ remote: false,
375
+ }
376
+ );
377
+ return files;
378
+ }
379
+
194
380
  /**
195
381
  * Get by name
196
382
  * @param id
197
383
  * @returns
198
384
  */
199
- async getById(
200
- id: string
201
- ): Promise<{ id: string; name: string; bytes: Uint8Array } | undefined> {
385
+ async getById<
386
+ OutputType extends "chunks" | "joined" = "joined",
387
+ Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array
388
+ >(
389
+ id: string,
390
+ properties?: { as: OutputType }
391
+ ): Promise<{ id: string; name: string; bytes: Output } | undefined> {
202
392
  const results = await this.files.index.search(
203
393
  new SearchRequest({
204
394
  query: [new StringMatch({ key: "id", value: id })],
@@ -212,9 +402,13 @@ export class Files extends Program<Args> {
212
402
  );
213
403
 
214
404
  for (const result of results) {
215
- const file = await result.getFile(this);
405
+ const file = await result.getFile(this, properties);
216
406
  if (file) {
217
- return { id: result.id, name: result.name, bytes: file };
407
+ return {
408
+ id: result.id,
409
+ name: result.name,
410
+ bytes: file as Output,
411
+ };
218
412
  }
219
413
  }
220
414
  }
@@ -224,9 +418,13 @@ export class Files extends Program<Args> {
224
418
  * @param name
225
419
  * @returns
226
420
  */
227
- async getByName(
228
- name: string
229
- ): Promise<{ id: string; name: string; bytes: Uint8Array } | undefined> {
421
+ async getByName<
422
+ OutputType extends "chunks" | "joined" = "joined",
423
+ Output = OutputType extends "chunks" ? Uint8Array[] : Uint8Array
424
+ >(
425
+ name: string,
426
+ properties?: { as: OutputType }
427
+ ): Promise<{ id: string; name: string; bytes: Output } | undefined> {
230
428
  const results = await this.files.index.search(
231
429
  new SearchRequest({
232
430
  query: [new StringMatch({ key: "name", value: name })],
@@ -240,19 +438,49 @@ export class Files extends Program<Args> {
240
438
  );
241
439
 
242
440
  for (const result of results) {
243
- const file = await result.getFile(this);
441
+ const file = await result.getFile(this, properties);
244
442
  if (file) {
245
- return { id: result.id, name: result.name, bytes: file };
443
+ return {
444
+ id: result.id,
445
+ name: result.name,
446
+ bytes: file as Output,
447
+ };
246
448
  }
247
449
  }
248
450
  }
249
451
 
250
452
  // Setup lifecycle, will be invoked on 'open'
251
453
  async open(args?: Args): Promise<void> {
454
+ await this.trustGraph?.open({
455
+ role: args?.role,
456
+ });
457
+
252
458
  await this.files.open({
253
459
  type: AbstractFile,
254
460
  // TODO add ACL
255
461
  role: args?.role,
462
+ replicas: { min: 3 },
463
+ canPerform: async (operation, context) => {
464
+ if (!this.trustGraph) {
465
+ return true;
466
+ }
467
+ for (const key of await context.entry.getPublicKeys()) {
468
+ if (await this.trustGraph.isTrusted(key)) {
469
+ return true;
470
+ }
471
+ }
472
+ return false;
473
+ },
474
+ index: {
475
+ fields: (doc) => {
476
+ return {
477
+ id: doc.id,
478
+ name: doc.name,
479
+ size: doc.size,
480
+ parentId: doc.parentId,
481
+ };
482
+ },
483
+ },
256
484
  });
257
485
  }
258
486
  }