@verdant-web/server 1.8.14-next.1 → 1.8.14

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.
Files changed (135) hide show
  1. package/dist/cjs/Baselines.d.ts +15 -15
  2. package/dist/cjs/Baselines.js +83 -83
  3. package/dist/cjs/ClientConnection.d.ts +18 -18
  4. package/dist/cjs/ClientConnection.js +105 -105
  5. package/dist/cjs/MessageSender.d.ts +5 -5
  6. package/dist/cjs/MessageSender.js +2 -2
  7. package/dist/cjs/OperationHistory.d.ts +36 -36
  8. package/dist/cjs/OperationHistory.js +120 -120
  9. package/dist/cjs/Presence.d.ts +15 -15
  10. package/dist/cjs/Presence.js +59 -59
  11. package/dist/cjs/Profiles.d.ts +10 -10
  12. package/dist/cjs/Profiles.js +19 -19
  13. package/dist/cjs/ReplicaKeepaliveTimers.d.ts +17 -17
  14. package/dist/cjs/ReplicaKeepaliveTimers.js +30 -30
  15. package/dist/cjs/Replicas.d.ts +24 -24
  16. package/dist/cjs/Replicas.js +137 -137
  17. package/dist/cjs/Server.d.ts +143 -143
  18. package/dist/cjs/Server.js +396 -396
  19. package/dist/cjs/ServerLibrary.d.ts +77 -77
  20. package/dist/cjs/ServerLibrary.js +487 -487
  21. package/dist/cjs/TokenProvider.d.ts +16 -16
  22. package/dist/cjs/TokenProvider.js +26 -26
  23. package/dist/cjs/TokenVerifier.d.ts +16 -16
  24. package/dist/cjs/TokenVerifier.js +28 -28
  25. package/dist/cjs/files/FileMetadata.d.ts +28 -28
  26. package/dist/cjs/files/FileMetadata.js +46 -46
  27. package/dist/cjs/files/FileStorage.d.ts +35 -35
  28. package/dist/cjs/files/FileStorage.js +71 -71
  29. package/dist/cjs/index.d.ts +9 -9
  30. package/dist/cjs/index.js +11 -11
  31. package/dist/cjs/migrations/v0.d.ts +1 -1
  32. package/dist/cjs/migrations/v0.js +4 -4
  33. package/dist/cjs/migrations/v1.d.ts +1 -1
  34. package/dist/cjs/migrations/v1.js +4 -4
  35. package/dist/cjs/migrations/v2.d.ts +1 -1
  36. package/dist/cjs/migrations/v2.js +5 -5
  37. package/dist/cjs/migrations/v3.d.ts +1 -1
  38. package/dist/cjs/migrations/v3.js +5 -5
  39. package/dist/cjs/migrations/v4.d.ts +1 -1
  40. package/dist/cjs/migrations/v4.js +5 -5
  41. package/dist/cjs/migrations/v5.d.ts +2 -2
  42. package/dist/cjs/migrations/v5.js +26 -26
  43. package/dist/cjs/migrations.d.ts +6 -6
  44. package/dist/cjs/migrations.js +62 -62
  45. package/dist/cjs/migrations.test.d.ts +1 -1
  46. package/dist/cjs/migrations.test.js +110 -110
  47. package/dist/cjs/types.d.ts +22 -22
  48. package/dist/cjs/types.js +2 -2
  49. package/dist/esm/Baselines.d.ts +15 -15
  50. package/dist/esm/Baselines.js +79 -79
  51. package/dist/esm/ClientConnection.d.ts +18 -18
  52. package/dist/esm/ClientConnection.js +101 -101
  53. package/dist/esm/MessageSender.d.ts +5 -5
  54. package/dist/esm/MessageSender.js +1 -1
  55. package/dist/esm/OperationHistory.d.ts +36 -36
  56. package/dist/esm/OperationHistory.js +116 -116
  57. package/dist/esm/Presence.d.ts +15 -15
  58. package/dist/esm/Presence.js +52 -52
  59. package/dist/esm/Profiles.d.ts +10 -10
  60. package/dist/esm/Profiles.js +15 -15
  61. package/dist/esm/ReplicaKeepaliveTimers.d.ts +17 -17
  62. package/dist/esm/ReplicaKeepaliveTimers.js +26 -26
  63. package/dist/esm/Replicas.d.ts +24 -24
  64. package/dist/esm/Replicas.js +133 -133
  65. package/dist/esm/Server.d.ts +143 -143
  66. package/dist/esm/Server.js +389 -389
  67. package/dist/esm/ServerLibrary.d.ts +77 -77
  68. package/dist/esm/ServerLibrary.js +483 -483
  69. package/dist/esm/TokenProvider.d.ts +16 -16
  70. package/dist/esm/TokenProvider.js +19 -19
  71. package/dist/esm/TokenVerifier.d.ts +16 -16
  72. package/dist/esm/TokenVerifier.js +21 -21
  73. package/dist/esm/files/FileMetadata.d.ts +28 -28
  74. package/dist/esm/files/FileMetadata.js +42 -42
  75. package/dist/esm/files/FileStorage.d.ts +35 -35
  76. package/dist/esm/files/FileStorage.js +44 -44
  77. package/dist/esm/index.d.ts +9 -9
  78. package/dist/esm/index.js +4 -4
  79. package/dist/esm/migrations/v0.d.ts +1 -1
  80. package/dist/esm/migrations/v0.js +1 -1
  81. package/dist/esm/migrations/v1.d.ts +1 -1
  82. package/dist/esm/migrations/v1.js +1 -1
  83. package/dist/esm/migrations/v2.d.ts +1 -1
  84. package/dist/esm/migrations/v2.js +2 -2
  85. package/dist/esm/migrations/v3.d.ts +1 -1
  86. package/dist/esm/migrations/v3.js +2 -2
  87. package/dist/esm/migrations/v4.d.ts +1 -1
  88. package/dist/esm/migrations/v4.js +2 -2
  89. package/dist/esm/migrations/v5.d.ts +2 -2
  90. package/dist/esm/migrations/v5.js +22 -22
  91. package/dist/esm/migrations.d.ts +6 -6
  92. package/dist/esm/migrations.js +35 -35
  93. package/dist/esm/migrations.test.d.ts +1 -1
  94. package/dist/esm/migrations.test.js +105 -105
  95. package/dist/esm/types.d.ts +22 -22
  96. package/dist/esm/types.js +1 -1
  97. package/dist/tsconfig-cjs.tsbuildinfo +1 -1
  98. package/dist/tsconfig.tsbuildinfo +1 -1
  99. package/package.json +2 -2
  100. package/dist/cjs/ServerStorage.d.ts +0 -35
  101. package/dist/cjs/ServerStorage.js +0 -60
  102. package/dist/cjs/ServerStorage.js.map +0 -1
  103. package/dist/cjs/migrations/v0.sql.d.ts +0 -2
  104. package/dist/cjs/migrations/v0.sql.js +0 -29
  105. package/dist/cjs/migrations/v0.sql.js.map +0 -1
  106. package/dist/cjs/migrations/v1.sql.d.ts +0 -2
  107. package/dist/cjs/migrations/v1.sql.js +0 -31
  108. package/dist/cjs/migrations/v1.sql.js.map +0 -1
  109. package/dist/cjs/migrations/v2.sql.d.ts +0 -2
  110. package/dist/cjs/migrations/v2.sql.js +0 -28
  111. package/dist/cjs/migrations/v2.sql.js.map +0 -1
  112. package/dist/cjs/migrations/v3.sql.d.ts +0 -2
  113. package/dist/cjs/migrations/v3.sql.js +0 -14
  114. package/dist/cjs/migrations/v3.sql.js.map +0 -1
  115. package/dist/cjs/migrations/v4.sql.d.ts +0 -2
  116. package/dist/cjs/migrations/v4.sql.js +0 -8
  117. package/dist/cjs/migrations/v4.sql.js.map +0 -1
  118. package/dist/esm/ServerStorage.d.ts +0 -44
  119. package/dist/esm/ServerStorage.js +0 -58
  120. package/dist/esm/ServerStorage.js.map +0 -1
  121. package/dist/esm/migrations/v0.sql.d.ts +0 -2
  122. package/dist/esm/migrations/v0.sql.js +0 -27
  123. package/dist/esm/migrations/v0.sql.js.map +0 -1
  124. package/dist/esm/migrations/v1.sql.d.ts +0 -2
  125. package/dist/esm/migrations/v1.sql.js +0 -29
  126. package/dist/esm/migrations/v1.sql.js.map +0 -1
  127. package/dist/esm/migrations/v2.sql.d.ts +0 -2
  128. package/dist/esm/migrations/v2.sql.js +0 -26
  129. package/dist/esm/migrations/v2.sql.js.map +0 -1
  130. package/dist/esm/migrations/v3.sql.d.ts +0 -2
  131. package/dist/esm/migrations/v3.sql.js +0 -12
  132. package/dist/esm/migrations/v3.sql.js.map +0 -1
  133. package/dist/esm/migrations/v4.sql.d.ts +0 -2
  134. package/dist/esm/migrations/v4.sql.js +0 -6
  135. package/dist/esm/migrations/v4.sql.js.map +0 -1
