UNPKG

3.09 kBPlain TextView Raw
1import FileSystem from './fs/index'
2
3import * as cidLog from './common/cid-log'
4import * as debug from './common/debug'
5import * as dataRoot from './data-root'
6import * as ucan from './ucan/internal'
7
8import { Branch } from './path'
9import { Maybe, authenticatedUsername } from './common/index'
10import { Permissions } from './ucan/permissions'
11
12
13/**
14 * Load a user's file system.
15 *
16 * @param permissions The permissions from initialise.
17 * Pass `null` if working without permissions
18 * @param username Optional, username of the user to load the file system from.
19 * Will try to load the file system of the authenticated user
20 * by default. Throws an error if there's no authenticated user.
21 * @param rootKey Optional, AES key to be the root key of a new filesystem.
22 * Will be used if a filesystem hasn't been created yet.
23 */
24export async function loadFileSystem(
25 permissions: Maybe<Permissions>,
26 username?: string,
27 rootKey?: string
28): Promise<FileSystem> {
29 let cid, fs
30
31 // Look for username
32 username = username || (await authenticatedUsername() || undefined)
33 if (!username) throw new Error("User hasn't authenticated yet")
34
35 // Ensure internal UCAN dictionary
36 await ucan.store([])
37
38 // Determine the correct CID of the file system to load
39 const dataCid = navigator.onLine ? await dataRoot.lookup(username) : null
40 const [ logIdx, logLength ] = dataCid ? await cidLog.index(dataCid) : [ -1, 0 ]
41
42 if (!navigator.onLine) {
43 // Offline, use local CID
44 cid = await cidLog.newest()
45
46 } else if (!dataCid) {
47 // No DNS CID yet
48 cid = await cidLog.newest()
49 if (cid) debug.log("📓 No DNSLink, using local CID:", cid)
50 else debug.log("📓 Creating a new file system")
51
52 } else if (logIdx === 0) {
53 // DNS is up to date
54 cid = dataCid
55 debug.log("📓 DNSLink is up to date:", cid)
56
57 } else if (logIdx > 0) {
58 // DNS is outdated
59 cid = await cidLog.newest()
60 const idxLog = logIdx === 1 ? "1 newer local entry" : logIdx + " newer local entries"
61 debug.log("📓 DNSLink is outdated (" + idxLog + "), using local CID:", cid)
62
63 } else {
64 // DNS is newer
65 cid = dataCid
66 await cidLog.add(cid)
67 debug.log("📓 DNSLink is newer:", cid)
68
69 }
70
71 // If a file system exists, load it and return it
72 const p = permissions || undefined
73
74 fs = cid ? await FileSystem.fromCID(cid, { permissions: p }) : null
75 if (fs) return fs
76
77 // Otherwise make a new one
78 if (!rootKey) throw new Error("Can't make new filesystem without a root AES key")
79 fs = await FileSystem.empty({ permissions: p, rootKey })
80 await addSampleData(fs)
81
82 // Fin
83 return fs
84}
85
86
87
88// ㊙️
89
90
91async function addSampleData(fs: FileSystem): Promise<void> {
92 await fs.mkdir({ directory: [ Branch.Private, "Apps" ] })
93 await fs.mkdir({ directory: [ Branch.Private, "Audio" ] })
94 await fs.mkdir({ directory: [ Branch.Private, "Documents" ] })
95 await fs.mkdir({ directory: [ Branch.Private, "Photos" ] })
96 await fs.mkdir({ directory: [ Branch.Private, "Video" ] })
97 await fs.publish()
98}