@zenfs/core 2.0.0 → 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 (87) hide show
  1. package/dist/backends/backend.js +6 -5
  2. package/dist/backends/cow.d.ts +2 -2
  3. package/dist/backends/cow.js +39 -58
  4. package/dist/backends/fetch.js +27 -29
  5. package/dist/backends/passthrough.d.ts +2 -3
  6. package/dist/backends/passthrough.js +84 -199
  7. package/dist/backends/port.d.ts +16 -3
  8. package/dist/backends/port.js +61 -30
  9. package/dist/backends/single_buffer.d.ts +52 -46
  10. package/dist/backends/single_buffer.js +462 -219
  11. package/dist/backends/store/fs.d.ts +16 -10
  12. package/dist/backends/store/fs.js +227 -242
  13. package/dist/backends/store/store.d.ts +3 -3
  14. package/dist/backends/store/store.js +11 -10
  15. package/dist/config.d.ts +2 -2
  16. package/dist/config.js +10 -11
  17. package/dist/internal/devices.d.ts +2 -2
  18. package/dist/internal/devices.js +39 -49
  19. package/dist/internal/error.d.ts +9 -204
  20. package/dist/internal/error.js +19 -288
  21. package/dist/internal/file_index.d.ts +1 -1
  22. package/dist/internal/file_index.js +9 -9
  23. package/dist/internal/filesystem.d.ts +23 -8
  24. package/dist/internal/index.d.ts +1 -1
  25. package/dist/internal/index.js +1 -1
  26. package/dist/internal/index_fs.d.ts +2 -2
  27. package/dist/internal/index_fs.js +19 -19
  28. package/dist/internal/inode.d.ts +81 -103
  29. package/dist/internal/inode.js +336 -195
  30. package/dist/mixins/async.js +32 -28
  31. package/dist/mixins/mutexed.d.ts +4 -4
  32. package/dist/mixins/mutexed.js +39 -39
  33. package/dist/mixins/readonly.d.ts +2 -2
  34. package/dist/mixins/readonly.js +20 -20
  35. package/dist/mixins/sync.js +2 -2
  36. package/dist/polyfills.js +1 -1
  37. package/dist/readline.js +1 -1
  38. package/dist/utils.d.ts +8 -5
  39. package/dist/utils.js +14 -17
  40. package/dist/vfs/acl.d.ts +8 -8
  41. package/dist/vfs/acl.js +66 -47
  42. package/dist/vfs/async.d.ts +2 -2
  43. package/dist/vfs/async.js +6 -8
  44. package/dist/vfs/dir.d.ts +1 -1
  45. package/dist/vfs/dir.js +3 -4
  46. package/dist/vfs/file.js +33 -24
  47. package/dist/vfs/flags.js +3 -3
  48. package/dist/vfs/ioctl.d.ts +8 -7
  49. package/dist/vfs/ioctl.js +132 -27
  50. package/dist/vfs/promises.d.ts +3 -3
  51. package/dist/vfs/promises.js +200 -235
  52. package/dist/vfs/shared.d.ts +1 -12
  53. package/dist/vfs/shared.js +7 -35
  54. package/dist/vfs/streams.js +9 -9
  55. package/dist/vfs/sync.d.ts +1 -2
  56. package/dist/vfs/sync.js +158 -170
  57. package/dist/vfs/watchers.js +8 -8
  58. package/dist/vfs/xattr.js +89 -106
  59. package/package.json +4 -2
  60. package/scripts/test.js +2 -2
  61. package/tests/assignment.ts +1 -1
  62. package/tests/backend/port.test.ts +4 -4
  63. package/tests/backend/single-buffer.test.ts +39 -10
  64. package/tests/backend/single-buffer.worker.js +30 -0
  65. package/tests/common/context.test.ts +2 -2
  66. package/tests/common/mutex.test.ts +9 -9
  67. package/tests/fetch/fetch.ts +1 -1
  68. package/tests/fs/append.test.ts +4 -4
  69. package/tests/fs/directory.test.ts +25 -25
  70. package/tests/fs/errors.test.ts +15 -19
  71. package/tests/fs/links.test.ts +3 -2
  72. package/tests/fs/open.test.ts +4 -21
  73. package/tests/fs/permissions.test.ts +8 -13
  74. package/tests/fs/read.test.ts +10 -9
  75. package/tests/fs/readFile.test.ts +8 -24
  76. package/tests/fs/rename.test.ts +4 -9
  77. package/tests/fs/stat.test.ts +2 -2
  78. package/tests/fs/times.test.ts +6 -6
  79. package/tests/fs/truncate.test.ts +8 -36
  80. package/tests/fs/watch.test.ts +10 -10
  81. package/tests/fs/write.test.ts +77 -13
  82. package/tests/fs/xattr.test.ts +7 -7
  83. package/tests/logs.js +2 -2
  84. package/tests/setup/port.ts +6 -0
  85. package/dist/internal/log.d.ts +0 -139
  86. package/dist/internal/log.js +0 -219
  87. package/tests/fs/writeFile.test.ts +0 -70
