@zenfs/core 1.11.4 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. package/dist/backends/backend.d.ts +19 -15
  2. package/dist/backends/backend.js +36 -19
  3. package/dist/backends/cow.d.ts +20 -30
  4. package/dist/backends/cow.js +83 -192
  5. package/dist/backends/fetch.d.ts +1 -0
  6. package/dist/backends/fetch.js +30 -30
  7. package/dist/backends/index.d.ts +1 -1
  8. package/dist/backends/index.js +1 -1
  9. package/dist/backends/memory.d.ts +5 -7
  10. package/dist/backends/memory.js +2 -3
  11. package/dist/backends/passthrough.d.ts +19 -23
  12. package/dist/backends/passthrough.js +98 -288
  13. package/dist/backends/port.d.ts +220 -0
  14. package/dist/backends/port.js +328 -0
  15. package/dist/backends/single_buffer.d.ts +59 -47
  16. package/dist/backends/single_buffer.js +468 -219
  17. package/dist/backends/store/fs.d.ts +25 -35
  18. package/dist/backends/store/fs.js +276 -315
  19. package/dist/backends/store/store.d.ts +10 -15
  20. package/dist/backends/store/store.js +11 -10
  21. package/dist/config.d.ts +3 -12
  22. package/dist/config.js +17 -19
  23. package/dist/context.d.ts +8 -21
  24. package/dist/context.js +33 -10
  25. package/dist/index.d.ts +2 -1
  26. package/dist/index.js +2 -1
  27. package/dist/internal/contexts.d.ts +63 -0
  28. package/dist/internal/contexts.js +15 -0
  29. package/dist/internal/credentials.d.ts +2 -11
  30. package/dist/internal/credentials.js +0 -19
  31. package/dist/internal/devices.d.ts +18 -80
  32. package/dist/internal/devices.js +103 -316
  33. package/dist/internal/error.d.ts +9 -204
  34. package/dist/internal/error.js +19 -288
  35. package/dist/internal/file_index.d.ts +1 -1
  36. package/dist/internal/file_index.js +11 -11
  37. package/dist/internal/filesystem.d.ts +51 -94
  38. package/dist/internal/filesystem.js +21 -20
  39. package/dist/internal/index.d.ts +1 -2
  40. package/dist/internal/index.js +1 -2
  41. package/dist/internal/index_fs.d.ts +12 -30
  42. package/dist/internal/index_fs.js +37 -69
  43. package/dist/internal/inode.d.ts +140 -24
  44. package/dist/internal/inode.js +515 -66
  45. package/dist/mixins/async.js +52 -112
  46. package/dist/mixins/mutexed.d.ts +19 -18
  47. package/dist/mixins/mutexed.js +62 -64
  48. package/dist/mixins/readonly.d.ts +7 -6
  49. package/dist/mixins/readonly.js +24 -18
  50. package/dist/mixins/sync.js +8 -8
  51. package/dist/{vfs/path.d.ts → path.d.ts} +3 -4
  52. package/dist/{vfs/path.js → path.js} +6 -9
  53. package/dist/polyfills.js +1 -1
  54. package/dist/readline.d.ts +134 -0
  55. package/dist/readline.js +623 -0
  56. package/dist/utils.d.ts +9 -37
  57. package/dist/utils.js +17 -85
  58. package/dist/vfs/acl.d.ts +42 -0
  59. package/dist/vfs/acl.js +268 -0
  60. package/dist/vfs/async.d.ts +9 -23
  61. package/dist/vfs/async.js +25 -27
  62. package/dist/vfs/config.d.ts +6 -18
  63. package/dist/vfs/config.js +8 -18
  64. package/dist/vfs/dir.d.ts +3 -3
  65. package/dist/vfs/dir.js +12 -12
  66. package/dist/vfs/file.d.ts +106 -0
  67. package/dist/vfs/file.js +244 -0
  68. package/dist/vfs/flags.d.ts +19 -0
  69. package/dist/vfs/flags.js +62 -0
  70. package/dist/vfs/index.d.ts +4 -10
  71. package/dist/vfs/index.js +4 -13
  72. package/dist/vfs/ioctl.d.ts +88 -0
  73. package/dist/vfs/ioctl.js +409 -0
  74. package/dist/vfs/promises.d.ts +81 -19
  75. package/dist/vfs/promises.js +404 -288
  76. package/dist/vfs/shared.d.ts +7 -37
  77. package/dist/vfs/shared.js +29 -85
  78. package/dist/{stats.d.ts → vfs/stats.d.ts} +14 -28
  79. package/dist/{stats.js → vfs/stats.js} +11 -66
  80. package/dist/vfs/streams.d.ts +1 -0
  81. package/dist/vfs/streams.js +32 -27
  82. package/dist/vfs/sync.d.ts +3 -3
  83. package/dist/vfs/sync.js +263 -260
  84. package/dist/vfs/watchers.d.ts +2 -2
  85. package/dist/vfs/watchers.js +12 -12
  86. package/dist/vfs/xattr.d.ts +116 -0
  87. package/dist/vfs/xattr.js +201 -0
  88. package/package.json +5 -3
  89. package/readme.md +1 -1
  90. package/scripts/test.js +2 -2
  91. package/tests/assignment.ts +1 -1
  92. package/tests/backend/config.worker.js +4 -1
  93. package/tests/backend/fetch.test.ts +3 -0
  94. package/tests/backend/port.test.ts +19 -33
  95. package/tests/backend/remote.worker.js +4 -1
  96. package/tests/backend/single-buffer.test.ts +53 -0
  97. package/tests/backend/single-buffer.worker.js +30 -0
  98. package/tests/common/context.test.ts +3 -3
  99. package/tests/common/handle.test.ts +17 -12
  100. package/tests/common/mutex.test.ts +9 -9
  101. package/tests/common/path.test.ts +1 -1
  102. package/tests/common/readline.test.ts +104 -0
  103. package/tests/common.ts +4 -19
  104. package/tests/fetch/fetch.ts +2 -2
  105. package/tests/fs/append.test.ts +4 -4
  106. package/tests/fs/directory.test.ts +25 -25
  107. package/tests/fs/errors.test.ts +15 -19
  108. package/tests/fs/links.test.ts +4 -3
  109. package/tests/fs/open.test.ts +4 -21
  110. package/tests/fs/permissions.test.ts +14 -18
  111. package/tests/fs/read.test.ts +10 -9
  112. package/tests/fs/readFile.test.ts +10 -26
  113. package/tests/fs/rename.test.ts +4 -9
  114. package/tests/fs/stat.test.ts +8 -8
  115. package/tests/fs/streams.test.ts +2 -11
  116. package/tests/fs/times.test.ts +7 -7
  117. package/tests/fs/truncate.test.ts +8 -36
  118. package/tests/fs/watch.test.ts +10 -10
  119. package/tests/fs/write.test.ts +77 -13
  120. package/tests/fs/xattr.test.ts +85 -0
  121. package/tests/logs.js +22 -0
  122. package/tests/setup/context.ts +1 -1
  123. package/tests/setup/index.ts +3 -3
  124. package/tests/setup/port.ts +7 -1
  125. package/dist/backends/port/fs.d.ts +0 -84
  126. package/dist/backends/port/fs.js +0 -151
  127. package/dist/backends/port/rpc.d.ts +0 -77
  128. package/dist/backends/port/rpc.js +0 -100
  129. package/dist/backends/store/simple.d.ts +0 -20
  130. package/dist/backends/store/simple.js +0 -13
  131. package/dist/internal/file.d.ts +0 -359
  132. package/dist/internal/file.js +0 -751
  133. package/dist/internal/log.d.ts +0 -133
  134. package/dist/internal/log.js +0 -218
  135. package/tests/fs/writeFile.test.ts +0 -70
@@ -32,23 +32,97 @@ var __runInitializers = (this && this.__runInitializers) || function (thisArg, i
32
32
  }
33
33
  return useValue ? value : void 0;
34
34
  };