@@ -1,16 +1,16 @@
1
- import { ReplicaType } from '@verdant-web/common';
2
- export declare class TokenProvider {
3
- private config;
4
- constructor(config: {
5
- secret: string;
6
- });
7
- getToken: ({ userId, libraryId, syncEndpoint, role, type, expiresIn, fileEndpoint, }: {
8
- userId: string;
9
- libraryId: string;
10
- syncEndpoint: string;
11
- fileEndpoint?: string | undefined;
12
- role?: string | undefined;
13
- type?: ReplicaType | undefined;
14
- expiresIn?: string | number | undefined;
15
- }) => string;
16
- }
1
+ import { ReplicaType } from '@verdant-web/common';
2
+ export declare class TokenProvider {
3
+ private config;
4
+ constructor(config: {
5
+ secret: string;
6
+ });
7
+ getToken: ({ userId, libraryId, syncEndpoint, role, type, expiresIn, fileEndpoint, }: {
8
+ userId: string;
9
+ libraryId: string;
10
+ syncEndpoint: string;
11
+ fileEndpoint?: string | undefined;
12
+ role?: string | undefined;
13
+ type?: ReplicaType | undefined;
14
+ expiresIn?: string | number | undefined;
15
+ }) => string;
16
+ }
@@ -1,20 +1,20 @@
1
- import { ReplicaType } from '@verdant-web/common';
2
- import jwt from 'jsonwebtoken';
3
- export class TokenProvider {
4
- constructor(config) {
5
- this.config = config;
6
- this.getToken = ({ userId, libraryId, syncEndpoint, role, type = ReplicaType.Realtime, expiresIn = '1d', fileEndpoint, }) => {
7
- return jwt.sign({
8
- sub: userId,
9
- lib: libraryId,
10
- url: syncEndpoint,
11
- file: fileEndpoint,
12
- role,
13
- type,
14
- }, this.config.secret, {
15
- expiresIn,
16
- });
17
- };
18
- }
19
- }
1
+ import { ReplicaType } from '@verdant-web/common';
2
+ import jwt from 'jsonwebtoken';
3
+ export class TokenProvider {
4
+ constructor(config) {
5
+ this.config = config;
6
+ this.getToken = ({ userId, libraryId, syncEndpoint, role, type = ReplicaType.Realtime, expiresIn = '1d', fileEndpoint, }) => {
7
+ return jwt.sign({
8
+ sub: userId,
9
+ lib: libraryId,
10
+ url: syncEndpoint,
11
+ file: fileEndpoint,
12
+ role,
13
+ type,
14
+ }, this.config.secret, {
15
+ expiresIn,
16
+ });
17
+ };
18
+ }
19
+ }
20
20
  //# sourceMappingURL=TokenProvider.js.map