@@ -32,24 +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 { _throw, 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';
46
- import { stringifyUUID } from '../utils.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
+ });
47
118
  let MetadataEntry = (() => {
119
+ var _MetadataEntry_id_accessor_storage, _MetadataEntry_offset__accessor_storage, _MetadataEntry_offset_accessor_storage, _MetadataEntry_size_accessor_storage;
48
120
  var _a, _b, _c, _d;
49
- let _classDecorators = [struct()];
121
+ let _classDecorators = [struct(packed)];
50
122
  let _classDescriptor;
51
123
  let _classExtraInitializers = [];
52
124
  let _classThis;
125
+ let _classSuper = BufferView;
53
126
  let _id_decorators;
54
127
  let _id_initializers = [];
55
128
  let _id_extraInitializers = [];
@@ -62,30 +135,47 @@ let MetadataEntry = (() => {
62
135
  let _size_decorators;
63
136
  let _size_initializers = [];
64
137
  let _size_extraInitializers = [];
65
- 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
+ }
66
154
  constructor() {
67
- /** Inode or data ID */
68
- this.id = __runInitializers(this, _id_initializers, 0);
69
- /** Reserved for 64-bit offset expansion */
70
- this.offset_ = (__runInitializers(this, _id_extraInitializers), __runInitializers(this, _offset__initializers, 0));
71
- /** Offset into the buffer the data is stored at. */
72
- this.offset = (__runInitializers(this, _offset__extraInitializers), __runInitializers(this, _offset_initializers, 0));
73
- /** The size of the data */
74
- 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)));
75
160
  __runInitializers(this, _size_extraInitializers);
76
161
  }
77
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();
78
167
  __setFunctionName(_classThis, "MetadataEntry");
79
168
  (() => {
80
- 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;
81
171
  _id_decorators = [(_a = t).uint32.bind(_a)];
82
172
  _offset__decorators = [(_b = t).uint32.bind(_b)];
83
173
  _offset_decorators = [(_c = t).uint32.bind(_c)];
84
174
  _size_decorators = [(_d = t).uint32.bind(_d)];
85
- __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);
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, _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);
88
- __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);
89
179
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
90
180
  MetadataEntry = _classThis = _classDescriptor.value;