35
+ var __addDisposableResource = (this && this.__addDisposableResource) || function (env, value, async) {
36
+ if (value !== null && value !== void 0) {
37
+ if (typeof value !== "object" && typeof value !== "function") throw new TypeError("Object expected.");
38
+ var dispose, inner;
39
+ if (async) {
40
+ if (!Symbol.asyncDispose) throw new TypeError("Symbol.asyncDispose is not defined.");
41
+ dispose = value[Symbol.asyncDispose];
42
+ }
43
+ if (dispose === void 0) {
44
+ if (!Symbol.dispose) throw new TypeError("Symbol.dispose is not defined.");
45
+ dispose = value[Symbol.dispose];
46
+ if (async) inner = dispose;
47
+ }
48
+ if (typeof dispose !== "function") throw new TypeError("Object not disposable.");
49
+ if (inner) dispose = function() { try { inner.call(this); } catch (e) { return Promise.reject(e); } };
50
+ env.stack.push({ value: value, dispose: dispose, async: async });
51
+ }
52
+ else if (async) {
53
+ env.stack.push({ async: true });
54
+ }
55
+ return value;
56
+ };
57
+ var __disposeResources = (this && this.__disposeResources) || (function (SuppressedError) {
58
+ return function (env) {
59
+ function fail(e) {
60
+ env.error = env.hasError ? new SuppressedError(e, env.error, "An error was suppressed during disposal.") : e;
61
+ env.hasError = true;
62
+ }
63
+ var r, s = 0;
64
+ function next() {
65
+ while (r = env.stack.pop()) {
66
+ try {
67
+ if (!r.async && s === 1) return s = 0, env.stack.push(r), Promise.resolve().then(next);
68
+ if (r.dispose) {
69
+ var result = r.dispose.call(r.value);
70
+ if (r.async) return s |= 2, Promise.resolve(result).then(next, function(e) { fail(e); return next(); });
71
+ }
72
+ else s |= 1;
73
+ }
74
+ catch (e) {
75
+ fail(e);
76
+ }
77
+ }
78
+ if (s === 1) return env.hasError ? Promise.reject(env.error) : Promise.resolve();
79
+ if (env.hasError) throw env.error;
80
+ }
81
+ return next();
82
+ };
83
+ })(typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
84
+ var e = new Error(message);
85
+ return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
86
+ });
35
87
  var __setFunctionName = (this && this.__setFunctionName) || function (f, name, prefix) {
36
88
  if (typeof name === "symbol") name = name.description ? "[".concat(name.description, "]") : "";
37
89
  return Object.defineProperty(f, "name", { configurable: true, value: prefix ? "".concat(prefix, " ", name) : name });
38
90
  };
39
- import { deserialize, member, offsetof, serialize, sizeof, struct, types as t } from 'utilium';
91
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
92
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
93
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
94
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
95
+ };
96
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
97
+ if (kind === "m") throw new TypeError("Private method is not writable");
98
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
99
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
100
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
101
+ };
102
+ import { withErrno } from 'kerium';
103
+ import { alert, crit, err, warn } from 'kerium/log';
104
+ import { field, offsetof, packed, sizeof, struct, types as t } from 'memium';
105
+ import { BufferView } from 'utilium/buffer.js';
40
106
  import { crc32c } from 'utilium/checksum.js';
41
- import { Errno, ErrnoError } from '../internal/error.js';
42
- import { _inode_version } from '../internal/inode.js';
43
- import { crit, warn } from '../internal/log.js';
107
+ import { decodeUUID, encodeUUID } from 'utilium/string.js';
108
+ import { _inode_version, Inode } from '../internal/inode.js';
44
109
  import { StoreFS } from './store/fs.js';
45
110
  import { SyncMapTransaction } from './store/map.js';