@@ -1,16 +1,16 @@
1
- import { ReplicaType } from '@verdant-web/common';
2
- export declare class TokenVerifier {
3
- private config;
4
- constructor(config: {
5
- secret: string;
6
- });
7
- verifyToken: (token: string) => TokenInfo;
8
- }
9
- export interface TokenInfo {
10
- userId: string;
11
- libraryId: string;
12
- syncEndpoint: string;
13
- role?: string;
14
- type: ReplicaType;
15
- token: string;
16
- }
1
+ import { ReplicaType } from '@verdant-web/common';
2
+ export declare class TokenVerifier {
3
+ private config;
4
+ constructor(config: {
5
+ secret: string;
6
+ });
7
+ verifyToken: (token: string) => TokenInfo;
8
+ }
9
+ export interface TokenInfo {
10
+ userId: string;
11
+ libraryId: string;
12
+ syncEndpoint: string;
13
+ role?: string;
14
+ type: ReplicaType;
15
+ token: string;
16
+ }
@@ -1,22 +1,22 @@
1
- import { assert } from '@verdant-web/common';
2
- import jwt from 'jsonwebtoken';
3
- export class TokenVerifier {
4
- constructor(config) {
5
- this.config = config;
6
- this.verifyToken = (token) => {
7
- const decoded = jwt.verify(token, this.config.secret, {
8
- complete: false,
9
- });
10
- assert(decoded.sub);
11
- return {
12
- userId: decoded.sub,
13
- libraryId: decoded.lib,
14
- syncEndpoint: decoded.url,
15
- role: decoded.role,
16
- type: decoded.type,
17
- token,
18
- };
19
- };
20
- }
21
- }
1
+ import { assert } from '@verdant-web/common';
2
+ import jwt from 'jsonwebtoken';
3
+ export class TokenVerifier {
4
+ constructor(config) {
5
+ this.config = config;
6
+ this.verifyToken = (token) => {
7
+ const decoded = jwt.verify(token, this.config.secret, {
8
+ complete: false,
9
+ });
10
+ assert(decoded.sub);
11
+ return {
12
+ userId: decoded.sub,
13
+ libraryId: decoded.lib,
14
+ syncEndpoint: decoded.url,
15
+ role: decoded.role,
16
+ type: decoded.type,
17
+ token,
18
+ };
19
+ };
20
+ }
21
+ }
22
22
  //# sourceMappingURL=TokenVerifier.js.map