91
181
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -97,80 +187,148 @@ let MetadataEntry = (() => {
97
187
  * Number of entries per block of metadata
98
188
  */
99
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;
100
194
  /**
101
195
  * A block of metadata for a single-buffer file system.
102
196
  * This metadata maps IDs (for inodes and data) to actual offsets in the buffer.
103
197
  * This is done since IDs are not guaranteed to be sequential.
104
198
  */
105
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;
106
201
  var _a, _b, _c, _d;
107
- let _classDecorators = [struct()];
202
+ let _classDecorators = [struct(packed)];
108
203
  let _classDescriptor;
109
204
  let _classExtraInitializers = [];
110
205
  let _classThis;
206
+ let _classSuper = Int32Array;
111
207
  let _checksum_decorators;
112
208
  let _checksum_initializers = [];
113
209
  let _checksum_extraInitializers = [];
114
210
  let _timestamp_decorators;
115
211
  let _timestamp_initializers = [];
116
212
  let _timestamp_extraInitializers = [];
117
- let _previous_offset__decorators;
118
- let _previous_offset__initializers = [];
119
- let _previous_offset__extraInitializers = [];
120
213
  let _previous_offset_decorators;
121
214
  let _previous_offset_initializers = [];
122
215
  let _previous_offset_extraInitializers = [];
123
- let _entries_decorators;
124
- let _entries_initializers = [];
125
- let _entries_extraInitializers = [];
126
- var MetadataBlock = _classThis = class {
127
- constructor(superblock = _throw(new ErrnoError(Errno.EINVAL, 'Metadata block must be initialized with a superblock')), offset = 0) {
128
- this.superblock = superblock;
129
- this.offset = offset;
130
- /**
131
- * The crc32c checksum for the metadata block.
132
- * @privateRemarks Keep this first!
133
- */
134
- this.checksum = __runInitializers(this, _checksum_initializers, 0);
135
- /** The (last) time this metadata block was updated */
136
- this.timestamp = (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _timestamp_initializers, Date.now()));
137
- /** Reserved for 64-bit offset expansion */
138
- this.previous_offset_ = (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _previous_offset__initializers, 0));
139
- /** Offset to the previous metadata block */
140
- this.previous_offset = (__runInitializers(this, _previous_offset__extraInitializers), __runInitializers(this, _previous_offset_initializers, 0));
141
- this._previous = __runInitializers(this, _previous_offset_extraInitializers);
142
- /** Metadata entries. */
143
- this.entries = __runInitializers(this, _entries_initializers, Array.from({ length: entries_per_block }, () => new MetadataEntry()));
144
- __runInitializers(this, _entries_extraInitializers);
145
- this.superblock = superblock;
146
- this.offset = offset;
147
- if (!offset)
148
- return; // fresh block
149
- deserialize(this, superblock.store._buffer.subarray(offset, offset + sizeof(MetadataBlock)));
150
- if (!checksumMatches(this))
151
- throw crit(new ErrnoError(Errno.EIO, 'SingleBuffer: Checksum mismatch for metadata block at 0x' + offset.toString(16)));
152
- }
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"); }
153
235
  get previous() {
154
236
  var _a;
155
237
  if (!this.previous_offset)
156
238
  return;
157
- (_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));
158
240
  return this._previous;
159
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
+ }
160
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();
161
318
  __setFunctionName(_classThis, "MetadataBlock");
162
319
  (() => {
163
- 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;
164
322
  _checksum_decorators = [(_a = t).uint32.bind(_a)];
165
- _timestamp_decorators = [(_b = t).uint32.bind(_b)];
166
- _previous_offset__decorators = [(_c = t).uint32.bind(_c)];
167
- _previous_offset_decorators = [(_d = t).uint32.bind(_d)];
168
- _entries_decorators = [member(MetadataEntry, entries_per_block)];
169
- __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);
170
- __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);
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, _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);
173
- __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);
174
332
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
175
333
  MetadataBlock = _classThis = _classDescriptor.value;
176
334
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -178,16 +336,19 @@ let MetadataBlock = (() => {
178
336
  })();
179
337
  return MetadataBlock = _classThis;
180
338
  })();
181
- const sb_magic = 0x7a2e7362; // 'z.sb'
339
+ export { MetadataBlock };
340
+ const sb_magic = 0x62732e7a; // 'z.sb'
182
341
  /**
183
342
  * The super block structure for a single-buffer file system
184
343
  */
185
344
  let SuperBlock = (() => {
186
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
187
- 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)];
188
348
  let _classDescriptor;
189
349
  let _classExtraInitializers = [];
190
350
  let _classThis;
351
+ let _classSuper = BufferView;
191
352
  let _checksum_decorators;
192
353
  let _checksum_initializers = [];
193
354
  let _checksum_extraInitializers = [];
