@zenfs/core 1.2.2 → 1.2.3

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.
@@ -4,6 +4,7 @@ import { SyncTransaction, type Store } from './store.js';
4
4
  * An interface for simple synchronous stores that don't have special support for transactions and such.
5
5
  */
6
6
  export interface SimpleSyncStore extends Store {
7
+ keys(): Iterable<Ino>;
7
8
  get(ino: Ino): Uint8Array | undefined;
8
9
  set(ino: Ino, data: Uint8Array): void;
9
10
  delete(ino: Ino): void;
@@ -17,6 +18,7 @@ export declare abstract class SimpleAsyncStore implements SimpleSyncStore {
17
18
  protected cache: Map<Ino, Uint8Array>;
18
19
  protected queue: Set<Promise<unknown>>;
19
20
  protected abstract entries(): Promise<Iterable<[Ino, Uint8Array]>>;
21
+ keys(): Iterable<Ino>;
20
22
  get(ino: Ino): Uint8Array | undefined;
21
23
  set(ino: Ino, data: Uint8Array): void;
22
24
  protected abstract _set(ino: Ino, data: Uint8Array): Promise<void>;
@@ -43,6 +45,7 @@ export declare class SimpleTransaction extends SyncTransaction<SimpleSyncStore>
43
45
  */
44
46
  protected modifiedKeys: Set<Ino>;
45
47
  protected store: SimpleSyncStore;
48
+ keysSync(): Iterable<Ino>;
46
49
  getSync(ino: Ino): Uint8Array;
47
50
  setSync(ino: Ino, data: Uint8Array): void;
48
51
  removeSync(ino: Ino): void;
@@ -8,6 +8,9 @@ export class SimpleAsyncStore {
8
8
  this.cache = new Map();
9
9
  this.queue = new Set();
10
10
  }
11
+ keys() {
12
+ return this.cache.keys();
13
+ }
11
14
  get(ino) {
12
15
  return this.cache.get(ino);
13
16
  }
@@ -55,6 +58,9 @@ export class SimpleTransaction extends SyncTransaction {
55
58
  */
56
59
  this.modifiedKeys = new Set();
57
60
  }
61
+ keysSync() {
62
+ return this.store.keys();
63
+ }
58
64
  getSync(ino) {
59
65
  const val = this.store.get(ino);
60
66
  this.stashOldValue(ino, val);
@@ -32,9 +32,17 @@ export declare abstract class Transaction<T extends Store = Store> {
32
32
  protected store: T;
33
33
  constructor(store: T);
34
34
  /**
35
- * Whether the transaction was commited or aborted
35
+ * Whether the transaction was committed or aborted
36
36
  */
37
37
  protected done: boolean;
38
+ /**
39
+ * Gets all of the keys
40
+ */
41
+ abstract keys(): Promise<Iterable<Ino>>;
42
+ /**
43
+ * Gets all of the keys
44
+ */
45
+ abstract keysSync(): Iterable<Ino>;
38
46
  /**
39
47
  * Retrieves the data at `ino`.
40
48
  * @param ino The key to look under for data.
@@ -92,6 +100,7 @@ export declare abstract class Transaction<T extends Store = Store> {
92
100
  * Transaction that implements asynchronous operations with synchronous ones
93
101
  */
94
102
  export declare abstract class SyncTransaction<T extends Store = Store> extends Transaction<T> {
103
+ keys(): Promise<Iterable<Ino>>;
95
104
  get(ino: Ino): Promise<Uint8Array>;
96
105
  set(ino: bigint, data: Uint8Array): Promise<void>;
97
106
  remove(ino: Ino): Promise<void>;
@@ -102,9 +111,10 @@ export declare abstract class SyncTransaction<T extends Store = Store> extends T
102
111
  * Transaction that only supports asynchronous operations
103
112
  */
104
113
  export declare abstract class AsyncTransaction<T extends Store = Store> extends Transaction<T> {
105
- getSync(): Uint8Array;
106
- setSync(): void;
107
- removeSync(): void;
108
- commitSync(): void;
109
- abortSync(): void;
114
+ keysSync(): never;
115
+ getSync(): never;
116
+ setSync(): never;
117
+ removeSync(): never;
118
+ commitSync(): never;
119
+ abortSync(): never;
110
120
  }
@@ -7,7 +7,7 @@ export class Transaction {
7
7
  constructor(store) {
8
8
  this.store = store;
9
9
  /**
10
- * Whether the transaction was commited or aborted
10
+ * Whether the transaction was committed or aborted
11
11
  */
12
12
  this.done = false;
13
13
  }
@@ -29,6 +29,9 @@ export class Transaction {
29
29
  */
30
30
  export class SyncTransaction extends Transaction {
31
31
  /* eslint-disable @typescript-eslint/require-await */
32
+ async keys() {
33
+ return this.keysSync();
34
+ }
32
35
  async get(ino) {
33
36
  return this.getSync(ino);
34
37
  }
@@ -49,6 +52,9 @@ export class SyncTransaction extends Transaction {
49
52
  * Transaction that only supports asynchronous operations
50
53
  */
51
54
  export class AsyncTransaction extends Transaction {
55
+ keysSync() {
56
+ throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.keysSync');
57
+ }
52
58
  getSync() {
53
59
  throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.getSync');
54
60
  }
@@ -45,6 +45,7 @@ var __disposeResources = (this && this.__disposeResources) || (function (Suppres
45
45
  var e = new Error(message);
46
46
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
47
47
  });
48
+ import { StoreFS } from '../backends/store/fs.js';
48
49
  import { join } from '../emulation/path.js';
49
50
  import { Errno, ErrnoError } from '../error.js';
50
51
  import { parseFlag, PreloadFile } from '../file.js';
@@ -84,6 +85,18 @@ export function Async(FS) {
84
85
  }
85
86
  this.checkSync();
86
87
  await this._sync.ready();
88
+ // optimization: for 2 storeFS', we copy at a lower abstraction level.
89
+ if (this._sync instanceof StoreFS && this instanceof StoreFS) {
90
+ const sync = this._sync['store'].transaction();
91
+ const async = this['store'].transaction();
92
+ const promises = [];
93
+ for (const key of sync.keysSync()) {
94
+ promises.push(async.set(key, sync.getSync(key)));
95
+ }
96
+ await Promise.all(promises);
97
+ this._isInitialized = true;
98
+ return;
99
+ }
87
100
  try {
88
101
  await this.crossCopy('/');
89
102
  this._isInitialized = true;
@@ -187,10 +200,11 @@ export function Async(FS) {
187
200
  const stats = await this.stat(path);
188
201
  this._sync.mkdirSync(path, stats.mode);
189
202
  }
190
- const files = await this.readdir(path);
191
- for (const file of files) {
192
- await this.crossCopy(join(path, file));
203
+ const promises = [];
204
+ for (const file of await this.readdir(path)) {
205
+ promises.push(this.crossCopy(join(path, file)));
193
206
  }
207
+ await Promise.all(promises);
194
208
  }
195
209
  /**
196
210
  * @internal
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zenfs/core",
3
- "version": "1.2.2",
3
+ "version": "1.2.3",
4
4
  "description": "A filesystem, anywhere",
5
5
  "funding": {
6
6
  "type": "individual",
@@ -5,6 +5,7 @@ import { SyncTransaction, type Store } from './store.js';
5
5
  * An interface for simple synchronous stores that don't have special support for transactions and such.
6
6
  */
7
7
  export interface SimpleSyncStore extends Store {
8
+ keys(): Iterable<Ino>;
8
9
  get(ino: Ino): Uint8Array | undefined;
9
10
  set(ino: Ino, data: Uint8Array): void;
10
11
  delete(ino: Ino): void;
@@ -23,6 +24,10 @@ export abstract class SimpleAsyncStore implements SimpleSyncStore {
23
24
 
24
25
  protected abstract entries(): Promise<Iterable<[Ino, Uint8Array]>>;
25
26
 
27
+ public keys(): Iterable<Ino> {
28
+ return this.cache.keys();
29
+ }
30
+
26
31
  public get(ino: Ino): Uint8Array | undefined {
27
32
  return this.cache.get(ino);
28
33
  }
@@ -82,6 +87,10 @@ export class SimpleTransaction extends SyncTransaction<SimpleSyncStore> {
82
87
 
83
88
  protected declare store: SimpleSyncStore;
84
89
 
90
+ public keysSync(): Iterable<Ino> {
91
+ return this.store.keys();
92
+ }
93
+
85
94
  public getSync(ino: Ino): Uint8Array {
86
95
  const val = this.store.get(ino);
87
96
  this.stashOldValue(ino, val);
@@ -39,10 +39,20 @@ export abstract class Transaction<T extends Store = Store> {
39
39
  public constructor(protected store: T) {}
40
40
 
41
41
  /**
42
- * Whether the transaction was commited or aborted
42
+ * Whether the transaction was committed or aborted
43
43
  */
44
44
  protected done: boolean = false;
45
45
 
46
+ /**
47
+ * Gets all of the keys
48
+ */
49
+ public abstract keys(): Promise<Iterable<Ino>>;
50
+
51
+ /**
52
+ * Gets all of the keys
53
+ */
54
+ public abstract keysSync(): Iterable<Ino>;
55
+
46
56
  /**
47
57
  * Retrieves the data at `ino`.
48
58
  * @param ino The key to look under for data.
@@ -125,6 +135,9 @@ export abstract class Transaction<T extends Store = Store> {
125
135
  */
126
136
  export abstract class SyncTransaction<T extends Store = Store> extends Transaction<T> {
127
137
  /* eslint-disable @typescript-eslint/require-await */
138
+ public async keys(): Promise<Iterable<Ino>> {
139
+ return this.keysSync();
140
+ }
128
141
  public async get(ino: Ino): Promise<Uint8Array> {
129
142
  return this.getSync(ino);
130
143
  }
@@ -151,23 +164,27 @@ export abstract class SyncTransaction<T extends Store = Store> extends Transacti
151
164
  * Transaction that only supports asynchronous operations
152
165
  */
153
166
  export abstract class AsyncTransaction<T extends Store = Store> extends Transaction<T> {
154
- public getSync(): Uint8Array {
167
+ public keysSync(): never {
168
+ throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.keysSync');
169
+ }
170
+
171
+ public getSync(): never {
155
172
  throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.getSync');
156
173
  }
157
174
 
158
- public setSync(): void {
175
+ public setSync(): never {
159
176
  throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.setSync');
160
177
  }
161
178
 
162
- public removeSync(): void {
179
+ public removeSync(): never {
163
180
  throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.removeSync');
164
181
  }
165
182
 
166
- public commitSync(): void {
183
+ public commitSync(): never {
167
184
  throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.commitSync');
168
185
  }
169
186
 
170
- public abortSync(): void {
187
+ public abortSync(): never {
171
188
  throw ErrnoError.With('ENOSYS', undefined, 'AsyncTransaction.abortSync');
172
189
  }
173
190
  }
@@ -1,3 +1,5 @@
1
+ import { StoreFS } from '../backends/store/fs.js';
2
+ import type { Store } from '../backends/store/store.js';
1
3
  import { join } from '../emulation/path.js';
2
4
  import { Errno, ErrnoError } from '../error.js';
3
5
  import { parseFlag, PreloadFile, type File } from '../file.js';
@@ -72,6 +74,22 @@ export function Async<T extends typeof FileSystem>(
72
74
 
73
75
  await this._sync.ready();
74
76
 
77
+ // optimization: for 2 storeFS', we copy at a lower abstraction level.
78
+ if (this._sync instanceof StoreFS && this instanceof StoreFS) {
79
+ const sync = (this._sync as StoreFS<Store>)['store'].transaction();
80
+ const async = (this as StoreFS<Store>)['store'].transaction();
81
+
82
+ const promises = [];
83
+ for (const key of sync.keysSync()) {
84
+ promises.push(async.set(key, sync.getSync(key)));
85
+ }
86
+
87
+ await Promise.all(promises);
88
+
89
+ this._isInitialized = true;
90
+ return;
91
+ }
92
+
75
93
  try {
76
94
  await this.crossCopy('/');
77
95
  this._isInitialized = true;
@@ -175,10 +193,11 @@ export function Async<T extends typeof FileSystem>(
175
193
  const stats = await this.stat(path);
176
194
  this._sync.mkdirSync(path, stats.mode);
177
195
  }
178
- const files = await this.readdir(path);
179
- for (const file of files) {
180
- await this.crossCopy(join(path, file));
196
+ const promises = [];
197
+ for (const file of await this.readdir(path)) {
198
+ promises.push(this.crossCopy(join(path, file)));
181
199
  }
200
+ await Promise.all(promises);
182
201
  }
183
202
 
184
203
  /**