111
+ // eslint-disable-next-line @typescript-eslint/unbound-method
112
+ const { format } = new Intl.NumberFormat('en-US', {
113
+ notation: 'compact',
114
+ maximumFractionDigits: 2,
115
+ unit: 'byte',
116
+ unitDisplay: 'narrow',
117
+ });
46
118
  let MetadataEntry = (() => {
119
+ var _MetadataEntry_id_accessor_storage, _MetadataEntry_offset__accessor_storage, _MetadataEntry_offset_accessor_storage, _MetadataEntry_size_accessor_storage;
47
120
  var _a, _b, _c, _d;
48
- let _classDecorators = [struct()];
121
+ let _classDecorators = [struct(packed)];
49
122
  let _classDescriptor;
50
123
  let _classExtraInitializers = [];
51
124
  let _classThis;
125
+ let _classSuper = BufferView;
52
126
  let _id_decorators;
53
127
  let _id_initializers = [];
54
128
  let _id_extraInitializers = [];
@@ -61,30 +135,47 @@ let MetadataEntry = (() => {
61
135
  let _size_decorators;
62
136
  let _size_initializers = [];
63
137
  let _size_extraInitializers = [];
64
- var MetadataEntry = _classThis = class {
138
+ var MetadataEntry = _classThis = class extends _classSuper {
139
+ /** Inode or data ID */
140
+ get id() { return __classPrivateFieldGet(this, _MetadataEntry_id_accessor_storage, "f"); }
141
+ set id(value) { __classPrivateFieldSet(this, _MetadataEntry_id_accessor_storage, value, "f"); }
142
+ /** Reserved for 64-bit offset expansion */
143
+ get offset_() { return __classPrivateFieldGet(this, _MetadataEntry_offset__accessor_storage, "f"); }
144
+ set offset_(value) { __classPrivateFieldSet(this, _MetadataEntry_offset__accessor_storage, value, "f"); }
145
+ /** Offset into the buffer the data is stored at. */
146
+ get offset() { return __classPrivateFieldGet(this, _MetadataEntry_offset_accessor_storage, "f"); }
147
+ set offset(value) { __classPrivateFieldSet(this, _MetadataEntry_offset_accessor_storage, value, "f"); }
148
+ /** The size of the data */
149
+ get size() { return __classPrivateFieldGet(this, _MetadataEntry_size_accessor_storage, "f"); }
150
+ set size(value) { __classPrivateFieldSet(this, _MetadataEntry_size_accessor_storage, value, "f"); }
151
+ toString() {
152
+ return `<MetadataEntry @ 0x${this.byteOffset.toString(16).padStart(8, '0')}>`;
153
+ }
65
154
  constructor() {
66
- /** Inode or data ID */
67
- this.id = __runInitializers(this, _id_initializers, 0);
68
- /** Reserved for 64-bit offset expansion */
69
- this.offset_ = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _offset__initializers, 0));
70
- /** Offset into the buffer the data is stored at. */
71
- this.offset = (__runInitializers(this, _offset__extraInitializers), __runInitializers(this, _offset_initializers, 0));
72
- /** The size of the data */
73
- this.size = (__runInitializers(this, _offset_extraInitializers), __runInitializers(this, _size_initializers, 0));
155
+ super(...arguments);
156
+ _MetadataEntry_id_accessor_storage.set(this, __runInitializers(this, _id_initializers, void 0));
157
+ _MetadataEntry_offset__accessor_storage.set(this, (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _offset__initializers, void 0)));
158
+ _MetadataEntry_offset_accessor_storage.set(this, (__runInitializers(this, _offset__extraInitializers), __runInitializers(this, _offset_initializers, void 0)));
159
+ _MetadataEntry_size_accessor_storage.set(this, (__runInitializers(this, _offset_extraInitializers), __runInitializers(this, _size_initializers, void 0)));
74
160
  __runInitializers(this, _size_extraInitializers);
75
161
  }
76
162
  };
163
+ _MetadataEntry_id_accessor_storage = new WeakMap();
164
+ _MetadataEntry_offset__accessor_storage = new WeakMap();
165
+ _MetadataEntry_offset_accessor_storage = new WeakMap();
166
+ _MetadataEntry_size_accessor_storage = new WeakMap();
77
167
  __setFunctionName(_classThis, "MetadataEntry");
78
168
  (() => {
79
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
169
+ var _a;
170
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
80
171
  _id_decorators = [(_a = t).uint32.bind(_a)];
81
172
  _offset__decorators = [(_b = t).uint32.bind(_b)];
82
173
  _offset_decorators = [(_c = t).uint32.bind(_c)];
83
174
  _size_decorators = [(_d = t).uint32.bind(_d)];
84
- __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
85
- __esDecorate(null, null, _offset__decorators, { kind: "field", name: "offset_", static: false, private: false, access: { has: obj => "offset_" in obj, get: obj => obj.offset_, set: (obj, value) => { obj.offset_ = value; } }, metadata: _metadata }, _offset__initializers, _offset__extraInitializers);
86
- __esDecorate(null, null, _offset_decorators, { kind: "field", name: "offset", static: false, private: false, access: { has: obj => "offset" in obj, get: obj => obj.offset, set: (obj, value) => { obj.offset = value; } }, metadata: _metadata }, _offset_initializers, _offset_extraInitializers);
87
- __esDecorate(null, null, _size_decorators, { kind: "field", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
175
+ __esDecorate(_classThis, null, _id_decorators, { kind: "accessor", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
176
+ __esDecorate(_classThis, null, _offset__decorators, { kind: "accessor", name: "offset_", static: false, private: false, access: { has: obj => "offset_" in obj, get: obj => obj.offset_, set: (obj, value) => { obj.offset_ = value; } }, metadata: _metadata }, _offset__initializers, _offset__extraInitializers);
177
+ __esDecorate(_classThis, null, _offset_decorators, { kind: "accessor", name: "offset", static: false, private: false, access: { has: obj => "offset" in obj, get: obj => obj.offset, set: (obj, value) => { obj.offset = value; } }, metadata: _metadata }, _offset_initializers, _offset_extraInitializers);
178
+ __esDecorate(_classThis, null, _size_decorators, { kind: "accessor", name: "size", static: false, private: false, access: { has: obj => "size" in obj, get: obj => obj.size, set: (obj, value) => { obj.size = value; } }, metadata: _metadata }, _size_initializers, _size_extraInitializers);
88
179
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
89
180
  MetadataEntry = _classThis = _classDescriptor.value;
90
181
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -96,80 +187,148 @@ let MetadataEntry = (() => {
96
187
  * Number of entries per block of metadata
97
188
  */
98
189
  const entries_per_block = 255;
190
+ /**
191
+ * Number of times to attempt to acquire a lock before giving up.
192
+ */
193
+ const max_lock_attempts = 5;
99
194
  /**
100
195
  * A block of metadata for a single-buffer file system.
101
196
  * This metadata maps IDs (for inodes and data) to actual offsets in the buffer.
102
197
  * This is done since IDs are not guaranteed to be sequential.
103
198
  */
104
199
  let MetadataBlock = (() => {
200
+ var _MetadataBlock_checksum_accessor_storage, _MetadataBlock_timestamp_accessor_storage, _MetadataBlock_previous_offset_accessor_storage, _MetadataBlock_items_accessor_storage, _MetadataBlock_locked_accessor_storage;
105
201
  var _a, _b, _c, _d;
106
- let _classDecorators = [struct()];
202
+ let _classDecorators = [struct(packed)];
107
203
  let _classDescriptor;
108
204
  let _classExtraInitializers = [];
109
205
  let _classThis;
206
+ let _classSuper = Int32Array;
110
207
  let _checksum_decorators;
111
208
  let _checksum_initializers = [];
112
209
  let _checksum_extraInitializers = [];
113
210
  let _timestamp_decorators;
114
211
  let _timestamp_initializers = [];
115
212
  let _timestamp_extraInitializers = [];
116
- let _previous_offset__decorators;
117
- let _previous_offset__initializers = [];
118
- let _previous_offset__extraInitializers = [];
119
213
  let _previous_offset_decorators;
120
214
  let _previous_offset_initializers = [];
121
215
  let _previous_offset_extraInitializers = [];
122
- let _entries_decorators;
123
- let _entries_initializers = [];
124
- let _entries_extraInitializers = [];
125
- var MetadataBlock = _classThis = class {
126
- constructor(superblock, offset = 0) {
127
- this.superblock = superblock;
128
- this.offset = offset;
129
- /**
130
- * The crc32c checksum for the metadata block.
131
- * @privateRemarks Keep this first!
132
- */
133
- this.checksum = __runInitializers(this, _checksum_initializers, 0);
134
- /** The (last) time this metadata block was updated */
135
- this.timestamp = (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _timestamp_initializers, Date.now()));
136
- /** Reserved for 64-bit offset expansion */
137
- this.previous_offset_ = (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _previous_offset__initializers, 0));
138
- /** Offset to the previous metadata block */
139
- this.previous_offset = (__runInitializers(this, _previous_offset__extraInitializers), __runInitializers(this, _previous_offset_initializers, 0));
140
- this._previous = __runInitializers(this, _previous_offset_extraInitializers);
141
- /** Metadata entries. */
142
- this.entries = __runInitializers(this, _entries_initializers, Array.from({ length: entries_per_block }, () => new MetadataEntry()));
143
- __runInitializers(this, _entries_extraInitializers);
144
- this.superblock = superblock;
145
- this.offset = offset;
146
- if (!offset)
147
- return; // fresh block
148
- deserialize(this, superblock.store._buffer.subarray(offset, offset + sizeof(MetadataBlock)));
149
- if (!checksumMatches(this))
150
- throw crit(new ErrnoError(Errno.EIO, 'SingleBuffer: Checksum mismatch for metadata block at 0x' + offset.toString(16)));
151
- }
216
+ let _items_decorators;
217
+ let _items_initializers = [];
218
+ let _items_extraInitializers = [];
219
+ let _locked_decorators;
220
+ let _locked_initializers = [];
221
+ let _locked_extraInitializers = [];
222
+ var MetadataBlock = _classThis = class extends _classSuper {
223
+ /**
224
+ * The crc32c checksum for the metadata block.
225
+ * @privateRemarks Keep this first!
226
+ */
227
+ get checksum() { return __classPrivateFieldGet(this, _MetadataBlock_checksum_accessor_storage, "f"); }
228
+ set checksum(value) { __classPrivateFieldSet(this, _MetadataBlock_checksum_accessor_storage, value, "f"); }
229
+ /** The (last) time this metadata block was updated */
230
+ get timestamp() { return __classPrivateFieldGet(this, _MetadataBlock_timestamp_accessor_storage, "f"); }
231
+ set timestamp(value) { __classPrivateFieldSet(this, _MetadataBlock_timestamp_accessor_storage, value, "f"); }
232
+ /** Offset to the previous metadata block */
233
+ get previous_offset() { return __classPrivateFieldGet(this, _MetadataBlock_previous_offset_accessor_storage, "f"); }
234
+ set previous_offset(value) { __classPrivateFieldSet(this, _MetadataBlock_previous_offset_accessor_storage, value, "f"); }
152
235
  get previous() {
153
236
  var _a;
154
237
  if (!this.previous_offset)
155
238
  return;
156
- (_a = this._previous) !== null && _a !== void 0 ? _a : (this._previous = new MetadataBlock(this.superblock, this.previous_offset));
239
+ (_a = this._previous) !== null && _a !== void 0 ? _a : (this._previous = new MetadataBlock(this.buffer, this.previous_offset));
157
240
  return this._previous;
158
241
  }
242
+ get offsetHex() {
243
+ return '0x' + this.byteOffset.toString(16).padStart(8, '0');
244
+ }
245
+ /** Metadata entries. */
246
+ get items() { return __classPrivateFieldGet(this, _MetadataBlock_items_accessor_storage, "f"); }
247
+ set items(value) { __classPrivateFieldSet(this, _MetadataBlock_items_accessor_storage, value, "f"); }
248
+ toString(long = false) {
249
+ if (!long)
250
+ return `<MetadataBlock @ ${this.offsetHex}>`;
251
+ let text = [
252
+ `---- Metadata block at ${this.offsetHex} ----`,
253
+ `Checksum: 0x${this.checksum.toString(16).padStart(8, '0')}`,
254
+ `Last updated: ${new Date(Number(this.timestamp)).toLocaleString()}`,
255
+ `Previous block: 0x${this.previous_offset.toString(16).padStart(8, '0')}`,
256
+ 'Entries:',
257
+ ].join('\n');
258
+ for (const entry of this.items) {
259
+ if (!entry.offset)
260
+ continue;
261
+ text += `\n\t0x${entry.id.toString(16).padStart(8, '0')}: ${format(entry.size).padStart(5)} at 0x${entry.offset.toString(16).padStart(8, '0')}`;
262
+ }
263
+ return text;
264
+ }
265
+ /**
266
+ * If non-zero, this block is locked for writing.
267
+ * Note a int32 is used for `Atomics.wait`
268
+ */
269
+ get locked() { return __classPrivateFieldGet(this, _MetadataBlock_locked_accessor_storage, "f"); }
270
+ set locked(value) { __classPrivateFieldSet(this, _MetadataBlock_locked_accessor_storage, value, "f"); }
271
+ /**
272
+ * Wait for the block to be unlocked.
273
+ */
274
+ waitUnlocked(depth = 0) {
275
+ if (depth > max_lock_attempts)
276
+ throw crit(withErrno('EBUSY', `sbfs: exceeded max attempts waiting for metadata block at ${this.offsetHex} to be unlocked`));
277
+ const i = this.length - 1;
278
+ if (!Atomics.load(this, i))
279
+ return;
280
+ switch (Atomics.wait(this, i, 1)) {
281
+ case 'ok':
282
+ break;
283
+ case 'not-equal':
284
+ depth++;
285
+ err(`sbfs: waiting for metadata block at ${this.offsetHex} to be unlocked (${depth}/${max_lock_attempts})`);
286
+ return this.waitUnlocked(depth);
287
+ case 'timed-out':
288
+ throw crit(withErrno('EBUSY', `sbfs: timed out waiting for metadata block at ${this.offsetHex} to be unlocked`));
289
+ }
290
+ }
291
+ lock() {
292
+ this.waitUnlocked();
293
+ const i = offsetof(this, 'locked');
294
+ Atomics.store(this, i, 1);
295
+ const release = () => {
296
+ Atomics.store(this, i, 0);
297
+ Atomics.notify(this, i, 1);
298
+ };
299
+ release[Symbol.dispose] = release;
300
+ return release;
301
+ }
302
+ constructor() {
303
+ super(...arguments);
304
+ _MetadataBlock_checksum_accessor_storage.set(this, __runInitializers(this, _checksum_initializers, void 0));
305
+ _MetadataBlock_timestamp_accessor_storage.set(this, (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _timestamp_initializers, BigInt(Date.now()))));
306
+ _MetadataBlock_previous_offset_accessor_storage.set(this, (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _previous_offset_initializers, void 0)));
307
+ this._previous = __runInitializers(this, _previous_offset_extraInitializers);
308
+ _MetadataBlock_items_accessor_storage.set(this, __runInitializers(this, _items_initializers, void 0));
309
+ _MetadataBlock_locked_accessor_storage.set(this, (__runInitializers(this, _items_extraInitializers), __runInitializers(this, _locked_initializers, void 0)));
310
+ __runInitializers(this, _locked_extraInitializers);
311
+ }
159
312
  };
313
+ _MetadataBlock_checksum_accessor_storage = new WeakMap();
314
+ _MetadataBlock_timestamp_accessor_storage = new WeakMap();
315
+ _MetadataBlock_previous_offset_accessor_storage = new WeakMap();
316
+ _MetadataBlock_items_accessor_storage = new WeakMap();
317
+ _MetadataBlock_locked_accessor_storage = new WeakMap();
160
318
  __setFunctionName(_classThis, "MetadataBlock");
161
319
  (() => {
162
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
320
+ var _a;
321
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
163
322
  _checksum_decorators = [(_a = t).uint32.bind(_a)];
164
- _timestamp_decorators = [(_b = t).uint32.bind(_b)];
165
- _previous_offset__decorators = [(_c = t).uint32.bind(_c)];
166
- _previous_offset_decorators = [(_d = t).uint32.bind(_d)];
167
- _entries_decorators = [member(MetadataEntry, entries_per_block)];
168
- __esDecorate(null, null, _checksum_decorators, { kind: "field", name: "checksum", static: false, private: false, access: { has: obj => "checksum" in obj, get: obj => obj.checksum, set: (obj, value) => { obj.checksum = value; } }, metadata: _metadata }, _checksum_initializers, _checksum_extraInitializers);
169
- __esDecorate(null, null, _timestamp_decorators, { kind: "field", name: "timestamp", static: false, private: false, access: { has: obj => "timestamp" in obj, get: obj => obj.timestamp, set: (obj, value) => { obj.timestamp = value; } }, metadata: _metadata }, _timestamp_initializers, _timestamp_extraInitializers);
170
- __esDecorate(null, null, _previous_offset__decorators, { kind: "field", name: "previous_offset_", static: false, private: false, access: { has: obj => "previous_offset_" in obj, get: obj => obj.previous_offset_, set: (obj, value) => { obj.previous_offset_ = value; } }, metadata: _metadata }, _previous_offset__initializers, _previous_offset__extraInitializers);
171
- __esDecorate(null, null, _previous_offset_decorators, { kind: "field", name: "previous_offset", static: false, private: false, access: { has: obj => "previous_offset" in obj, get: obj => obj.previous_offset, set: (obj, value) => { obj.previous_offset = value; } }, metadata: _metadata }, _previous_offset_initializers, _previous_offset_extraInitializers);
172
- __esDecorate(null, null, _entries_decorators, { kind: "field", name: "entries", static: false, private: false, access: { has: obj => "entries" in obj, get: obj => obj.entries, set: (obj, value) => { obj.entries = value; } }, metadata: _metadata }, _entries_initializers, _entries_extraInitializers);
323
+ _timestamp_decorators = [(_b = t).uint64.bind(_b)];
324
+ _previous_offset_decorators = [(_c = t).uint32.bind(_c)];
325
+ _items_decorators = [field(MetadataEntry, { length: entries_per_block })];
326
+ _locked_decorators = [(_d = t).int32.bind(_d)];
327
+ __esDecorate(_classThis, null, _checksum_decorators, { kind: "accessor", name: "checksum", static: false, private: false, access: { has: obj => "checksum" in obj, get: obj => obj.checksum, set: (obj, value) => { obj.checksum = value; } }, metadata: _metadata }, _checksum_initializers, _checksum_extraInitializers);
328
+ __esDecorate(_classThis, null, _timestamp_decorators, { kind: "accessor", name: "timestamp", static: false, private: false, access: { has: obj => "timestamp" in obj, get: obj => obj.timestamp, set: (obj, value) => { obj.timestamp = value; } }, metadata: _metadata }, _timestamp_initializers, _timestamp_extraInitializers);
329
+ __esDecorate(_classThis, null, _previous_offset_decorators, { kind: "accessor", name: "previous_offset", static: false, private: false, access: { has: obj => "previous_offset" in obj, get: obj => obj.previous_offset, set: (obj, value) => { obj.previous_offset = value; } }, metadata: _metadata }, _previous_offset_initializers, _previous_offset_extraInitializers);
330
+ __esDecorate(_classThis, null, _items_decorators, { kind: "accessor", name: "items", static: false, private: false, access: { has: obj => "items" in obj, get: obj => obj.items, set: (obj, value) => { obj.items = value; } }, metadata: _metadata }, _items_initializers, _items_extraInitializers);
331
+ __esDecorate(_classThis, null, _locked_decorators, { kind: "accessor", name: "locked", static: false, private: false, access: { has: obj => "locked" in obj, get: obj => obj.locked, set: (obj, value) => { obj.locked = value; } }, metadata: _metadata }, _locked_initializers, _locked_extraInitializers);
173
332
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
174
333
  MetadataBlock = _classThis = _classDescriptor.value;
175
334
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -177,16 +336,19 @@ let MetadataBlock = (() => {
177
336
  })();
178
337
  return MetadataBlock = _classThis;
179
338
  })();
180
- const sb_magic = 0x7a2e7362; // 'z.sb'
339
+ export { MetadataBlock };
340
+ const sb_magic = 0x62732e7a; // 'z.sb'
181
341
  /**
182
342
  * The super block structure for a single-buffer file system
183
343
  */
184
344
  let SuperBlock = (() => {
185
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
186
- let _classDecorators = [struct()];
345
+ var _SuperBlock_checksum_accessor_storage, _SuperBlock_magic_accessor_storage, _SuperBlock_version_accessor_storage, _SuperBlock_inode_format_accessor_storage, _SuperBlock_flags_accessor_storage, _SuperBlock_used_bytes_accessor_storage, _SuperBlock_total_bytes_accessor_storage, _SuperBlock_uuid_accessor_storage, _SuperBlock_metadata_block_size_accessor_storage, _SuperBlock_metadata_offset__accessor_storage, _SuperBlock_metadata_offset_accessor_storage, _SuperBlock_label_accessor_storage, _SuperBlock__padding_accessor_storage;
346
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k;
347
+ let _classDecorators = [struct(packed)];
187
348
  let _classDescriptor;
188
349
  let _classExtraInitializers = [];
189
350
  let _classThis;
351
+ let _classSuper = BufferView;
190
352
  let _checksum_decorators;
191
353
  let _checksum_initializers = [];
192
354
  let _checksum_extraInitializers = [];
@@ -208,9 +370,9 @@ let SuperBlock = (() => {
208
370
  let _total_bytes_decorators;
209
371
  let _total_bytes_initializers = [];
210
372
  let _total_bytes_extraInitializers = [];
211
- let _id_decorators;
212
- let _id_initializers = [];
213
- let _id_extraInitializers = [];
373
+ let _uuid_decorators;
374
+ let _uuid_initializers = [];
375
+ let _uuid_extraInitializers = [];
214
376
  let _metadata_block_size_decorators;
215
377
  let _metadata_block_size_initializers = [];
216
378
  let _metadata_block_size_extraInitializers = [];
@@ -226,58 +388,97 @@ let SuperBlock = (() => {
226
388
  let __padding_decorators;
227
389
  let __padding_initializers = [];
228
390
  let __padding_extraInitializers = [];
229
- var SuperBlock = _classThis = class {
230
- constructor(store) {
231
- this.store = store;
232
- /**
233
- * The crc32c checksum for the super block.
234
- * @privateRemarks Keep this first!
235
- */
236
- this.checksum = __runInitializers(this, _checksum_initializers, 0);
237
- /** Signature for the superblock. */
238
- this.magic = (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _magic_initializers, sb_magic));
239
- /** The version of the on-disk format */
240
- this.version = (__runInitializers(this, _magic_extraInitializers), __runInitializers(this, _version_initializers, 1));
241
- /** Which format of `Inode` is used */
242
- this.inode_format = (__runInitializers(this, _version_extraInitializers), __runInitializers(this, _inode_format_initializers, _inode_version));
243
- /** Flags for the file system. Currently unused */
244
- this.flags = (__runInitializers(this, _inode_format_extraInitializers), __runInitializers(this, _flags_initializers, 0));
245
- /** The number of used bytes, including the super block and metadata */
246
- this.used_bytes = (__runInitializers(this, _flags_extraInitializers), __runInitializers(this, _used_bytes_initializers, BigInt(0)));
247
- /** The total size of the entire file system, including the super block and metadata */
248
- this.total_bytes = (__runInitializers(this, _used_bytes_extraInitializers), __runInitializers(this, _total_bytes_initializers, BigInt(0)));
249
- /** An ID for this file system */
250
- this.id = (__runInitializers(this, _total_bytes_extraInitializers), __runInitializers(this, _id_initializers, BigInt(0)));
251
- /**
252
- * The size in bytes of a metadata block.
253
- * Not currently configurable.
254
- */
255
- this.metadata_block_size = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _metadata_block_size_initializers, sizeof(MetadataBlock)));
256
- /** Reserved for 64-bit offset expansion */
257
- this.metadata_offset_ = (__runInitializers(this, _metadata_block_size_extraInitializers), __runInitializers(this, _metadata_offset__initializers, 0));
258
- /** Offset of the current metadata block */
259
- this.metadata_offset = (__runInitializers(this, _metadata_offset__extraInitializers), __runInitializers(this, _metadata_offset_initializers, 0));
391
+ var SuperBlock = _classThis = class extends _classSuper {
392
+ constructor(...args) {
393
+ super(...args);
394
+ _SuperBlock_checksum_accessor_storage.set(this, __runInitializers(this, _checksum_initializers, void 0));
395
+ _SuperBlock_magic_accessor_storage.set(this, (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _magic_initializers, void 0)));
396
+ _SuperBlock_version_accessor_storage.set(this, (__runInitializers(this, _magic_extraInitializers), __runInitializers(this, _version_initializers, void 0)));
397
+ _SuperBlock_inode_format_accessor_storage.set(this, (__runInitializers(this, _version_extraInitializers), __runInitializers(this, _inode_format_initializers, void 0)));
398
+ _SuperBlock_flags_accessor_storage.set(this, (__runInitializers(this, _inode_format_extraInitializers), __runInitializers(this, _flags_initializers, void 0)));
399
+ _SuperBlock_used_bytes_accessor_storage.set(this, (__runInitializers(this, _flags_extraInitializers), __runInitializers(this, _used_bytes_initializers, void 0)));
400
+ _SuperBlock_total_bytes_accessor_storage.set(this, (__runInitializers(this, _used_bytes_extraInitializers), __runInitializers(this, _total_bytes_initializers, void 0)));
401
+ _SuperBlock_uuid_accessor_storage.set(this, (__runInitializers(this, _total_bytes_extraInitializers), __runInitializers(this, _uuid_initializers, void 0)));
402
+ _SuperBlock_metadata_block_size_accessor_storage.set(this, (__runInitializers(this, _uuid_extraInitializers), __runInitializers(this, _metadata_block_size_initializers, void 0)));
403
+ _SuperBlock_metadata_offset__accessor_storage.set(this, (__runInitializers(this, _metadata_block_size_extraInitializers), __runInitializers(this, _metadata_offset__initializers, void 0)));
404
+ _SuperBlock_metadata_offset_accessor_storage.set(this, (__runInitializers(this, _metadata_offset__extraInitializers), __runInitializers(this, _metadata_offset_initializers, void 0)));
260
405
  this.metadata = __runInitializers(this, _metadata_offset_extraInitializers);
261
- /** An optional label for the file system */
262
- this.label = __runInitializers(this, _label_initializers, '');
263
- /** Padded to 256 bytes */
264
- this._padding = (__runInitializers(this, _label_extraInitializers), __runInitializers(this, __padding_initializers, new Array(132).fill(0)));
406
+ _SuperBlock_label_accessor_storage.set(this, __runInitializers(this, _label_initializers, void 0));
407
+ _SuperBlock__padding_accessor_storage.set(this, (__runInitializers(this, _label_extraInitializers), __runInitializers(this, __padding_initializers, void 0)));
265
408
  __runInitializers(this, __padding_extraInitializers);
266
- this.store = store;
267
- if (store._view.getUint32(offsetof(SuperBlock, 'magic'), true) != sb_magic) {
268
- warn('SingleBuffer: Invalid magic value, assuming this is a fresh super block');
269
- this.metadata = new MetadataBlock(this);
270
- this.used_bytes = BigInt(sizeof(SuperBlock) + sizeof(MetadataBlock));
271
- this.total_bytes = BigInt(store._buffer.byteLength);
272
- store._write(this);
273
- store._write(this.metadata);
409
+ if (this.magic != sb_magic) {
410
+ warn('sbfs: Invalid magic value, assuming this is a fresh super block');
411
+ const md = new MetadataBlock(this.buffer, sizeof(SuperBlock));
412
+ Object.assign(this, {
413
+ metadata: md,
414
+ metadata_offset: md.byteOffset,
415
+ used_bytes: BigInt(sizeof(SuperBlock) + sizeof(MetadataBlock)),
416
+ total_bytes: BigInt(this.buffer.byteLength),
417
+ magic: sb_magic,
418
+ version: 1,
419
+ inode_format: _inode_version,
420
+ metadata_block_size: sizeof(MetadataBlock),
421
+ uuid: encodeUUID(crypto.randomUUID()),
422
+ });
423
+ _update(this);
424
+ _update(md);
274
425
  return;
275
426
  }
276
- deserialize(this, store._buffer.subarray(0, sizeof(SuperBlock)));
277
- if (!checksumMatches(this))
278
- throw crit(new ErrnoError(Errno.EIO, 'SingleBuffer: Checksum mismatch for super block!'));
279
- this.metadata = new MetadataBlock(this, this.metadata_offset);
427
+ if (this.checksum !== checksum(this))
428
+ throw crit(withErrno('EIO', 'sbfs: checksum mismatch for super block'));
429
+ this.metadata = new MetadataBlock(this.buffer, this.metadata_offset);
430
+ if (this.metadata.checksum !== checksum(this.metadata))
431
+ throw crit(withErrno('EIO', `sbfs: checksum mismatch for metadata block (saved ${this.metadata.checksum.toString(16).padStart(8, '0')}, computed ${checksum(this.metadata).toString(16).padStart(8, '0')})`));
432
+ if (this.inode_format != _inode_version)
433
+ throw crit(withErrno('EIO', 'sbfs: inode format mismatch'));
434
+ if (this.metadata_block_size != sizeof(MetadataBlock))
435
+ throw crit(withErrno('EIO', 'sbfs: metadata block size mismatch'));
280
436
  }
437
+ /**
438
+ * The crc32c checksum for the super block.
439
+ * @privateRemarks Keep this first!
440
+ */
441
+ get checksum() { return __classPrivateFieldGet(this, _SuperBlock_checksum_accessor_storage, "f"); }
442
+ set checksum(value) { __classPrivateFieldSet(this, _SuperBlock_checksum_accessor_storage, value, "f"); }
443
+ /** Signature for the superblock. */
444
+ get magic() { return __classPrivateFieldGet(this, _SuperBlock_magic_accessor_storage, "f"); }
445
+ set magic(value) { __classPrivateFieldSet(this, _SuperBlock_magic_accessor_storage, value, "f"); }
446
+ /** The version of the on-disk format */
447
+ get version() { return __classPrivateFieldGet(this, _SuperBlock_version_accessor_storage, "f"); }
448
+ set version(value) { __classPrivateFieldSet(this, _SuperBlock_version_accessor_storage, value, "f"); }
449
+ /** Which format of `Inode` is used */
450
+ get inode_format() { return __classPrivateFieldGet(this, _SuperBlock_inode_format_accessor_storage, "f"); }
451
+ set inode_format(value) { __classPrivateFieldSet(this, _SuperBlock_inode_format_accessor_storage, value, "f"); }
452
+ /** Flags for the file system. Currently unused */
453
+ get flags() { return __classPrivateFieldGet(this, _SuperBlock_flags_accessor_storage, "f"); }
454
+ set flags(value) { __classPrivateFieldSet(this, _SuperBlock_flags_accessor_storage, value, "f"); }
455
+ /** The number of used bytes, including the super block and metadata */
456
+ get used_bytes() { return __classPrivateFieldGet(this, _SuperBlock_used_bytes_accessor_storage, "f"); }
457
+ set used_bytes(value) { __classPrivateFieldSet(this, _SuperBlock_used_bytes_accessor_storage, value, "f"); }
458
+ /** The total size of the entire file system, including the super block and metadata */
459
+ get total_bytes() { return __classPrivateFieldGet(this, _SuperBlock_total_bytes_accessor_storage, "f"); }
460
+ set total_bytes(value) { __classPrivateFieldSet(this, _SuperBlock_total_bytes_accessor_storage, value, "f"); }
461
+ /** A UUID for this file system */
462
+ get uuid() { return __classPrivateFieldGet(this, _SuperBlock_uuid_accessor_storage, "f"); }
463
+ set uuid(value) { __classPrivateFieldSet(this, _SuperBlock_uuid_accessor_storage, value, "f"); }
464
+ /**
465
+ * The size in bytes of a metadata block.
466
+ * Not currently configurable.
467
+ */
468
+ get metadata_block_size() { return __classPrivateFieldGet(this, _SuperBlock_metadata_block_size_accessor_storage, "f"); }
469
+ set metadata_block_size(value) { __classPrivateFieldSet(this, _SuperBlock_metadata_block_size_accessor_storage, value, "f"); }
470
+ /** Reserved for 64-bit offset expansion */
471
+ get metadata_offset_() { return __classPrivateFieldGet(this, _SuperBlock_metadata_offset__accessor_storage, "f"); }
472
+ set metadata_offset_(value) { __classPrivateFieldSet(this, _SuperBlock_metadata_offset__accessor_storage, value, "f"); }
473
+ /** Offset of the current metadata block */
474
+ get metadata_offset() { return __classPrivateFieldGet(this, _SuperBlock_metadata_offset_accessor_storage, "f"); }
475
+ set metadata_offset(value) { __classPrivateFieldSet(this, _SuperBlock_metadata_offset_accessor_storage, value, "f"); }
476
+ /** An optional label for the file system */
477
+ get label() { return __classPrivateFieldGet(this, _SuperBlock_label_accessor_storage, "f"); }
478
+ set label(value) { __classPrivateFieldSet(this, _SuperBlock_label_accessor_storage, value, "f"); }
479
+ /** Padded to 256 bytes */
480
+ get _padding() { return __classPrivateFieldGet(this, _SuperBlock__padding_accessor_storage, "f"); }
481
+ set _padding(value) { __classPrivateFieldSet(this, _SuperBlock__padding_accessor_storage, value, "f"); }
281
482
  /**
282
483
  * Rotate out the current metadata block.
283
484
  * Allocates a new metadata block, moves the current one to backup,
@@ -285,14 +486,13 @@ let SuperBlock = (() => {
285
486
  * @returns the new metadata block
286
487
  */
287
488
  rotateMetadata() {
288
- const metadata = new MetadataBlock(this);
289
- metadata.offset = Number(this.used_bytes);
489
+ const metadata = new MetadataBlock(this.buffer, Number(this.used_bytes));
290
490
  metadata.previous_offset = this.metadata_offset;
291
491
  this.metadata = metadata;
292
- this.metadata_offset = metadata.offset;
293
- this.store._write(metadata);
492
+ this.metadata_offset = metadata.byteOffset;
493
+ _update(metadata);
294
494
  this.used_bytes += BigInt(sizeof(MetadataBlock));
295
- this.store._write(this);
495
+ _update(this);
296
496
  return metadata;
297
497
  }
298
498
  /**
@@ -305,9 +505,9 @@ let SuperBlock = (() => {
305
505
  if (offset + length > this.total_bytes || offset < sizeof(SuperBlock))
306
506
  return false;
307
507
  for (let block = this.metadata; block; block = block.previous) {
308
- if (offset < block.offset + sizeof(MetadataBlock) && offset + length > block.offset)
508
+ if (offset < block.byteOffset + sizeof(MetadataBlock) && offset + length > block.byteOffset)
309
509
  return false;
310
- for (const entry of block.entries) {
510
+ for (const entry of block.items) {
311
511
  if (!entry.offset)
312
512
  continue;
313
513
  if ((offset >= entry.offset && offset < entry.offset + entry.size)
@@ -320,9 +520,23 @@ let SuperBlock = (() => {
320
520
  return true;
321
521
  }
322
522
  };
523
+ _SuperBlock_checksum_accessor_storage = new WeakMap();
524
+ _SuperBlock_magic_accessor_storage = new WeakMap();
525
+ _SuperBlock_version_accessor_storage = new WeakMap();
526
+ _SuperBlock_inode_format_accessor_storage = new WeakMap();
527
+ _SuperBlock_flags_accessor_storage = new WeakMap();
528
+ _SuperBlock_used_bytes_accessor_storage = new WeakMap();
529
+ _SuperBlock_total_bytes_accessor_storage = new WeakMap();
530
+ _SuperBlock_uuid_accessor_storage = new WeakMap();
531
+ _SuperBlock_metadata_block_size_accessor_storage = new WeakMap();
532
+ _SuperBlock_metadata_offset__accessor_storage = new WeakMap();
533
+ _SuperBlock_metadata_offset_accessor_storage = new WeakMap();
534
+ _SuperBlock_label_accessor_storage = new WeakMap();
535
+ _SuperBlock__padding_accessor_storage = new WeakMap();
323
536
  __setFunctionName(_classThis, "SuperBlock");
324
537
  (() => {
325
- const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(null) : void 0;
538
+ var _a;
539
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create((_a = _classSuper[Symbol.metadata]) !== null && _a !== void 0 ? _a : null) : void 0;
326
540
  _checksum_decorators = [(_a = t).uint32.bind(_a)];
327
541
  _magic_decorators = [(_b = t).uint32.bind(_b)];
328
542
  _version_decorators = [(_c = t).uint16.bind(_c)];
@@ -330,25 +544,25 @@ let SuperBlock = (() => {
330
544
  _flags_decorators = [(_e = t).uint32.bind(_e)];
331
545
  _used_bytes_decorators = [(_f = t).uint64.bind(_f)];
332
546
  _total_bytes_decorators = [(_g = t).uint64.bind(_g)];
333
- _id_decorators = [(_h = t).uint128.bind(_h)];
334
- _metadata_block_size_decorators = [(_j = t).uint32.bind(_j)];
335
- _metadata_offset__decorators = [(_k = t).uint32.bind(_k)];
336
- _metadata_offset_decorators = [(_l = t).uint32.bind(_l)];
547
+ _uuid_decorators = [t.uint8(16)];
548
+ _metadata_block_size_decorators = [(_h = t).uint32.bind(_h)];
549
+ _metadata_offset__decorators = [(_j = t).uint32.bind(_j)];
550
+ _metadata_offset_decorators = [(_k = t).uint32.bind(_k)];
337
551
  _label_decorators = [t.char(64)];
338
552
  __padding_decorators = [t.char(132)];
339
- __esDecorate(null, null, _checksum_decorators, { kind: "field", name: "checksum", static: false, private: false, access: { has: obj => "checksum" in obj, get: obj => obj.checksum, set: (obj, value) => { obj.checksum = value; } }, metadata: _metadata }, _checksum_initializers, _checksum_extraInitializers);
340
- __esDecorate(null, null, _magic_decorators, { kind: "field", name: "magic", static: false, private: false, access: { has: obj => "magic" in obj, get: obj => obj.magic, set: (obj, value) => { obj.magic = value; } }, metadata: _metadata }, _magic_initializers, _magic_extraInitializers);
341
- __esDecorate(null, null, _version_decorators, { kind: "field", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
342
- __esDecorate(null, null, _inode_format_decorators, { kind: "field", name: "inode_format", static: false, private: false, access: { has: obj => "inode_format" in obj, get: obj => obj.inode_format, set: (obj, value) => { obj.inode_format = value; } }, metadata: _metadata }, _inode_format_initializers, _inode_format_extraInitializers);
343
- __esDecorate(null, null, _flags_decorators, { kind: "field", name: "flags", static: false, private: false, access: { has: obj => "flags" in obj, get: obj => obj.flags, set: (obj, value) => { obj.flags = value; } }, metadata: _metadata }, _flags_initializers, _flags_extraInitializers);
344
- __esDecorate(null, null, _used_bytes_decorators, { kind: "field", name: "used_bytes", static: false, private: false, access: { has: obj => "used_bytes" in obj, get: obj => obj.used_bytes, set: (obj, value) => { obj.used_bytes = value; } }, metadata: _metadata }, _used_bytes_initializers, _used_bytes_extraInitializers);
345
- __esDecorate(null, null, _total_bytes_decorators, { kind: "field", name: "total_bytes", static: false, private: false, access: { has: obj => "total_bytes" in obj, get: obj => obj.total_bytes, set: (obj, value) => { obj.total_bytes = value; } }, metadata: _metadata }, _total_bytes_initializers, _total_bytes_extraInitializers);
346
- __esDecorate(null, null, _id_decorators, { kind: "field", name: "id", static: false, private: false, access: { has: obj => "id" in obj, get: obj => obj.id, set: (obj, value) => { obj.id = value; } }, metadata: _metadata }, _id_initializers, _id_extraInitializers);
347
- __esDecorate(null, null, _metadata_block_size_decorators, { kind: "field", name: "metadata_block_size", static: false, private: false, access: { has: obj => "metadata_block_size" in obj, get: obj => obj.metadata_block_size, set: (obj, value) => { obj.metadata_block_size = value; } }, metadata: _metadata }, _metadata_block_size_initializers, _metadata_block_size_extraInitializers);
348
- __esDecorate(null, null, _metadata_offset__decorators, { kind: "field", name: "metadata_offset_", static: false, private: false, access: { has: obj => "metadata_offset_" in obj, get: obj => obj.metadata_offset_, set: (obj, value) => { obj.metadata_offset_ = value; } }, metadata: _metadata }, _metadata_offset__initializers, _metadata_offset__extraInitializers);
349
- __esDecorate(null, null, _metadata_offset_decorators, { kind: "field", name: "metadata_offset", static: false, private: false, access: { has: obj => "metadata_offset" in obj, get: obj => obj.metadata_offset, set: (obj, value) => { obj.metadata_offset = value; } }, metadata: _metadata }, _metadata_offset_initializers, _metadata_offset_extraInitializers);
350
- __esDecorate(null, null, _label_decorators, { kind: "field", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
351
- __esDecorate(null, null, __padding_decorators, { kind: "field", name: "_padding", static: false, private: false, access: { has: obj => "_padding" in obj, get: obj => obj._padding, set: (obj, value) => { obj._padding = value; } }, metadata: _metadata }, __padding_initializers, __padding_extraInitializers);
553
+ __esDecorate(_classThis, null, _checksum_decorators, { kind: "accessor", name: "checksum", static: false, private: false, access: { has: obj => "checksum" in obj, get: obj => obj.checksum, set: (obj, value) => { obj.checksum = value; } }, metadata: _metadata }, _checksum_initializers, _checksum_extraInitializers);
554
+ __esDecorate(_classThis, null, _magic_decorators, { kind: "accessor", name: "magic", static: false, private: false, access: { has: obj => "magic" in obj, get: obj => obj.magic, set: (obj, value) => { obj.magic = value; } }, metadata: _metadata }, _magic_initializers, _magic_extraInitializers);
555
+ __esDecorate(_classThis, null, _version_decorators, { kind: "accessor", name: "version", static: false, private: false, access: { has: obj => "version" in obj, get: obj => obj.version, set: (obj, value) => { obj.version = value; } }, metadata: _metadata }, _version_initializers, _version_extraInitializers);
556
+ __esDecorate(_classThis, null, _inode_format_decorators, { kind: "accessor", name: "inode_format", static: false, private: false, access: { has: obj => "inode_format" in obj, get: obj => obj.inode_format, set: (obj, value) => { obj.inode_format = value; } }, metadata: _metadata }, _inode_format_initializers, _inode_format_extraInitializers);
557
+ __esDecorate(_classThis, null, _flags_decorators, { kind: "accessor", name: "flags", static: false, private: false, access: { has: obj => "flags" in obj, get: obj => obj.flags, set: (obj, value) => { obj.flags = value; } }, metadata: _metadata }, _flags_initializers, _flags_extraInitializers);
558
+ __esDecorate(_classThis, null, _used_bytes_decorators, { kind: "accessor", name: "used_bytes", static: false, private: false, access: { has: obj => "used_bytes" in obj, get: obj => obj.used_bytes, set: (obj, value) => { obj.used_bytes = value; } }, metadata: _metadata }, _used_bytes_initializers, _used_bytes_extraInitializers);
559
+ __esDecorate(_classThis, null, _total_bytes_decorators, { kind: "accessor", name: "total_bytes", static: false, private: false, access: { has: obj => "total_bytes" in obj, get: obj => obj.total_bytes, set: (obj, value) => { obj.total_bytes = value; } }, metadata: _metadata }, _total_bytes_initializers, _total_bytes_extraInitializers);
560
+ __esDecorate(_classThis, null, _uuid_decorators, { kind: "accessor", name: "uuid", static: false, private: false, access: { has: obj => "uuid" in obj, get: obj => obj.uuid, set: (obj, value) => { obj.uuid = value; } }, metadata: _metadata }, _uuid_initializers, _uuid_extraInitializers);
561
+ __esDecorate(_classThis, null, _metadata_block_size_decorators, { kind: "accessor", name: "metadata_block_size", static: false, private: false, access: { has: obj => "metadata_block_size" in obj, get: obj => obj.metadata_block_size, set: (obj, value) => { obj.metadata_block_size = value; } }, metadata: _metadata }, _metadata_block_size_initializers, _metadata_block_size_extraInitializers);
562
+ __esDecorate(_classThis, null, _metadata_offset__decorators, { kind: "accessor", name: "metadata_offset_", static: false, private: false, access: { has: obj => "metadata_offset_" in obj, get: obj => obj.metadata_offset_, set: (obj, value) => { obj.metadata_offset_ = value; } }, metadata: _metadata }, _metadata_offset__initializers, _metadata_offset__extraInitializers);
563
+ __esDecorate(_classThis, null, _metadata_offset_decorators, { kind: "accessor", name: "metadata_offset", static: false, private: false, access: { has: obj => "metadata_offset" in obj, get: obj => obj.metadata_offset, set: (obj, value) => { obj.metadata_offset = value; } }, metadata: _metadata }, _metadata_offset_initializers, _metadata_offset_extraInitializers);
564
+ __esDecorate(_classThis, null, _label_decorators, { kind: "accessor", name: "label", static: false, private: false, access: { has: obj => "label" in obj, get: obj => obj.label, set: (obj, value) => { obj.label = value; } }, metadata: _metadata }, _label_initializers, _label_extraInitializers);
565
+ __esDecorate(_classThis, null, __padding_decorators, { kind: "accessor", name: "_padding", static: false, private: false, access: { has: obj => "_padding" in obj, get: obj => obj._padding, set: (obj, value) => { obj._padding = value; } }, metadata: _metadata }, __padding_initializers, __padding_extraInitializers);
352
566
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
353
567
  SuperBlock = _classThis = _classDescriptor.value;
354
568
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -356,117 +570,150 @@ let SuperBlock = (() => {
356
570
  })();
357
571
  return SuperBlock = _classThis;
358
572
  })();
359
- function checksumMatches(value) {
360
- const buffer = serialize(value);
361
- const computed = crc32c(buffer.subarray(4)); // note we don't include the checksum when computing a new one.
362
- return value.checksum === computed;
573
+ export { SuperBlock };
574
+ /**
575
+ * Compute the checksum for a super block or metadata block.
576
+ * Note we don't include the checksum when computing a new one.
577
+ */
578
+ function checksum(value) {
579
+ return crc32c(new Uint8Array(value.buffer, value.byteOffset + 4, sizeof(value) - 4));
580
+ }
581
+ /**
582
+ * Update a block's checksum and timestamp.
583
+ * @internal @hidden
584
+ */
585
+ function _update(value) {
586
+ if (value instanceof MetadataBlock)
587
+ value.timestamp = BigInt(Date.now());
588
+ value.checksum = checksum(value);
363
589
  }
364
590
  /**
365
591
  *
366
592
  * @category Stores and Transactions
367
593
  */
368
- export class SingleBufferStore {
369
- constructor(buffer) {
594
+ export class SingleBufferStore extends BufferView {
595
+ get uuid() {
596
+ return decodeUUID(this.superblock.uuid);
597
+ }
598
+ constructor(...args) {
599
+ super(...args);
370
600
  this.flags = [];
371
601
  this.name = 'sbfs';
372
- this.id = 0x73626673; // 'sbfs'
373
- if (buffer.byteLength < sizeof(SuperBlock) + sizeof(MetadataBlock))
374
- throw crit(new ErrnoError(Errno.EINVAL, 'SingleBuffer: Buffer is too small for a file system'));
375
- this._view = !ArrayBuffer.isView(buffer) ? new DataView(buffer) : new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
376
- this._buffer = !ArrayBuffer.isView(buffer) ? new Uint8Array(buffer) : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
377
- this.superblock = new SuperBlock(this);
602
+ this.type = 0x73626673; // 'sbfs'
603
+ if (this.byteLength < sizeof(SuperBlock) + sizeof(MetadataBlock))
604
+ throw crit(withErrno('EINVAL', 'sbfs: Buffer is too small for a file system'));
605
+ this._view = new DataView(this.buffer, this.byteOffset, this.byteLength);
606
+ this._u8 = new Uint8Array(this.buffer, this.byteOffset, this.byteLength);
607
+ this.superblock = new SuperBlock(this.buffer, this.byteOffset);
378
608
  }
379
- /**
380
- * Update a block's checksum and write it to the store's buffer.
381
- * @internal @hidden
382
- */
383
- _write(value) {
384
- value.checksum = crc32c(serialize(value).subarray(4));
385
- const offset = 'offset' in value ? value.offset : 0;
386
- this._buffer.set(serialize(value), offset);
387
- }
388
- keys() {
609
+ *keys() {
389
610
  const keys = new Set();
390
611
  for (let block = this.superblock.metadata; block; block = block.previous) {
391
- for (const entry of block.entries)
392
- if (entry.offset)
393
- keys.add(entry.id);
612
+ block.waitUnlocked();
613
+ for (const entry of block.items) {
614
+ if (!entry.offset || keys.has(entry.id))
615
+ continue;
616
+ keys.add(entry.id);
617
+ yield entry.id;
618
+ }
394
619
  }
395
- return keys;
396
620
  }
397
621
  get(id) {
398
622
  for (let block = this.superblock.metadata; block; block = block.previous) {
399
- for (const entry of block.entries) {
400
- if (entry.offset && entry.id == id) {
401
- return this._buffer.subarray(entry.offset, entry.offset + entry.size);
402
- }
623
+ block.waitUnlocked();
624
+ for (const entry of block.items) {
625
+ if (!entry.offset || entry.id != id)
626
+ continue;
627
+ const off = this.byteOffset + entry.offset;
628
+ return new Uint8Array(this.buffer.slice(off, off + entry.size));
403
629
  }
404
630
  }
405
631
  }
406
632
  set(id, data) {
407
- for (let block = this.superblock.metadata; block; block = block.previous) {
408
- for (const entry of block.entries) {
409
- if (!entry.offset || entry.id != id)
410
- continue;
411
- if (data.length <= entry.size) {
412
- this._buffer.set(data, entry.offset);
413
- if (data.length < entry.size) {
633
+ const env_1 = { stack: [], error: void 0, hasError: false };
634
+ try {
635
+ if (id === 0 && data.length < sizeof(Inode))
636
+ throw alert(withErrno('EIO', `sbfs: tried to set ${data.length} bytes for id 0!`));
637
+ for (let block = this.superblock.metadata; block; block = block.previous) {
638
+ block.waitUnlocked();
639
+ for (const entry of block.items) {
640
+ const env_2 = { stack: [], error: void 0, hasError: false };
641
+ try {
642
+ if (!entry.offset || entry.id != id)
643
+ continue;
644
+ const lock = __addDisposableResource(env_2, block.lock(), false);
645
+ if (data.length == entry.size) {
646
+ this._u8.set(data, entry.offset);
647
+ return;
648
+ }
649
+ if (data.length < entry.size || this.superblock.isUnused(entry.offset, data.length)) {
650
+ this._u8.set(data, entry.offset);
651
+ entry.size = data.length;
652
+ _update(block);
653
+ return;
654
+ }
655
+ entry.offset = Number(this.superblock.used_bytes);
414
656
  entry.size = data.length;
415
- this._write(block);
657
+ this._u8.set(data, entry.offset);
658
+ _update(block);
659
+ this.superblock.used_bytes += BigInt(data.length);
660
+ _update(this.superblock);
661
+ return;
416
662
  }
417
- return;
418
- }
419
- if (this.superblock.isUnused(entry.offset, data.length)) {
420
- entry.size = data.length;
421
- this._buffer.set(data, entry.offset);
422
- this._write(block);
423
- return;
424
- }
425
- const used_bytes = Number(this.superblock.used_bytes);
426
- for (let block = this.superblock.metadata; block; block = block.previous) {
427
- for (const entry of block.entries) {
428
- if (entry.offset != used_bytes)
429
- continue;
430
- entry.offset += data.length;
431
- this._write(block);
432
- break;
663
+ catch (e_1) {
664
+ env_2.error = e_1;
665
+ env_2.hasError = true;
666
+ }
667
+ finally {
668
+ __disposeResources(env_2);
433
669
  }
434
670
  }
435
- entry.offset = used_bytes;
436
- entry.size = data.length;
437
- this._buffer.set(data, entry.offset);
438
- this._write(block);
439
- this.superblock.used_bytes += BigInt(data.length);
440
- this._write(this.superblock);
441
- return;
442
671
  }
672
+ let entry = Array.from(this.superblock.metadata.items).find(e => !e.offset);
673
+ if (!entry) {
674
+ this.superblock.rotateMetadata();
675
+ entry = this.superblock.metadata.items[0];
676
+ }
677
+ const lock = __addDisposableResource(env_1, this.superblock.metadata.lock(), false);
678
+ const offset = Number(this.superblock.used_bytes);
679
+ entry.id = id;
680
+ entry.offset = offset;
681
+ entry.size = data.length;
682
+ this._u8.set(data, offset);
683
+ this.superblock.used_bytes += BigInt(data.length);
684
+ _update(this.superblock.metadata);
685
+ _update(this.superblock);
686
+ }
687
+ catch (e_2) {
688
+ env_1.error = e_2;
689
+ env_1.hasError = true;
443
690
  }
444
- let entry = this.superblock.metadata.entries.find(e => !e.offset);
445
- if (!entry) {
446
- this.superblock.rotateMetadata();
447
- entry = this.superblock.metadata.entries[0];
691
+ finally {
692
+ __disposeResources(env_1);
448
693
  }
449
- const offset = Number(this.superblock.used_bytes);
450
- entry.id = id;
451
- entry.offset = offset;
452
- entry.size = data.length;
453
- this._buffer.set(data, offset);
454
- this.superblock.used_bytes += BigInt(data.length);
455
- this._write(this.superblock.metadata);
456
- this._write(this.superblock);
457
694
  }
458
695
  delete(id) {
459
696
  for (let block = this.superblock.metadata; block; block = block.previous) {
460
- for (const entry of block.entries) {
697
+ block.waitUnlocked();
698
+ for (const entry of block.items) {
461
699
  if (entry.id != id)
462
700
  continue;
463
701
  entry.offset = 0;
464
702
  entry.size = 0;
465
- this._write(block);
703
+ entry.id = 0;
704
+ _update(block);
466
705
  return;
467
706
  }
468
707
  }
469
708
  }
709
+ get fs() {
710
+ return this._fs;
711
+ }
712
+ set fs(fs) {
713
+ if (this.buffer instanceof SharedArrayBuffer)
714
+ fs === null || fs === void 0 ? void 0 : fs.attributes.set('no_id_tables', true);
715
+ this._fs = fs;
716
+ }
470
717
  sync() {
471
718
  return Promise.resolve();
472
719
  }
@@ -485,8 +732,10 @@ const _SingleBuffer = {
485
732
  options: {
486
733
  buffer: { type: 'object', required: true },
487
734
  },
488
- create({ buffer }) {
489
- const fs = new StoreFS(new SingleBufferStore(buffer));
735
+ create(opt) {
736
+ const fs = new StoreFS(ArrayBuffer.isView(opt.buffer)
737
+ ? new SingleBufferStore(opt.buffer.buffer, opt.buffer.byteOffset, opt.buffer.byteLength)
738
+ : new SingleBufferStore(opt.buffer));
490
739
  fs.checkRootSync();
491
740
  return fs;
492
741
  },