@@ -1,28 +1,28 @@
1
- import { Database } from 'better-sqlite3';
2
- import { FileInfo } from './FileStorage.js';
3
- export interface FileMetadataConfig {
4
- deleteExpirationDays?: number;
5
- }
6
- export declare class FileMetadata {
7
- private db;
8
- private deleteExpirationDays;
9
- constructor(db: Database, { deleteExpirationDays }?: FileMetadataConfig);
10
- get: (libraryId: string, fileId: string) => {
11
- libraryId: string;
12
- fileId: string;
13
- name: string;
14
- type: string;
15
- };
16
- getAll: (libraryId: string) => any[];
17
- deleteAll: (libraryId: string) => import("better-sqlite3").RunResult;
18
- put: (libraryId: string, fileInfo: FileInfo) => import("better-sqlite3").RunResult;
19
- markPendingDelete: (libraryId: string, fileId: string) => import("better-sqlite3").RunResult;
20
- delete: (libraryId: string, fileId: string) => import("better-sqlite3").RunResult;
21
- getPendingDeletes: (libraryId: string) => {
22
- libraryId: string;
23
- fileId: string;
24
- name: string;
25
- type: string;
26
- pendingDeleteAt: number;
27
- }[];
28
- }
1
+ import { Database } from 'better-sqlite3';
2
+ import { FileInfo } from './FileStorage.js';
3
+ export interface FileMetadataConfig {
4
+ deleteExpirationDays?: number;
5
+ }
6
+ export declare class FileMetadata {
7
+ private db;
8
+ private deleteExpirationDays;
9
+ constructor(db: Database, { deleteExpirationDays }?: FileMetadataConfig);
10
+ get: (libraryId: string, fileId: string) => {
11
+ libraryId: string;
12
+ fileId: string;
13
+ name: string;
14
+ type: string;
15
+ };
16
+ getAll: (libraryId: string) => any[];
17
+ deleteAll: (libraryId: string) => import("better-sqlite3").RunResult;
18
+ put: (libraryId: string, fileInfo: FileInfo) => import("better-sqlite3").RunResult;
19
+ markPendingDelete: (libraryId: string, fileId: string) => import("better-sqlite3").RunResult;
20
+ delete: (libraryId: string, fileId: string) => import("better-sqlite3").RunResult;
21
+ getPendingDeletes: (libraryId: string) => {
22
+ libraryId: string;
23
+ fileId: string;
24
+ name: string;
25
+ type: string;
26
+ pendingDeleteAt: number;
27
+ }[];
28
+ }
@@ -1,65 +1,65 @@
1
- export class FileMetadata {
2
- constructor(db, { deleteExpirationDays = 1 } = {}) {
3
- this.db = db;
4
- this.deleteExpirationDays = 1;
5
- this.get = (libraryId, fileId) => {
6
- return this.db
1
+ export class FileMetadata {
2
+ constructor(db, { deleteExpirationDays = 1 } = {}) {
3
+ this.db = db;
4
+ this.deleteExpirationDays = 1;
5
+ this.get = (libraryId, fileId) => {
6
+ return this.db
7
7
  .prepare(`
8
8
  SELECT * FROM FileMetadata
9
9
  WHERE libraryId = ? AND fileId = ?
10
- `)
11
- .get(libraryId, fileId);
12
- };
13
- this.getAll = (libraryId) => {
14
- return this.db
10
+ `)
11
+ .get(libraryId, fileId);
12
+ };
13
+ this.getAll = (libraryId) => {
14
+ return this.db
15
15
  .prepare(`
16
16
  SELECT * FROM FileMetadata
17
17
  WHERE libraryId = ?
18
- `)
19
- .all(libraryId);
20
- };
21
- this.deleteAll = (libraryId) => {
22
- return this.db
18
+ `)
19
+ .all(libraryId);
20
+ };
21
+ this.deleteAll = (libraryId) => {
22
+ return this.db
23
23
  .prepare(`
24
24
  DELETE FROM FileMetadata
25
25
  WHERE libraryId = ?
26
- `)
27
- .run(libraryId);
28
- };
29
- this.put = (libraryId, fileInfo) => {
30
- return this.db
26
+ `)
27
+ .run(libraryId);
28
+ };
29
+ this.put = (libraryId, fileInfo) => {
30
+ return this.db
31
31
  .prepare(`
32
32
  INSERT OR REPLACE INTO FileMetadata (libraryId, fileId, name, type)
33
33
  VALUES (?, ?, ?, ?)
34
- `)
35
- .run(libraryId, fileInfo.id, fileInfo.fileName, fileInfo.type);
36
- };
37
- this.markPendingDelete = (libraryId, fileId) => {
38
- return this.db
34
+ `)
35
+ .run(libraryId, fileInfo.id, fileInfo.fileName, fileInfo.type);
36
+ };
37
+ this.markPendingDelete = (libraryId, fileId) => {
38
+ return this.db
39
39
  .prepare(`
40
40
  UPDATE FileMetadata
41
41
  SET pendingDeleteAt = ?
42
42
  WHERE libraryId = ? AND fileId = ?
43
- `)
44
- .run(Date.now(), libraryId, fileId);
45
- };
46
- this.delete = (libraryId, fileId) => {
47
- return this.db
43
+ `)
44
+ .run(Date.now(), libraryId, fileId);
45
+ };
46
+ this.delete = (libraryId, fileId) => {
47
+ return this.db
48
48
  .prepare(`
49
49
  DELETE FROM FileMetadata
50
50
  WHERE libraryId = ? AND fileId = ?
51
- `)
52
- .run(libraryId, fileId);
53
- };
54
- this.getPendingDeletes = (libraryId) => {
55
- return this.db
51
+ `)
52
+ .run(libraryId, fileId);
53
+ };
54
+ this.getPendingDeletes = (libraryId) => {
55
+ return this.db
56
56
  .prepare(`
57
57
  SELECT * FROM FileMetadata
58
58
  WHERE libraryId = ? AND pendingDeleteAt < ?
59
- `)
60
- .all(libraryId, Date.now() - 1000 * 60 * 60 * 24 * this.deleteExpirationDays);
61
- };
62
- this.deleteExpirationDays = deleteExpirationDays;
63
- }
64
- }
59
+ `)
60
+ .all(libraryId, Date.now() - 1000 * 60 * 60 * 24 * this.deleteExpirationDays);
61
+ };
62
+ this.deleteExpirationDays = deleteExpirationDays;
63
+ }
64
+ }
65
65
  //# sourceMappingURL=FileMetadata.js.map
@@ -1,35 +1,35 @@
1
- /// <reference types="node" resolution-mode="require"/>
2
- import { Readable } from 'stream';
3
- export interface FileInfo {
4
- fileName: string;
5
- id: string;
6
- libraryId: string;
7
- type: string;
8
- }
9
- /**
10
- * The interface for implementing a file storage backend.
11
- * verdant will supply file Blobs and metadata, and the storage backend
12
- * must store them somewhere.
13
- *
14
- * The storage backend must also provide a way to get a URL for the file,
15
- * even if the file is not yet uploaded, based on its metadata.
16
- */
17
- export interface FileStorage {
18
- put(fileStream: Readable, data: FileInfo): Promise<void>;
19
- getUrl(data: FileInfo): string | Promise<string>;
20
- delete(data: FileInfo): Promise<void>;
21
- }
22
- export declare class LocalFileStorage implements FileStorage {
23
- private readonly host;
24
- private readonly rootDirectory;
25
- constructor({ rootDirectory, host, }: {
26
- rootDirectory: string;
27
- host: string;
28
- });
29
- private prepareHost;
30
- put(fileStream: Readable, data: FileInfo): Promise<void>;
31
- getUrl(data: FileInfo): string;
32
- delete(data: FileInfo): Promise<void>;
33
- private getPath;
34
- private getStorageLocation;
35
- }
1
+ /// <reference types="node" resolution-mode="require"/>
2
+ import { Readable } from 'stream';
3
+ export interface FileInfo {
4
+ fileName: string;
5
+ id: string;
6
+ libraryId: string;
7
+ type: string;
8
+ }
9
+ /**
10
+ * The interface for implementing a file storage backend.
11
+ * verdant will supply file Blobs and metadata, and the storage backend
12
+ * must store them somewhere.
13
+ *
14
+ * The storage backend must also provide a way to get a URL for the file,
15
+ * even if the file is not yet uploaded, based on its metadata.
16
+ */
17
+ export interface FileStorage {
18
+ put(fileStream: Readable, data: FileInfo): Promise<void>;
19
+ getUrl(data: FileInfo): string | Promise<string>;
20
+ delete(data: FileInfo): Promise<void>;
21
+ }
22
+ export declare class LocalFileStorage implements FileStorage {
23
+ private readonly host;
24
+ private readonly rootDirectory;
25
+ constructor({ rootDirectory, host, }: {
26
+ rootDirectory: string;
27
+ host: string;
28
+ });
29
+ private prepareHost;
30
+ put(fileStream: Readable, data: FileInfo): Promise<void>;
31
+ getUrl(data: FileInfo): string;
32
+ delete(data: FileInfo): Promise<void>;
33
+ private getPath;
34
+ private getStorageLocation;
35
+ }
@@ -1,45 +1,45 @@
1
- import * as fs from 'fs';
2
- import * as path from 'path';
3
- export class LocalFileStorage {
4
- constructor({ rootDirectory, host, }) {
5
- this.prepareHost = (host) => {
6
- if (host.endsWith('/')) {
7
- return host.slice(0, -1);
8
- }
9
- return host;
10
- };
11
- this.host = this.prepareHost(host);
12
- this.rootDirectory = rootDirectory;
13
- }
14
- async put(fileStream, data) {
15
- const filePath = this.getPath(data);
16
- const containingDirectory = path.dirname(path.join(this.rootDirectory, filePath));
17
- await fs.promises.mkdir(containingDirectory, {
18
- recursive: true,
19
- });
20
- const dest = fs.createWriteStream(this.getStorageLocation(data));
21
- fileStream.pipe(dest);
22
- }
23
- getUrl(data) {
24
- return `${this.host}/${this.getPath(data)}`;
25
- }
26
- async delete(data) {
27
- await fs.promises.unlink(this.getStorageLocation(data));
28
- const containingDirectory = path.dirname(path.join(this.rootDirectory, this.getPath(data)));
29
- // delete the containing folder if it's empty
30
- try {
31
- await fs.promises.rmdir(containingDirectory);
32
- }
33
- catch (e) {
34
- // ignore
35
- }
36
- }
37
- getPath(data) {
38
- // retain the file extension
39
- return `${data.libraryId}/${data.id}/${data.fileName}`;
40
- }
41
- getStorageLocation(data) {
42
- return path.join(this.rootDirectory, this.getPath(data));
43
- }
44
- }
1
+ import * as fs from 'fs';
2
+ import * as path from 'path';
3
+ export class LocalFileStorage {
4
+ constructor({ rootDirectory, host, }) {
5
+ this.prepareHost = (host) => {
6
+ if (host.endsWith('/')) {
7
+ return host.slice(0, -1);
8
+ }
9
+ return host;
10
+ };
11
+ this.host = this.prepareHost(host);
12
+ this.rootDirectory = rootDirectory;
13
+ }
14
+ async put(fileStream, data) {
15
+ const filePath = this.getPath(data);
16
+ const containingDirectory = path.dirname(path.join(this.rootDirectory, filePath));
17
+ await fs.promises.mkdir(containingDirectory, {
18
+ recursive: true,
19
+ });
20
+ const dest = fs.createWriteStream(this.getStorageLocation(data));
21
+ fileStream.pipe(dest);
22
+ }
23
+ getUrl(data) {
24
+ return `${this.host}/${this.getPath(data)}`;
25
+ }
26
+ async delete(data) {
27
+ await fs.promises.unlink(this.getStorageLocation(data));
28
+ const containingDirectory = path.dirname(path.join(this.rootDirectory, this.getPath(data)));
29
+ // delete the containing folder if it's empty
30
+ try {
31
+ await fs.promises.rmdir(containingDirectory);
32
+ }
33
+ catch (e) {
34
+ // ignore
35
+ }
36
+ }
37
+ getPath(data) {
38
+ // retain the file extension
39
+ return `${data.libraryId}/${data.id}/${data.fileName}`;
40
+ }
41
+ getStorageLocation(data) {
42
+ return path.join(this.rootDirectory, this.getPath(data));
43
+ }
44
+ }
45
45
  //# sourceMappingURL=FileStorage.js.map
@@ -1,9 +1,9 @@
1
- export type { MessageSender } from './MessageSender.js';
2
- export type { UserProfiles } from './Profiles.js';
3
- export type { ClientMessage, ServerMessage } from '@verdant-web/common';
4
- export { ReplicaType } from '@verdant-web/common';
5
- export { Server } from './Server.js';
6
- export { TokenProvider } from './TokenProvider.js';
7
- export { LocalFileStorage } from './files/FileStorage.js';
8
- export type { FileStorage, FileInfo } from './files/FileStorage.js';
9
- export type { TokenInfo } from './TokenVerifier.js';
1
+ export type { MessageSender } from './MessageSender.js';
2
+ export type { UserProfiles } from './Profiles.js';
3
+ export type { ClientMessage, ServerMessage } from '@verdant-web/common';
4
+ export { ReplicaType } from '@verdant-web/common';
5
+ export { Server } from './Server.js';
6
+ export { TokenProvider } from './TokenProvider.js';
7
+ export { LocalFileStorage } from './files/FileStorage.js';
8
+ export type { FileStorage, FileInfo } from './files/FileStorage.js';
9
+ export type { TokenInfo } from './TokenVerifier.js';
package/dist/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
- export { ReplicaType } from '@verdant-web/common';
2
- export { Server } from './Server.js';
3
- export { TokenProvider } from './TokenProvider.js';
4
- export { LocalFileStorage } from './files/FileStorage.js';
1
+ export { ReplicaType } from '@verdant-web/common';
2
+ export { Server } from './Server.js';
3
+ export { TokenProvider } from './TokenProvider.js';
4
+ export { LocalFileStorage } from './files/FileStorage.js';
5
5
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- export declare const sql = "\nCREATE TABLE IF NOT EXISTS ReplicaInfo (\n id TEXT PRIMARY KEY NOT NULL,\n libraryId TEXT NOT NULL,\n clientId TEXT NOT NULL,\n lastSeenWallClockTime INTEGER,\n ackedLogicalTime TEXT,\n type INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS OperationHistory (\n libraryId TEXT NOT NULL,\n replicaId TEXT NOT NULL,\n oid TEXT NOT NULL,\n data TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n PRIMARY KEY (libraryId, replicaId, oid, timestamp)\n);\n\nCREATE TABLE IF NOT EXISTS DocumentBaseline (\n oid TEXT PRIMARY KEY NOT NULL,\n snapshot TEXT,\n timestamp TEXT NOT NULL,\n libraryId TEXT NOT NULL\n);\n";
1
+ export declare const sql = "\nCREATE TABLE IF NOT EXISTS ReplicaInfo (\n id TEXT PRIMARY KEY NOT NULL,\n libraryId TEXT NOT NULL,\n clientId TEXT NOT NULL,\n lastSeenWallClockTime INTEGER,\n ackedLogicalTime TEXT,\n type INTEGER NOT NULL DEFAULT 0\n);\n\nCREATE TABLE IF NOT EXISTS OperationHistory (\n libraryId TEXT NOT NULL,\n replicaId TEXT NOT NULL,\n oid TEXT NOT NULL,\n data TEXT NOT NULL,\n timestamp INTEGER NOT NULL,\n PRIMARY KEY (libraryId, replicaId, oid, timestamp)\n);\n\nCREATE TABLE IF NOT EXISTS DocumentBaseline (\n oid TEXT PRIMARY KEY NOT NULL,\n snapshot TEXT,\n timestamp TEXT NOT NULL,\n libraryId TEXT NOT NULL\n);\n";
@@ -23,5 +23,5 @@ CREATE TABLE IF NOT EXISTS DocumentBaseline (
23
23
  timestamp TEXT NOT NULL,
24
24
  libraryId TEXT NOT NULL
25
25
  );
26
- `;
26
+ `;
27
27
  //# sourceMappingURL=v0.js.map
@@ -1 +1 @@
1
- export declare const sql = "\nALTER TABLE\n ReplicaInfo RENAME TO ReplicaInfoOld;\n\nCREATE TABLE ReplicaInfo (\n id TEXT NOT NULL,\n libraryId TEXT NOT NULL,\n clientId TEXT NOT NULL,\n lastSeenWallClockTime INTEGER,\n ackedLogicalTime TEXT,\n type INTEGER NOT NULL DEFAULT 0,\n PRIMARY KEY (id, libraryId)\n);\n\nINSERT INTO\n ReplicaInfo\nSELECT\n id,\n libraryId,\n clientId,\n lastSeenWallClockTime,\n ackedLogicalTime,\n type\nFROM\n ReplicaInfoOld;\n\nDROP TABLE ReplicaInfoOld;\n";
1
+ export declare const sql = "\nALTER TABLE\n ReplicaInfo RENAME TO ReplicaInfoOld;\n\nCREATE TABLE ReplicaInfo (\n id TEXT NOT NULL,\n libraryId TEXT NOT NULL,\n clientId TEXT NOT NULL,\n lastSeenWallClockTime INTEGER,\n ackedLogicalTime TEXT,\n type INTEGER NOT NULL DEFAULT 0,\n PRIMARY KEY (id, libraryId)\n);\n\nINSERT INTO\n ReplicaInfo\nSELECT\n id,\n libraryId,\n clientId,\n lastSeenWallClockTime,\n ackedLogicalTime,\n type\nFROM\n ReplicaInfoOld;\n\nDROP TABLE ReplicaInfoOld;\n";
@@ -25,5 +25,5 @@ FROM
25
25
  ReplicaInfoOld;
26
26
 
27
27
  DROP TABLE ReplicaInfoOld;
28
- `;
28
+ `;
29
29
  //# sourceMappingURL=v1.js.map
@@ -1 +1 @@
1
- export declare const sql = "\n ALTER TABLE\n DocumentBaseline RENAME TO DocumentBaselineOld;\n\n CREATE TABLE DocumentBaseline (\n oid TEXT NOT NULL,\n snapshot TEXT,\n timestamp TEXT NOT NULL,\n libraryId TEXT NOT NULL,\n PRIMARY KEY (libraryId, oid)\n );\n\n INSERT INTO\n DocumentBaseline\n SELECT\n oid,\n snapshot,\n timestamp,\n libraryId\n FROM\n DocumentBaselineOld;\n\n DROP TABLE DocumentBaselineOld;\n";
1
+ export declare const sql = "\n ALTER TABLE\n DocumentBaseline RENAME TO DocumentBaselineOld;\n\n CREATE TABLE DocumentBaseline (\n oid TEXT NOT NULL,\n snapshot TEXT,\n timestamp TEXT NOT NULL,\n libraryId TEXT NOT NULL,\n PRIMARY KEY (libraryId, oid)\n );\n\n INSERT INTO\n DocumentBaseline\n SELECT\n oid,\n snapshot,\n timestamp,\n libraryId\n FROM\n DocumentBaselineOld;\n\n DROP TABLE DocumentBaselineOld;\n";
@@ -1,4 +1,4 @@
1
- // fixes primary key for document baselines to include libraryId
1
+ // fixes primary key for document baselines to include libraryId
2
2
  export const sql = `