@@ -227,60 +388,97 @@ let SuperBlock = (() => {
227
388
  let __padding_decorators;
228
389
  let __padding_initializers = [];
229
390
  let __padding_extraInitializers = [];
230
- var SuperBlock = _classThis = class {
231
- constructor(store = _throw(new ErrnoError(Errno.EINVAL, 'Super block must be initialized with a store'))) {
232
- this.store = store;
233
- /**
234
- * The crc32c checksum for the super block.
235
- * @privateRemarks Keep this first!
236
- */
237
- this.checksum = __runInitializers(this, _checksum_initializers, 0);
238
- /** Signature for the superblock. */
239
- this.magic = (__runInitializers(this, _checksum_extraInitializers), __runInitializers(this, _magic_initializers, sb_magic));
240
- /** The version of the on-disk format */
241
- this.version = (__runInitializers(this, _magic_extraInitializers), __runInitializers(this, _version_initializers, 1));
242
- /** Which format of `Inode` is used */
243
- this.inode_format = (__runInitializers(this, _version_extraInitializers), __runInitializers(this, _inode_format_initializers, _inode_version));
244
- /** Flags for the file system. Currently unused */
245
- this.flags = (__runInitializers(this, _inode_format_extraInitializers), __runInitializers(this, _flags_initializers, 0));
246
- /** The number of used bytes, including the super block and metadata */
247
- this.used_bytes = (__runInitializers(this, _flags_extraInitializers), __runInitializers(this, _used_bytes_initializers, BigInt(0)));
248
- /** The total size of the entire file system, including the super block and metadata */
249
- this.total_bytes = (__runInitializers(this, _used_bytes_extraInitializers), __runInitializers(this, _total_bytes_initializers, BigInt(0)));
250
- /** A UUID for this file system */
251
- this.uuid = (__runInitializers(this, _total_bytes_extraInitializers), __runInitializers(this, _uuid_initializers, BigInt(0)));
252
- /**
253
- * The size in bytes of a metadata block.
254
- * Not currently configurable.
255
- */
256
- this.metadata_block_size = (__runInitializers(this, _uuid_extraInitializers), __runInitializers(this, _metadata_block_size_initializers, sizeof(MetadataBlock)));
257
- /** Reserved for 64-bit offset expansion */
258
- this.metadata_offset_ = (__runInitializers(this, _metadata_block_size_extraInitializers), __runInitializers(this, _metadata_offset__initializers, 0));
259
- /** Offset of the current metadata block */
260
- 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)));
261
405
  this.metadata = __runInitializers(this, _metadata_offset_extraInitializers);
262
- /** An optional label for the file system */
263
- this.label = __runInitializers(this, _label_initializers, '');
264
- /** Padded to 256 bytes */
265
- 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)));
266
408
  __runInitializers(this, __padding_extraInitializers);
267
- this.store = store;
268
- if (store._view.getUint32(offsetof(SuperBlock, 'magic'), true) != sb_magic) {
269
- warn('SingleBuffer: Invalid magic value, assuming this is a fresh super block');
270
- this.metadata = new MetadataBlock(this);
271
- this.metadata.offset = sizeof(SuperBlock);
272
- this.metadata_offset = this.metadata.offset;
273
- this.used_bytes = BigInt(sizeof(SuperBlock) + sizeof(MetadataBlock));
274
- this.total_bytes = BigInt(store._buffer.byteLength);
275
- store._write(this);
276
- 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);
277
425
  return;
278
426
  }
279
- deserialize(this, store._buffer.subarray(0, sizeof(SuperBlock)));
280
- if (!checksumMatches(this))
281
- throw crit(new ErrnoError(Errno.EIO, 'SingleBuffer: Checksum mismatch for super block!'));
282
- 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'));
283
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"); }
284
482
  /**
285
483
  * Rotate out the current metadata block.
286
484
  * Allocates a new metadata block, moves the current one to backup,
@@ -288,14 +486,13 @@ let SuperBlock = (() => {
288
486
  * @returns the new metadata block
289
487
  */
