@ocfl/ocfl 0.4.0 → 1.0.0-beta.2
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/LICENSE +674 -0
- package/README.md +24 -9
- package/dist/constants.d.ts +15 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +14 -0
- package/dist/constants.js.map +1 -0
- package/dist/digest.d.ts +58 -0
- package/dist/digest.d.ts.map +1 -0
- package/dist/digest.js +204 -0
- package/dist/digest.js.map +1 -0
- package/dist/error.d.ts +5 -0
- package/dist/error.d.ts.map +1 -0
- package/dist/error.js +9 -0
- package/dist/error.js.map +1 -0
- package/dist/extension.d.ts +82 -0
- package/dist/extension.d.ts.map +1 -0
- package/dist/extension.js +169 -0
- package/dist/extension.js.map +1 -0
- package/dist/extensions/0002-flat-direct-storage-layout.d.ts +12 -0
- package/dist/extensions/0002-flat-direct-storage-layout.d.ts.map +1 -0
- package/dist/extensions/0002-flat-direct-storage-layout.js +34 -0
- package/dist/extensions/0002-flat-direct-storage-layout.js.map +1 -0
- package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.d.ts +15 -0
- package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.d.ts.map +1 -0
- package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.js +49 -0
- package/dist/extensions/0003-hash-and-id-n-tuple-storage-layout.js.map +1 -0
- package/dist/extensions/0004-hashed-n-tuple-storage-layout.d.ts +17 -0
- package/dist/extensions/0004-hashed-n-tuple-storage-layout.d.ts.map +1 -0
- package/dist/extensions/0004-hashed-n-tuple-storage-layout.js +54 -0
- package/dist/extensions/0004-hashed-n-tuple-storage-layout.js.map +1 -0
- package/dist/extensions/0006-flat-omit-prefix-storage-layout.d.ts +6 -0
- package/dist/extensions/0006-flat-omit-prefix-storage-layout.d.ts.map +1 -0
- package/dist/extensions/0006-flat-omit-prefix-storage-layout.js +8 -0
- package/dist/extensions/0006-flat-omit-prefix-storage-layout.js.map +1 -0
- package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.d.ts +6 -0
- package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.d.ts.map +1 -0
- package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.js +8 -0
- package/dist/extensions/0007-n-tuple-omit-prefix-storage-layout.js.map +1 -0
- package/dist/extensions/0009-digest-algorithms.d.ts +9 -0
- package/dist/extensions/0009-digest-algorithms.d.ts.map +1 -0
- package/dist/extensions/0009-digest-algorithms.js +11 -0
- package/dist/extensions/0009-digest-algorithms.js.map +1 -0
- package/dist/extensions/000N-path-direct-storage-layout.d.ts +16 -0
- package/dist/extensions/000N-path-direct-storage-layout.d.ts.map +1 -0
- package/dist/extensions/000N-path-direct-storage-layout.js +46 -0
- package/dist/extensions/000N-path-direct-storage-layout.js.map +1 -0
- package/dist/extensions/index.d.ts +23 -0
- package/dist/extensions/index.d.ts.map +1 -0
- package/dist/extensions/index.js +8 -0
- package/dist/extensions/index.js.map +1 -0
- package/dist/file.d.ts +87 -0
- package/dist/file.d.ts.map +1 -0
- package/dist/file.js +118 -0
- package/dist/file.js.map +1 -0
- package/dist/index.d.ts +61 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +73 -0
- package/dist/index.js.map +1 -0
- package/dist/inventory.d.ts +155 -0
- package/dist/inventory.d.ts.map +1 -0
- package/dist/inventory.js +591 -0
- package/dist/inventory.js.map +1 -0
- package/dist/object.d.ts +188 -0
- package/dist/object.d.ts.map +1 -0
- package/dist/object.js +425 -0
- package/dist/object.js.map +1 -0
- package/dist/storage.d.ts +94 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +302 -0
- package/dist/storage.js.map +1 -0
- package/dist/store.d.ts +100 -0
- package/dist/store.d.ts.map +1 -0
- package/dist/store.js +157 -0
- package/dist/store.js.map +1 -0
- package/dist/transaction.d.ts +155 -0
- package/dist/transaction.d.ts.map +1 -0
- package/dist/transaction.js +394 -0
- package/dist/transaction.js.map +1 -0
- package/dist/types.d.ts +107 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/utils.d.ts +24 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +85 -0
- package/dist/utils.js.map +1 -0
- package/dist/validation.d.ts +32 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +31 -0
- package/dist/validation.js.map +1 -0
- package/package.json +31 -51
- package/src/constants.ts +16 -0
- package/src/digest.ts +258 -0
- package/src/error.ts +9 -0
- package/src/extension.ts +204 -0
- package/{lib/extensions/0002-flat-direct-storage-layout.js → src/extensions/0002-flat-direct-storage-layout.ts} +15 -22
- package/src/extensions/0003-hash-and-id-n-tuple-storage-layout.ts +56 -0
- package/src/extensions/0004-hashed-n-tuple-storage-layout.ts +59 -0
- package/src/extensions/0006-flat-omit-prefix-storage-layout.ts +9 -0
- package/src/extensions/0007-n-tuple-omit-prefix-storage-layout.ts +9 -0
- package/src/extensions/0009-digest-algorithms.ts +12 -0
- package/src/extensions/000N-path-direct-storage-layout.ts +51 -0
- package/src/extensions/index.ts +24 -0
- package/src/file.ts +161 -0
- package/src/index.ts +92 -0
- package/src/inventory.ts +634 -0
- package/src/object.ts +473 -0
- package/src/storage.ts +342 -0
- package/src/store.ts +199 -0
- package/src/transaction.ts +455 -0
- package/{lib/types.d.ts → src/types.ts} +28 -74
- package/src/utils.ts +94 -0
- package/src/validation.ts +46 -0
- package/index.js +0 -129
- package/index.mjs +0 -18
- package/lib/constants.js +0 -24
- package/lib/digest.js +0 -307
- package/lib/enum.js +0 -90
- package/lib/error.js +0 -19
- package/lib/extension.js +0 -194
- package/lib/extensions/0003-hash-and-id-n-tuple-storage-layout.js +0 -60
- package/lib/extensions/0004-hashed-n-tuple-storage-layout.js +0 -63
- package/lib/extensions/0005-mutable-head.js +0 -0
- package/lib/extensions/0006-flat-omit-prefix-storage-layout.js +0 -7
- package/lib/extensions/0007-n-tuple-omit-prefix-storage-layout.js +0 -7
- package/lib/extensions/0008-schema-registry.js +0 -0
- package/lib/extensions/0009-digest-algorithms.js +0 -18
- package/lib/extensions/000N-path-direct-storage-layout.js +0 -61
- package/lib/extensions/index.js +0 -13
- package/lib/file.js +0 -147
- package/lib/index.js +0 -13
- package/lib/inventory.js +0 -564
- package/lib/object.js +0 -499
- package/lib/storage.js +0 -338
- package/lib/store.js +0 -191
- package/lib/transaction.js +0 -448
- package/lib/utils.js +0 -122
- package/lib/validation.js +0 -174
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store.js","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import type { Writable } from 'node:stream';
|
|
2
|
+
import type { OcflObjectInventoryMut } from './inventory.ts';
|
|
3
|
+
import type { OcflObject } from './object.ts';
|
|
4
|
+
import type { OcflStore, WriteFileData } from './store.ts';
|
|
5
|
+
export interface CommitOptions {
|
|
6
|
+
/** Freeform text used to record the rationale for creating the current version */
|
|
7
|
+
message?: string | undefined;
|
|
8
|
+
/** Identify the user or agent that created the current Version */
|
|
9
|
+
user?: {
|
|
10
|
+
/** Any readable name of the user, e.g., a proper name, user ID, agent ID. */
|
|
11
|
+
name: string;
|
|
12
|
+
/** A URI: either a mailto URI [RFC6068] with the e-mail address of the user or a URL to a personal identifier, e.g., an ORCID iD. */
|
|
13
|
+
address?: string;
|
|
14
|
+
} | undefined;
|
|
15
|
+
/** If true, force to commit. Use it after a purge. */
|
|
16
|
+
force?: boolean | undefined;
|
|
17
|
+
}
|
|
18
|
+
export interface RemoveOptions {
|
|
19
|
+
/** If true, completely remove the content from all versions */
|
|
20
|
+
purge?: boolean | undefined;
|
|
21
|
+
}
|
|
22
|
+
type TrackedPromise<T> = Promise<T> & {
|
|
23
|
+
done?: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* A Transaction represent an atomic update on an OCFL Object.
|
|
27
|
+
* When a transaction is commited, all changes are saved as a new version.
|
|
28
|
+
* This is a wrapper class to hide all the storage specific implementation.
|
|
29
|
+
*/
|
|
30
|
+
declare class OcflObjectTransaction {
|
|
31
|
+
/**
|
|
32
|
+
* Discard all the changes made in this transaction,
|
|
33
|
+
* @abstract
|
|
34
|
+
*/
|
|
35
|
+
rollback(): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Commit all the changes made in this transaction to the actual OCFL Object.
|
|
38
|
+
* @abstract
|
|
39
|
+
* @param options - Commit options. message and user will be included in the version entry of the inventory.json
|
|
40
|
+
*/
|
|
41
|
+
commit(_options?: CommitOptions): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* Completely remove a file path and corresponding content from all versions of an OCFL Object.
|
|
44
|
+
* This is a special case that is not supported as part of regular OCFL versioning operations.
|
|
45
|
+
*/
|
|
46
|
+
purge(logicalPath: string): Promise<void>;
|
|
47
|
+
/**
|
|
48
|
+
* Write data to a file at `logicalPath`
|
|
49
|
+
* @abstract
|
|
50
|
+
* @param logicalPath - A path relative to the object content directory
|
|
51
|
+
* @param data - Data to be written to the file
|
|
52
|
+
* @param options - The same options as https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
|
|
53
|
+
*/
|
|
54
|
+
write(_logicalPath: string, _data: WriteFileData, _options?: object | string): Promise<void>;
|
|
55
|
+
/**
|
|
56
|
+
* Import content by recursively copying a file or directory from local file system to the
|
|
57
|
+
* OCFL Object content. For example, `object.import('/home/john/data/b','data/b')` will
|
|
58
|
+
* copy `/home/john/data/b` from the local filesystem to the content `data/b` in the OFCL Object.
|
|
59
|
+
* Set target to empty string ('') to copy a directory content to the object's content root.
|
|
60
|
+
* If target is not specified, the base name of the source will be used.
|
|
61
|
+
* For examples:
|
|
62
|
+
* To copy '/src/data' directory as 'data' use import('/src/data', 'data').
|
|
63
|
+
* To copy all files inside '/src/data' directory to the logical root, use import('/src/data', '').
|
|
64
|
+
* @abstract
|
|
65
|
+
* @param source - A path to a file or directory in the local filesystem to be copied
|
|
66
|
+
* @param target - A logical path in the OCFL Object content.
|
|
67
|
+
*/
|
|
68
|
+
import(_source: string, _target?: string): Promise<void>;
|
|
69
|
+
/**
|
|
70
|
+
* Duplicate the logical path `source` as a different logical path `target`, both paths will then point
|
|
71
|
+
* to the same content path and bitstreams.
|
|
72
|
+
* @abstract
|
|
73
|
+
* @param source - The logical path to be copied
|
|
74
|
+
* @param target - The target logical path
|
|
75
|
+
*/
|
|
76
|
+
copy(_source: string, _target: string): Promise<void>;
|
|
77
|
+
/**
|
|
78
|
+
* Changes the logical path of existing content. This is similar to move operation in file systems
|
|
79
|
+
* Unless renaming files that are not yet commited, this operation will NOT rename the actual file name referenced by the manifest.
|
|
80
|
+
* @abstract
|
|
81
|
+
*/
|
|
82
|
+
rename(_source: string, _target: string): Promise<void>;
|
|
83
|
+
/**
|
|
84
|
+
* Alias of {@link OcflObjectTransaction.rename}
|
|
85
|
+
*/
|
|
86
|
+
move(source: string, target: string): Promise<void>;
|
|
87
|
+
/**
|
|
88
|
+
* Remove a file or directory
|
|
89
|
+
* @abstract
|
|
90
|
+
* @param logicalPath - A path relative to the object content directory
|
|
91
|
+
*/
|
|
92
|
+
remove(_logicalPath: string, _options?: RemoveOptions): Promise<void>;
|
|
93
|
+
/**
|
|
94
|
+
* Remove a file or directory. Alias of {@link OcflObjectTransaction.remove}
|
|
95
|
+
* @param logicalPath - A path relative to the object content directory
|
|
96
|
+
*/
|
|
97
|
+
delete(logicalPath: string, options?: RemoveOptions): Promise<void>;
|
|
98
|
+
/**
|
|
99
|
+
* Makes content from a version earlier than the previous version available in the current version of an OCFL Object.
|
|
100
|
+
* @abstract
|
|
101
|
+
*/
|
|
102
|
+
reinstate(_logicalPath: string, _versionName: string): Promise<number>;
|
|
103
|
+
/**
|
|
104
|
+
* Create a NodeJS writable stream
|
|
105
|
+
* @abstract
|
|
106
|
+
* @deprecated Use {@link OcflObjectTransaction.createWritable} instead
|
|
107
|
+
*/
|
|
108
|
+
createWriteStream(_logicalPath: string, _options?: unknown): Promise<Writable>;
|
|
109
|
+
/**
|
|
110
|
+
* Create a writable stream
|
|
111
|
+
* @abstract
|
|
112
|
+
*/
|
|
113
|
+
createWritable(_logicalPath: string, _options?: unknown): Promise<WritableStream>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Base class for any transaction implementation on different storage backend
|
|
117
|
+
*/
|
|
118
|
+
declare class OcflObjectTransactionImpl extends OcflObjectTransaction {
|
|
119
|
+
_workspaceVersionPath: string;
|
|
120
|
+
_contentRoot: string;
|
|
121
|
+
_object: OcflObject;
|
|
122
|
+
_store: OcflStore;
|
|
123
|
+
_inventory: OcflObjectInventoryMut;
|
|
124
|
+
_createdDir: string;
|
|
125
|
+
_queue: TrackedPromise<unknown>[];
|
|
126
|
+
_committed: boolean;
|
|
127
|
+
constructor(ocflObject: OcflObject, ocflStore: OcflStore, inventory: OcflObjectInventoryMut, workspaceVersionPath: string, createdDir: string);
|
|
128
|
+
/**
|
|
129
|
+
* Create a new transaction instance.
|
|
130
|
+
*/
|
|
131
|
+
static create(ocflObject: OcflObject, ocflStore: OcflStore, inventory: OcflObjectInventoryMut, workspacePath: string): Promise<OcflObjectTransactionImpl>;
|
|
132
|
+
_getRealPath(logicalPath: string): string;
|
|
133
|
+
rollback(): Promise<void>;
|
|
134
|
+
commit(options?: CommitOptions): Promise<void>;
|
|
135
|
+
_commit(options?: CommitOptions): Promise<void>;
|
|
136
|
+
createWritable(logicalPath: string, options?: unknown): Promise<WritableStream>;
|
|
137
|
+
write(logicalPath: string, data: WriteFileData, options?: object | string): Promise<void>;
|
|
138
|
+
/**
|
|
139
|
+
* Import a single file from source. This is a helper method for {@link OcflObjectTransaction.import | import()} method.
|
|
140
|
+
*/
|
|
141
|
+
importFile(source: string, target: string): Promise<void>;
|
|
142
|
+
import(source: string, target?: string): Promise<void>;
|
|
143
|
+
copy(source: string, target: string): Promise<void>;
|
|
144
|
+
rename(source: string, target: string): Promise<void>;
|
|
145
|
+
reinstate(logicalPath: string, versionName: string): Promise<number>;
|
|
146
|
+
remove(logicalPath: string, options?: RemoveOptions): Promise<void>;
|
|
147
|
+
/**
|
|
148
|
+
* A function wrapper to provide safe mutating operation that
|
|
149
|
+
* will check if a transaction is already committed and track any unfinished promises.
|
|
150
|
+
*/
|
|
151
|
+
_transact<T>(op: () => Promise<T>): Promise<T>;
|
|
152
|
+
private _track;
|
|
153
|
+
}
|
|
154
|
+
export { OcflObjectTransaction, OcflObjectTransactionImpl };
|
|
155
|
+
//# sourceMappingURL=transaction.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
/** Models a set of ocfl object modifying operations as a transaction that is as close as atomic as possible */
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { OcflConstants } from './constants.js';
|
|
4
|
+
import { OcflDigest } from './digest.js';
|
|
5
|
+
import { isErrnoException, parallelize } from './utils.js';
|
|
6
|
+
const { INVENTORY_NAME } = OcflConstants;
|
|
7
|
+
/** Split the digests into the content digest and the remaining fixity digests */
|
|
8
|
+
function splitDigests(digests, algorithm) {
|
|
9
|
+
const { [algorithm]: digest, ...fixity } = digests;
|
|
10
|
+
if (!digest) {
|
|
11
|
+
throw new Error(`Digest "${algorithm}" was not calculated.`);
|
|
12
|
+
}
|
|
13
|
+
return [digest, fixity];
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* A Transaction represent an atomic update on an OCFL Object.
|
|
17
|
+
* When a transaction is commited, all changes are saved as a new version.
|
|
18
|
+
* This is a wrapper class to hide all the storage specific implementation.
|
|
19
|
+
*/
|
|
20
|
+
class OcflObjectTransaction {
|
|
21
|
+
/**
|
|
22
|
+
* Discard all the changes made in this transaction,
|
|
23
|
+
* @abstract
|
|
24
|
+
*/
|
|
25
|
+
async rollback() {
|
|
26
|
+
throw new Error('Not Implemented');
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Commit all the changes made in this transaction to the actual OCFL Object.
|
|
30
|
+
* @abstract
|
|
31
|
+
* @param options - Commit options. message and user will be included in the version entry of the inventory.json
|
|
32
|
+
*/
|
|
33
|
+
async commit(_options) {
|
|
34
|
+
throw new Error('Not Implemented');
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Completely remove a file path and corresponding content from all versions of an OCFL Object.
|
|
38
|
+
* This is a special case that is not supported as part of regular OCFL versioning operations.
|
|
39
|
+
*/
|
|
40
|
+
async purge(logicalPath) {
|
|
41
|
+
return await this.remove(logicalPath, { purge: true });
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Write data to a file at `logicalPath`
|
|
45
|
+
* @abstract
|
|
46
|
+
* @param logicalPath - A path relative to the object content directory
|
|
47
|
+
* @param data - Data to be written to the file
|
|
48
|
+
* @param options - The same options as https://nodejs.org/api/fs.html#fs_fs_writefile_file_data_options_callback
|
|
49
|
+
*/
|
|
50
|
+
async write(_logicalPath, _data, _options) {
|
|
51
|
+
throw new Error('Not Implemented');
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Import content by recursively copying a file or directory from local file system to the
|
|
55
|
+
* OCFL Object content. For example, `object.import('/home/john/data/b','data/b')` will
|
|
56
|
+
* copy `/home/john/data/b` from the local filesystem to the content `data/b` in the OFCL Object.
|
|
57
|
+
* Set target to empty string ('') to copy a directory content to the object's content root.
|
|
58
|
+
* If target is not specified, the base name of the source will be used.
|
|
59
|
+
* For examples:
|
|
60
|
+
* To copy '/src/data' directory as 'data' use import('/src/data', 'data').
|
|
61
|
+
* To copy all files inside '/src/data' directory to the logical root, use import('/src/data', '').
|
|
62
|
+
* @abstract
|
|
63
|
+
* @param source - A path to a file or directory in the local filesystem to be copied
|
|
64
|
+
* @param target - A logical path in the OCFL Object content.
|
|
65
|
+
*/
|
|
66
|
+
async import(_source, _target) {
|
|
67
|
+
throw new Error('Not Implemented');
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Duplicate the logical path `source` as a different logical path `target`, both paths will then point
|
|
71
|
+
* to the same content path and bitstreams.
|
|
72
|
+
* @abstract
|
|
73
|
+
* @param source - The logical path to be copied
|
|
74
|
+
* @param target - The target logical path
|
|
75
|
+
*/
|
|
76
|
+
async copy(_source, _target) {
|
|
77
|
+
throw new Error('Not Implemented');
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Changes the logical path of existing content. This is similar to move operation in file systems
|
|
81
|
+
* Unless renaming files that are not yet commited, this operation will NOT rename the actual file name referenced by the manifest.
|
|
82
|
+
* @abstract
|
|
83
|
+
*/
|
|
84
|
+
async rename(_source, _target) {
|
|
85
|
+
throw new Error('Not Implemented');
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Alias of {@link OcflObjectTransaction.rename}
|
|
89
|
+
*/
|
|
90
|
+
async move(source, target) {
|
|
91
|
+
return this.rename(source, target);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Remove a file or directory
|
|
95
|
+
* @abstract
|
|
96
|
+
* @param logicalPath - A path relative to the object content directory
|
|
97
|
+
*/
|
|
98
|
+
async remove(_logicalPath, _options) {
|
|
99
|
+
throw new Error('Not Implemented');
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Remove a file or directory. Alias of {@link OcflObjectTransaction.remove}
|
|
103
|
+
* @param logicalPath - A path relative to the object content directory
|
|
104
|
+
*/
|
|
105
|
+
async delete(logicalPath, options) {
|
|
106
|
+
return this.remove(logicalPath, options);
|
|
107
|
+
}
|
|
108
|
+
/**
|
|
109
|
+
* Makes content from a version earlier than the previous version available in the current version of an OCFL Object.
|
|
110
|
+
* @abstract
|
|
111
|
+
*/
|
|
112
|
+
async reinstate(_logicalPath, _versionName) {
|
|
113
|
+
throw new Error('Not Implemented');
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Create a NodeJS writable stream
|
|
117
|
+
* @abstract
|
|
118
|
+
* @deprecated Use {@link OcflObjectTransaction.createWritable} instead
|
|
119
|
+
*/
|
|
120
|
+
async createWriteStream(_logicalPath, _options) {
|
|
121
|
+
throw new Error('Not Implemented');
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Create a writable stream
|
|
125
|
+
* @abstract
|
|
126
|
+
*/
|
|
127
|
+
async createWritable(_logicalPath, _options) {
|
|
128
|
+
throw new Error('Not Implemented');
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Base class for any transaction implementation on different storage backend
|
|
133
|
+
*/
|
|
134
|
+
class OcflObjectTransactionImpl extends OcflObjectTransaction {
|
|
135
|
+
_workspaceVersionPath;
|
|
136
|
+
_contentRoot;
|
|
137
|
+
_object;
|
|
138
|
+
_store;
|
|
139
|
+
_inventory;
|
|
140
|
+
_createdDir;
|
|
141
|
+
_queue = [];
|
|
142
|
+
_committed = false;
|
|
143
|
+
constructor(ocflObject, ocflStore, inventory, workspaceVersionPath, createdDir) {
|
|
144
|
+
super();
|
|
145
|
+
this._workspaceVersionPath = workspaceVersionPath;
|
|
146
|
+
this._contentRoot = path.join(workspaceVersionPath, inventory.contentDirectory);
|
|
147
|
+
this._object = ocflObject;
|
|
148
|
+
this._store = ocflStore;
|
|
149
|
+
this._inventory = inventory;
|
|
150
|
+
this._createdDir = createdDir;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Create a new transaction instance.
|
|
154
|
+
*/
|
|
155
|
+
static async create(ocflObject, ocflStore, inventory, workspacePath) {
|
|
156
|
+
const workspaceVersionPath = path.join(workspacePath, inventory.head);
|
|
157
|
+
if (await ocflStore.exists(workspaceVersionPath)) {
|
|
158
|
+
throw new Error('Uncommitted changes detected. Object is being updated by other process or there has been a failed update attempt');
|
|
159
|
+
}
|
|
160
|
+
await ocflStore.mkdir(workspacePath);
|
|
161
|
+
return new OcflObjectTransactionImpl(ocflObject, ocflStore, inventory, workspaceVersionPath, workspacePath);
|
|
162
|
+
}
|
|
163
|
+
_getRealPath(logicalPath) {
|
|
164
|
+
const p = path.normalize(logicalPath);
|
|
165
|
+
if (p.startsWith('/') || p.startsWith('..')) {
|
|
166
|
+
throw new Error('logicalPath must be a relative path without `..`');
|
|
167
|
+
}
|
|
168
|
+
return path.join(this._contentRoot, p);
|
|
169
|
+
}
|
|
170
|
+
async rollback() {
|
|
171
|
+
if (!this._committed) {
|
|
172
|
+
await Promise.all(this._queue);
|
|
173
|
+
if (this._createdDir) {
|
|
174
|
+
await this._store.remove(this._createdDir);
|
|
175
|
+
}
|
|
176
|
+
this._committed = true;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async commit(options) {
|
|
180
|
+
if (!this._committed) {
|
|
181
|
+
const count = this._queue.filter((p) => !p.done).length;
|
|
182
|
+
if (count > 0) {
|
|
183
|
+
await this.rollback();
|
|
184
|
+
throw new Error(`Unfinished operations detected (${count}). Make sure that updater callback is async function and there are no floating promises inside.`);
|
|
185
|
+
}
|
|
186
|
+
// if there is no changes, abort commit
|
|
187
|
+
if (!options?.force && !this._inventory.isChanged) {
|
|
188
|
+
return await this.rollback();
|
|
189
|
+
}
|
|
190
|
+
await this._commit(options);
|
|
191
|
+
this._object._setInventory(this._inventory);
|
|
192
|
+
this._committed = true;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
async _commit(options = {}) {
|
|
196
|
+
const inventory = this._inventory;
|
|
197
|
+
const digestAlgorithm = inventory.digestAlgorithm;
|
|
198
|
+
// set commit info
|
|
199
|
+
inventory.created = new Date().toISOString();
|
|
200
|
+
if (options.message) {
|
|
201
|
+
inventory.message = options.message;
|
|
202
|
+
}
|
|
203
|
+
if (options.user) {
|
|
204
|
+
inventory.user = options.user;
|
|
205
|
+
}
|
|
206
|
+
const workspaceVersionPath = this._workspaceVersionPath;
|
|
207
|
+
const objectVersionPath = path.join(this._object.root, inventory.head);
|
|
208
|
+
/* eg: /workspace/aa/bb/cc/object-1/v1/inventory.json */
|
|
209
|
+
let invPath = path.join(workspaceVersionPath, INVENTORY_NAME);
|
|
210
|
+
/* eg: /workspace/aa/bb/cc/object-1/v1/inventory.json.sha512 */
|
|
211
|
+
let invDigestPath = `${invPath}.${digestAlgorithm}`;
|
|
212
|
+
const inventoryContent = inventory.toString();
|
|
213
|
+
const digest = `${await OcflDigest.digest(digestAlgorithm, inventoryContent)} ${INVENTORY_NAME}`;
|
|
214
|
+
// write inventory.json to workspace
|
|
215
|
+
await this._store.writeFile(invPath, inventoryContent);
|
|
216
|
+
await this._store.writeFile(invDigestPath, digest);
|
|
217
|
+
if (workspaceVersionPath !== objectVersionPath) {
|
|
218
|
+
try {
|
|
219
|
+
await this._object._ensureNamaste();
|
|
220
|
+
await this._store.move(workspaceVersionPath, objectVersionPath);
|
|
221
|
+
await this._store.remove(this._createdDir);
|
|
222
|
+
}
|
|
223
|
+
catch (error) {
|
|
224
|
+
await this.rollback();
|
|
225
|
+
throw error;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// replace root inventory
|
|
229
|
+
/* eg: /data/aa/bb/cc/object-1/inventory.json */
|
|
230
|
+
const rootInvPath = path.join(this._object.root, INVENTORY_NAME);
|
|
231
|
+
/* eg: /data/aa/bb/cc/object-1/v1/inventory.json */
|
|
232
|
+
invPath = path.join(objectVersionPath, INVENTORY_NAME);
|
|
233
|
+
invDigestPath = `${invPath}.${digestAlgorithm}`;
|
|
234
|
+
const rootInvDigestPath = `${rootInvPath}.${digestAlgorithm}`;
|
|
235
|
+
await this._store.copyFile(invPath, `${rootInvPath}.tmp`);
|
|
236
|
+
await Promise.all([this._store.move(`${rootInvPath}.tmp`, rootInvPath), this._store.copyFile(invDigestPath, rootInvDigestPath)]);
|
|
237
|
+
}
|
|
238
|
+
async createWritable(logicalPath, options) {
|
|
239
|
+
if (this._committed) {
|
|
240
|
+
throw new Error('Transaction already commited');
|
|
241
|
+
}
|
|
242
|
+
const digestAlgo = this._inventory.digestAlgorithm;
|
|
243
|
+
const digestAlgos = [digestAlgo, ...(this._object.fixityAlgorithms || [])];
|
|
244
|
+
const hs = await OcflDigest.createStream(digestAlgos);
|
|
245
|
+
const realPath = this._getRealPath(logicalPath);
|
|
246
|
+
const writer = (await this._store.createWritable(realPath, options)).getWriter();
|
|
247
|
+
const inv = this._inventory;
|
|
248
|
+
const store = this._store;
|
|
249
|
+
const ws = new WritableStream({
|
|
250
|
+
write(chunk) {
|
|
251
|
+
hs.update(chunk);
|
|
252
|
+
return writer.write(chunk);
|
|
253
|
+
},
|
|
254
|
+
async close() {
|
|
255
|
+
await writer.close();
|
|
256
|
+
const [digest, fixity] = splitDigests(hs.digest(), digestAlgo);
|
|
257
|
+
if (inv.getContentPath(digest)) {
|
|
258
|
+
await store.remove(realPath);
|
|
259
|
+
}
|
|
260
|
+
inv.add(logicalPath, digest, fixity);
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
this._track(writer.closed);
|
|
264
|
+
return ws;
|
|
265
|
+
}
|
|
266
|
+
async write(logicalPath, data, options) {
|
|
267
|
+
return this._transact(async () => {
|
|
268
|
+
const realPath = this._getRealPath(logicalPath);
|
|
269
|
+
const digestAlgo = this._inventory.digestAlgorithm;
|
|
270
|
+
const digestAlgos = [digestAlgo, ...(this._object.fixityAlgorithms || [])];
|
|
271
|
+
let digest;
|
|
272
|
+
let fixity;
|
|
273
|
+
if (typeof data === 'string' || ArrayBuffer.isView(data)) {
|
|
274
|
+
// if data is not stream, check digest first
|
|
275
|
+
if (ArrayBuffer.isView(data) && !(data instanceof Uint8Array || data instanceof Uint16Array || data instanceof Uint32Array)) {
|
|
276
|
+
data = new Uint8Array(data.buffer);
|
|
277
|
+
}
|
|
278
|
+
const hashes = await OcflDigest.digest(digestAlgos, data);
|
|
279
|
+
[digest, fixity] = splitDigests(hashes, digestAlgo);
|
|
280
|
+
if (!this._inventory.getContentPath(digest)) {
|
|
281
|
+
// no digest yet, write the file to storage backend
|
|
282
|
+
await this._store.writeFile(realPath, data, options);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
else if (data instanceof ReadableStream) {
|
|
286
|
+
// save the stream first
|
|
287
|
+
const hs = await OcflDigest.createStreamThrough(digestAlgos);
|
|
288
|
+
const rs = data.pipeThrough(hs);
|
|
289
|
+
await this._store.writeFile(realPath, rs, options);
|
|
290
|
+
[digest, fixity] = splitDigests(hs.digest(), digestAlgo);
|
|
291
|
+
// already exists, delete temp file
|
|
292
|
+
if (this._inventory.getContentPath(digest)) {
|
|
293
|
+
await this._store.remove(realPath);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
else {
|
|
297
|
+
throw new TypeError(`Unsupported data type: ${Object.prototype.toString.call(data)}`);
|
|
298
|
+
}
|
|
299
|
+
this._inventory.add(logicalPath, digest, fixity);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Import a single file from source. This is a helper method for {@link OcflObjectTransaction.import | import()} method.
|
|
304
|
+
*/
|
|
305
|
+
async importFile(source, target) {
|
|
306
|
+
if (!target) {
|
|
307
|
+
throw new TypeError('Target logical path must not be empty if source is a file.');
|
|
308
|
+
}
|
|
309
|
+
const realPath = this._getRealPath(target);
|
|
310
|
+
const rs = await this._store.createReadable(source);
|
|
311
|
+
const digestAlgo = this._inventory.digestAlgorithm;
|
|
312
|
+
const digestAlgos = [digestAlgo, ...(this._object.fixityAlgorithms || [])];
|
|
313
|
+
const [digest, fixity] = splitDigests(await OcflDigest.digest(digestAlgos, rs), digestAlgo);
|
|
314
|
+
if (!this._inventory.getContentPath(digest)) {
|
|
315
|
+
await this._store.copyFile(source, realPath);
|
|
316
|
+
}
|
|
317
|
+
this._inventory.add(target, digest, fixity);
|
|
318
|
+
}
|
|
319
|
+
async import(source, target) {
|
|
320
|
+
return this._transact(async () => {
|
|
321
|
+
const dest = target ?? path.basename(source);
|
|
322
|
+
const srcStat = await this._store.stat(source);
|
|
323
|
+
if (srcStat.isFile()) {
|
|
324
|
+
await this.importFile(source, dest);
|
|
325
|
+
}
|
|
326
|
+
else if (srcStat.isDirectory()) {
|
|
327
|
+
const files = await this._store.readdir(source);
|
|
328
|
+
await parallelize(files, async (filename) => {
|
|
329
|
+
await this.import(path.join(source, filename), path.join(dest, filename));
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
async copy(source, target) {
|
|
335
|
+
return this._transact(async () => {
|
|
336
|
+
this._inventory.copy(source, target);
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
async rename(source, target) {
|
|
340
|
+
return this._transact(async () => {
|
|
341
|
+
// if file already exists in the workspace, rename the actual file
|
|
342
|
+
try {
|
|
343
|
+
const realSource = this._getRealPath(source);
|
|
344
|
+
const realTarget = this._getRealPath(target);
|
|
345
|
+
await this._store.move(realSource, realTarget);
|
|
346
|
+
}
|
|
347
|
+
catch (error) {
|
|
348
|
+
if (!isErrnoException(error) || error.code !== 'ENOENT') {
|
|
349
|
+
throw error;
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
this._inventory.rename(source, target);
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
async reinstate(logicalPath, versionName) {
|
|
356
|
+
return this._inventory.reinstate(logicalPath, versionName);
|
|
357
|
+
}
|
|
358
|
+
async remove(logicalPath, options) {
|
|
359
|
+
return this._transact(async () => {
|
|
360
|
+
if (options?.purge) {
|
|
361
|
+
// completely remove content from all versions
|
|
362
|
+
let ver = this._inventory.versionNumber.previous();
|
|
363
|
+
while (ver) {
|
|
364
|
+
this._inventory.delete(logicalPath, ver.toString());
|
|
365
|
+
ver = ver.previous();
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (this._inventory.delete(logicalPath)) {
|
|
369
|
+
return this._store.remove(this._getRealPath(logicalPath));
|
|
370
|
+
}
|
|
371
|
+
});
|
|
372
|
+
}
|
|
373
|
+
/**
|
|
374
|
+
* A function wrapper to provide safe mutating operation that
|
|
375
|
+
* will check if a transaction is already committed and track any unfinished promises.
|
|
376
|
+
*/
|
|
377
|
+
async _transact(op) {
|
|
378
|
+
if (this._committed) {
|
|
379
|
+
throw new Error('Transaction already commited');
|
|
380
|
+
}
|
|
381
|
+
return this._track(op());
|
|
382
|
+
}
|
|
383
|
+
_track(p) {
|
|
384
|
+
const markDone = () => {
|
|
385
|
+
p.done = true;
|
|
386
|
+
};
|
|
387
|
+
// then(f, f), not finally(f): finally's derived promise would reject unhandled.
|
|
388
|
+
p.then(markDone, markDone);
|
|
389
|
+
this._queue.push(p);
|
|
390
|
+
return p;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
export { OcflObjectTransaction, OcflObjectTransactionImpl };
|
|
394
|
+
//# sourceMappingURL=transaction.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../src/transaction.ts"],"names":[],"mappings":"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"}
|