3
3
  ALTER TABLE
4
4
  DocumentBaseline RENAME TO DocumentBaselineOld;
@@ -22,5 +22,5 @@ export const sql = `
22
22
  DocumentBaselineOld;
23
23
 
24
24
  DROP TABLE DocumentBaselineOld;
25
- `;
25
+ `;
26
26
  //# sourceMappingURL=v2.js.map
@@ -1 +1 @@
1
- export declare const sql = "\n CREATE TABLE IF NOT EXISTS FileMetadata (\n libraryId TEXT NOT NULL,\n fileId TEXT NOT NULL,\n name TEXT NOT NULL,\n type TEXT NOT NULL,\n pendingDeleteAt INTEGER,\n PRIMARY KEY (libraryId, fileId)\n );\n";
1
+ export declare const sql = "\n CREATE TABLE IF NOT EXISTS FileMetadata (\n libraryId TEXT NOT NULL,\n fileId TEXT NOT NULL,\n name TEXT NOT NULL,\n type TEXT NOT NULL,\n pendingDeleteAt INTEGER,\n PRIMARY KEY (libraryId, fileId)\n );\n";
@@ -1,4 +1,4 @@
1
- // add the FileMetadata table
1
+ // add the FileMetadata table
2
2
  export const sql = `
3
3
  CREATE TABLE IF NOT EXISTS FileMetadata (
4
4
  libraryId TEXT NOT NULL,
@@ -8,5 +8,5 @@ export const sql = `
8
8
  pendingDeleteAt INTEGER,
9
9
  PRIMARY KEY (libraryId, fileId)
10
10
  );
11
- `;
11
+ `;
12
12
  //# sourceMappingURL=v3.js.map
@@ -1 +1 @@
1
- export declare const sql = "\n ALTER TABLE ReplicaInfo ADD COLUMN ackedServerOrder INTEGER DEFAULT 0 NOT NULL;\n ALTER TABLE OperationHistory ADD COLUMN serverOrder INTEGER DEFAULT 0 NOT NULL;\n";
1
+ export declare const sql = "\n ALTER TABLE ReplicaInfo ADD COLUMN ackedServerOrder INTEGER DEFAULT 0 NOT NULL;\n ALTER TABLE OperationHistory ADD COLUMN serverOrder INTEGER DEFAULT 0 NOT NULL;\n";
@@ -1,6 +1,6 @@
1
- // add server order to replicas and operations
1
+ // add server order to replicas and operations
2
2
  export const sql = `
3
3
  ALTER TABLE ReplicaInfo ADD COLUMN ackedServerOrder INTEGER DEFAULT 0 NOT NULL;
4
4
  ALTER TABLE OperationHistory ADD COLUMN serverOrder INTEGER DEFAULT 0 NOT NULL;
5
- `;
5
+ `;
6
6
  //# sourceMappingURL=v4.js.map
@@ -1,2 +1,2 @@
1
- import SQL from 'better-sqlite3';
2
- export declare const procedure: (db: SQL.Database) => void;
1
+ import SQL from 'better-sqlite3';
2
+ export declare const procedure: (db: SQL.Database) => void;
@@ -1,33 +1,33 @@
1
- import { convertLegacyOid, replaceLegacyOidsInJsonString, } from '@verdant-web/common';
2
- // read all operations and write them back without legacy IDs.
3
- export const procedure = (db) => {
4
- const operations = db
5
- .prepare(/* sql */ `SELECT * from OperationHistory;`)
6
- .all();
7
- for (const op of operations) {
8
- db.prepare(
1
+ import { convertLegacyOid, replaceLegacyOidsInJsonString, } from '@verdant-web/common';
2
+ // read all operations and write them back without legacy IDs.
3
+ export const procedure = (db) => {
4
+ const operations = db
5
+ .prepare(/* sql */ `SELECT * from OperationHistory;`)
6
+ .all();
7
+ for (const op of operations) {
8
+ db.prepare(
9
9
  /* sql */ `
10
10
  UPDATE OperationHistory
11
11
  SET oid = ?,
12
12
  data = ?
13
13
  WHERE oid = ? AND timestamp = ? AND libraryId = ?;
14
- `).run(convertLegacyOid(op.oid),
15
- // data is already a string, so just leave it and do the conversion on the string
16
- op.data ? replaceLegacyOidsInJsonString(op.data) : op.data, op.oid, op.timestamp, op.libraryId);
17
- }
18
- const baselines = db
19
- .prepare(/* sql */ `SELECT * from DocumentBaseline;`)
20
- .all();
21
- for (const baseline of baselines) {
22
- db.prepare(
14
+ `).run(convertLegacyOid(op.oid),
15
+ // data is already a string, so just leave it and do the conversion on the string
16
+ op.data ? replaceLegacyOidsInJsonString(op.data) : op.data, op.oid, op.timestamp, op.libraryId);
17
+ }
18
+ const baselines = db
19
+ .prepare(/* sql */ `SELECT * from DocumentBaseline;`)
20
+ .all();
21
+ for (const baseline of baselines) {
22
+ db.prepare(
23
23
  /* sql */ `
24
24
  UPDATE DocumentBaseline
25
25
  SET oid = ?,
26
26
  snapshot = ?
27
27
  WHERE oid = ? AND libraryId = ?;
28
- `).run(convertLegacyOid(baseline.oid), baseline.snapshot
29
- ? replaceLegacyOidsInJsonString(baseline.snapshot)
30
- : baseline.snapshot, baseline.oid, baseline.libraryId);
31
- }
32
- };
28
+ `).run(convertLegacyOid(baseline.oid), baseline.snapshot
29
+ ? replaceLegacyOidsInJsonString(baseline.snapshot)
30
+ : baseline.snapshot, baseline.oid, baseline.libraryId);
31
+ }
32
+ };
33
33
  //# sourceMappingURL=v5.js.map