290
488
  rotateMetadata() {
291
- const metadata = new MetadataBlock(this);
292
- metadata.offset = Number(this.used_bytes);
489
+ const metadata = new MetadataBlock(this.buffer, Number(this.used_bytes));
293
490
  metadata.previous_offset = this.metadata_offset;
294
491
  this.metadata = metadata;
295
- this.metadata_offset = metadata.offset;
296
- this.store._write(metadata);
492
+ this.metadata_offset = metadata.byteOffset;
493
+ _update(metadata);
297
494
  this.used_bytes += BigInt(sizeof(MetadataBlock));
298
- this.store._write(this);
495
+ _update(this);
299
496
  return metadata;
300
497
  }
301
498
  /**
@@ -308,9 +505,9 @@ let SuperBlock = (() => {
308
505
  if (offset + length > this.total_bytes || offset < sizeof(SuperBlock))
309
506
  return false;
310
507
  for (let block = this.metadata; block; block = block.previous) {
311
- if (offset < block.offset + sizeof(MetadataBlock) && offset + length > block.offset)
508
+ if (offset < block.byteOffset + sizeof(MetadataBlock) && offset + length > block.byteOffset)
312
509
  return false;
313
- for (const entry of block.entries) {
510
+ for (const entry of block.items) {
314
511
  if (!entry.offset)
315
512
  continue;
316
513
  if ((offset >= entry.offset && offset < entry.offset + entry.size)
@@ -323,9 +520,23 @@ let SuperBlock = (() => {
323
520
  return true;
324
521
  }
325
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();
326
536
  __setFunctionName(_classThis, "SuperBlock");
327
537
  (() => {
328
- 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;
329
540
  _checksum_decorators = [(_a = t).uint32.bind(_a)];
330
541
  _magic_decorators = [(_b = t).uint32.bind(_b)];
331
542
  _version_decorators = [(_c = t).uint16.bind(_c)];
@@ -333,25 +544,25 @@ let SuperBlock = (() => {
333
544
  _flags_decorators = [(_e = t).uint32.bind(_e)];
334
545
  _used_bytes_decorators = [(_f = t).uint64.bind(_f)];
335
546
  _total_bytes_decorators = [(_g = t).uint64.bind(_g)];
336
- _uuid_decorators = [(_h = t).uint128.bind(_h)];
337
- _metadata_block_size_decorators = [(_j = t).uint32.bind(_j)];
338
- _metadata_offset__decorators = [(_k = t).uint32.bind(_k)];
339
- _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)];
340
551
  _label_decorators = [t.char(64)];
341
552
  __padding_decorators = [t.char(132)];
342
- __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);
343
- __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);
344
- __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);
345
- __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);
346
- __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);
347
- __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);
348
- __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);
349
- __esDecorate(null, null, _uuid_decorators, { kind: "field", 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);
350
- __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);
351
- __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);
352
- __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);
353
- __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);
354
- __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);
355
566
  __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
356
567
  SuperBlock = _classThis = _classDescriptor.value;
357
568
  if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
@@ -359,120 +570,150 @@ let SuperBlock = (() => {
359
570
  })();
360
571
  return SuperBlock = _classThis;
361
572
  })();
362
- function checksumMatches(value) {
363
- const buffer = serialize(value);
364
- const computed = crc32c(buffer.subarray(4)); // note we don't include the checksum when computing a new one.
365
- 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);
366
589
  }
367
590
  /**
368
591
  *
369
592
  * @category Stores and Transactions
370
593
  */
371
- export class SingleBufferStore {
594
+ export class SingleBufferStore extends BufferView {
372
595
  get uuid() {
373
- return stringifyUUID(this.superblock.uuid);
596
+ return decodeUUID(this.superblock.uuid);
374
597
  }
375
- constructor(buffer) {
598
+ constructor(...args) {
599
+ super(...args);
376
600
  this.flags = [];
377
601
  this.name = 'sbfs';
378
602
  this.type = 0x73626673; // 'sbfs'
379
- if (buffer.byteLength < sizeof(SuperBlock) + sizeof(MetadataBlock))
380
- throw crit(new ErrnoError(Errno.EINVAL, 'SingleBuffer: Buffer is too small for a file system'));
381
- this._view = !ArrayBuffer.isView(buffer) ? new DataView(buffer) : new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);
382
- this._buffer = !ArrayBuffer.isView(buffer) ? new Uint8Array(buffer) : new Uint8Array(buffer.buffer, buffer.byteOffset, buffer.byteLength);
383
- this.superblock = new SuperBlock(this);
384
- }
385
- /**
386
- * Update a block's checksum and write it to the store's buffer.
387
- * @internal @hidden
388
- */
389
- _write(value) {
390
- value.checksum = crc32c(serialize(value).subarray(4));
391
- const offset = 'offset' in value ? value.offset : 0;
392
- this._buffer.set(serialize(value), offset);
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);
393
608
  }
394
- keys() {
609
+ *keys() {
395
610
  const keys = new Set();
396
611
  for (let block = this.superblock.metadata; block; block = block.previous) {
397
- for (const entry of block.entries)
398
- if (entry.offset)
399
- 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
+ }
400
619
  }
401
- return keys;
402
620
  }
403
621
  get(id) {
404
622
  for (let block = this.superblock.metadata; block; block = block.previous) {
405
- for (const entry of block.entries) {
406
- if (entry.offset && entry.id == id) {
407
- return this._buffer.subarray(entry.offset, entry.offset + entry.size);
408
- }
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));
409
629
  }
410
630
  }
411
631
  }
412
632
  set(id, data) {
413
- for (let block = this.superblock.metadata; block; block = block.previous) {
414
- for (const entry of block.entries) {
415
- if (!entry.offset || entry.id != id)
416
- continue;
417
- if (data.length <= entry.size) {
418
- this._buffer.set(data, entry.offset);
419
- 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);
420
656
  entry.size = data.length;
421
- 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;
422
662
  }
423
- return;
424
- }
425
- if (this.superblock.isUnused(entry.offset, data.length)) {
426
- entry.size = data.length;
427
- this._buffer.set(data, entry.offset);
428
- this._write(block);
429
- return;
430
- }
431
- const used_bytes = Number(this.superblock.used_bytes);
432
- for (let block = this.superblock.metadata; block; block = block.previous) {
433
- for (const entry of block.entries) {
434
- if (entry.offset != used_bytes)
435
- continue;
436
- entry.offset += data.length;
437
- this._write(block);
438
- break;
663
+ catch (e_1) {
664
+ env_2.error = e_1;
665
+ env_2.hasError = true;
666
+ }
667
+ finally {
668
+ __disposeResources(env_2);
439
669
  }
440
670
  }
441
- entry.offset = used_bytes;
442
- entry.size = data.length;
443
- this._buffer.set(data, entry.offset);
444
- this._write(block);
445
- this.superblock.used_bytes += BigInt(data.length);
446
- this._write(this.superblock);
447
- return;
448
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;
449
690
  }
450
- let entry = this.superblock.metadata.entries.find(e => !e.offset);
451
- if (!entry) {
452
- this.superblock.rotateMetadata();
453
- entry = this.superblock.metadata.entries[0];
691
+ finally {
692
+ __disposeResources(env_1);
454
693
  }
455
- const offset = Number(this.superblock.used_bytes);
456
- entry.id = id;
457
- entry.offset = offset;
458
- entry.size = data.length;
459
- this._buffer.set(data, offset);
460
- this.superblock.used_bytes += BigInt(data.length);
461
- this._write(this.superblock.metadata);
462
- this._write(this.superblock);
463
694
  }
464
695
  delete(id) {
465
696
  for (let block = this.superblock.metadata; block; block = block.previous) {
466
- for (const entry of block.entries) {
697
+ block.waitUnlocked();
698
+ for (const entry of block.items) {
467
699
  if (entry.id != id)
468
700
  continue;
469
701
  entry.offset = 0;
470
702
  entry.size = 0;
471
- this._write(block);
703
+ entry.id = 0;
704
+ _update(block);
472
705
  return;
473
706
  }
474
707
  }
475
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
+ }
476
717
  sync() {
477
718
  return Promise.resolve();
478
719
  }
@@ -491,8 +732,10 @@ const _SingleBuffer = {
491
732
  options: {
492
733
  buffer: { type: 'object', required: true },
493
734
  },
494
- create({ buffer }) {
495
- 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));
496
739
  fs.checkRootSync();
497
740
  return fs;
498
741
  },