@archildata/client 0.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.
- package/README.md +126 -0
- package/archil-node.darwin-arm64.node +0 -0
- package/archildata-client.darwin-arm64.node +0 -0
- package/archildata-client.linux-arm64-gnu.node +0 -0
- package/archildata-client.linux-x64-gnu.node +0 -0
- package/index.d.ts +332 -0
- package/index.js +317 -0
- package/package.json +58 -0
package/README.md
ADDED
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# @archil/node
|
|
2
|
+
|
|
3
|
+
High-performance Node.js bindings for the Archil distributed filesystem client.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
This package provides low-level N-API bindings to the Archil client library, exposing the `ArchilService` trait methods directly to JavaScript/TypeScript. It's designed for use cases where you need direct protocol access without FUSE overhead.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @archil/node
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { ArchilClient } from '@archil/node';
|
|
19
|
+
|
|
20
|
+
// Connect to Archil (authenticated via mount server)
|
|
21
|
+
const client = await ArchilClient.connectAuthenticated({
|
|
22
|
+
mountServer: 'https://mount.archil.io',
|
|
23
|
+
mountName: 'my-account/my-disk',
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
// Get root directory attributes
|
|
27
|
+
const rootAttrs = await client.getAttributes(1n);
|
|
28
|
+
console.log('Root size:', rootAttrs.size);
|
|
29
|
+
|
|
30
|
+
// List directory contents
|
|
31
|
+
const entries = await client.readDirectory(1n);
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
console.log(`${entry.name} (inode: ${entry.inodeId})`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// Read a file
|
|
37
|
+
const lookup = await client.lookupInode(1n, 'myfile.txt');
|
|
38
|
+
const data = await client.readInode(lookup.inodeId, 0n, 1024);
|
|
39
|
+
console.log('File content:', data.toString());
|
|
40
|
+
|
|
41
|
+
// Close when done
|
|
42
|
+
await client.close();
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## API
|
|
46
|
+
|
|
47
|
+
### `ArchilClient`
|
|
48
|
+
|
|
49
|
+
The main client class for interacting with Archil filesystems.
|
|
50
|
+
|
|
51
|
+
#### Connection Methods
|
|
52
|
+
|
|
53
|
+
- `connectDirect(config)` - Connect directly to a server (for testing)
|
|
54
|
+
- `connectAuthenticated(config)` - Connect via mount server with authentication
|
|
55
|
+
|
|
56
|
+
#### Metadata Operations
|
|
57
|
+
|
|
58
|
+
- `getAttributes(inodeId, user?)` - Get inode attributes
|
|
59
|
+
- `lookupInode(parentInodeId, name, user?)` - Lookup entry by name
|
|
60
|
+
- `readDirectory(inodeId, offset?, cookie?, user?)` - List directory entries
|
|
61
|
+
- `getExtendedAttribute(inodeId, name, user?)` - Get xattr value
|
|
62
|
+
- `listExtendedAttributes(inodeId, user?)` - List xattr names
|
|
63
|
+
|
|
64
|
+
#### Data Operations
|
|
65
|
+
|
|
66
|
+
- `readInode(inodeId, offset, length, user?)` - Read file data
|
|
67
|
+
|
|
68
|
+
#### Delegation Operations
|
|
69
|
+
|
|
70
|
+
- `checkout(inodeId, force?, user?)` - Acquire write delegation
|
|
71
|
+
- `checkin(inodeId, user?)` - Release delegation
|
|
72
|
+
- `checkinAll()` - Release all delegations
|
|
73
|
+
|
|
74
|
+
#### Mutation Operations
|
|
75
|
+
|
|
76
|
+
- `conditionalCreate(parentInodeId, name, childInodeId, attributes, user?)` - Create file/directory
|
|
77
|
+
- `setImmutable(inodeId)` - Mark subtree as immutable
|
|
78
|
+
- `setMutable(inodeId)` - Mark subtree as mutable
|
|
79
|
+
- `listImmutableSubtrees()` - List immutable roots
|
|
80
|
+
|
|
81
|
+
### Types
|
|
82
|
+
|
|
83
|
+
All inode IDs and file offsets use JavaScript `bigint` for 64-bit support:
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
interface UnixUser {
|
|
87
|
+
uid: number;
|
|
88
|
+
gid: number;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
interface InodeAttributes {
|
|
92
|
+
inodeId: bigint;
|
|
93
|
+
inodeType: 'File' | 'Directory' | 'Symlink' | ...;
|
|
94
|
+
size: bigint;
|
|
95
|
+
uid: number;
|
|
96
|
+
gid: number;
|
|
97
|
+
mode: number;
|
|
98
|
+
nlink: number;
|
|
99
|
+
ctimeMs: number;
|
|
100
|
+
atimeMs: number;
|
|
101
|
+
mtimeMs: number;
|
|
102
|
+
btimeMs: number;
|
|
103
|
+
rdev?: bigint;
|
|
104
|
+
symlinkTarget?: string;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
interface DirectoryEntry {
|
|
108
|
+
name: string;
|
|
109
|
+
inodeId: bigint;
|
|
110
|
+
inodeType: string;
|
|
111
|
+
}
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Building
|
|
115
|
+
|
|
116
|
+
This package uses napi-rs for native bindings. To build from source:
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
cd rust-libs/archil-node
|
|
120
|
+
npm install
|
|
121
|
+
npm run build
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## License
|
|
125
|
+
|
|
126
|
+
Proprietary - Archil Inc.
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,332 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
|
|
4
|
+
/* auto-generated by NAPI-RS */
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Initialize the Rust logger to output to stderr.
|
|
8
|
+
*
|
|
9
|
+
* @param level - Log level: "trace", "debug", "info", "warn", or "error"
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```typescript
|
|
13
|
+
* import { initLogging } from '@archildata/client';
|
|
14
|
+
* initLogging('debug'); // Call once at startup
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare function initLogging(level?: string | undefined | null): void
|
|
18
|
+
/** Unix user context for permission checks */
|
|
19
|
+
export interface UnixUser {
|
|
20
|
+
uid: number
|
|
21
|
+
gid: number
|
|
22
|
+
}
|
|
23
|
+
/** Inode type enum exposed to JavaScript */
|
|
24
|
+
export const enum JsInodeType {
|
|
25
|
+
File = 'File',
|
|
26
|
+
Directory = 'Directory',
|
|
27
|
+
Symlink = 'Symlink',
|
|
28
|
+
BlockDevice = 'BlockDevice',
|
|
29
|
+
CharacterDevice = 'CharacterDevice',
|
|
30
|
+
Fifo = 'Fifo',
|
|
31
|
+
Socket = 'Socket'
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Inode attributes exposed to JavaScript
|
|
35
|
+
*
|
|
36
|
+
* Note: inode_id, size, and rdev use i64 which will be converted to/from
|
|
37
|
+
* JavaScript BigInt automatically by napi-rs when values exceed Number.MAX_SAFE_INTEGER.
|
|
38
|
+
*/
|
|
39
|
+
export interface InodeAttributes {
|
|
40
|
+
/** Inode ID (use BigInt in JS for values > 2^53) */
|
|
41
|
+
inodeId: number
|
|
42
|
+
/** Type of the inode (File, Directory, Symlink, etc.) */
|
|
43
|
+
inodeType: string
|
|
44
|
+
/** File size in bytes */
|
|
45
|
+
size: number
|
|
46
|
+
/** Owner user ID */
|
|
47
|
+
uid: number
|
|
48
|
+
/** Owner group ID */
|
|
49
|
+
gid: number
|
|
50
|
+
/** Unix permission mode */
|
|
51
|
+
mode: number
|
|
52
|
+
/** Number of hard links */
|
|
53
|
+
nlink: number
|
|
54
|
+
/** Change time (milliseconds since epoch) */
|
|
55
|
+
ctimeMs: number
|
|
56
|
+
/** Access time (milliseconds since epoch) */
|
|
57
|
+
atimeMs: number
|
|
58
|
+
/** Modification time (milliseconds since epoch) */
|
|
59
|
+
mtimeMs: number
|
|
60
|
+
/** Birth/creation time (milliseconds since epoch) */
|
|
61
|
+
btimeMs: number
|
|
62
|
+
/** Device ID for block/char devices */
|
|
63
|
+
rdev?: number
|
|
64
|
+
/** Symlink target if this is a symlink */
|
|
65
|
+
symlinkTarget?: string
|
|
66
|
+
}
|
|
67
|
+
/** Directory entry returned from readdir */
|
|
68
|
+
export interface DirectoryEntry {
|
|
69
|
+
/** Name of the entry */
|
|
70
|
+
name: string
|
|
71
|
+
/** Inode ID of the entry */
|
|
72
|
+
inodeId: number
|
|
73
|
+
/** Type of the entry (File, Directory, etc.) */
|
|
74
|
+
inodeType: string
|
|
75
|
+
}
|
|
76
|
+
/** Lookup response containing inode info */
|
|
77
|
+
export interface LookupResponse {
|
|
78
|
+
/** Inode ID of the found entry (-1 if not found) */
|
|
79
|
+
inodeId: number
|
|
80
|
+
/** Attributes of the found inode */
|
|
81
|
+
attributes: InodeAttributes
|
|
82
|
+
}
|
|
83
|
+
/** Connection configuration for direct server connections */
|
|
84
|
+
export interface DirectConnectionConfig {
|
|
85
|
+
/** Server address (e.g., "localhost:8080") */
|
|
86
|
+
serverAddress: string
|
|
87
|
+
/** File system ID (optional, will be determined by server if not provided) */
|
|
88
|
+
fileSystemId?: number
|
|
89
|
+
/** Log level for Rust logging (e.g., "debug", "info", "warn", "error", "trace") */
|
|
90
|
+
logLevel?: string
|
|
91
|
+
}
|
|
92
|
+
/** Connection configuration for authenticated connections via mount server */
|
|
93
|
+
export interface AuthenticatedConnectionConfig {
|
|
94
|
+
/** Mount server address */
|
|
95
|
+
mountServer: string
|
|
96
|
+
/** Disk name (e.g., "dsk-xxx" or "account/diskname") */
|
|
97
|
+
mountName: string
|
|
98
|
+
/** Optional auth token (uses IAM if not provided) */
|
|
99
|
+
authToken?: string
|
|
100
|
+
/** Optional STS region for IAM authentication */
|
|
101
|
+
stsRegion?: string
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Simplified connection configuration using just region and disk name.
|
|
105
|
+
*
|
|
106
|
+
* This mirrors the CLI's `archil mount` command interface.
|
|
107
|
+
*
|
|
108
|
+
* Example usage:
|
|
109
|
+
* ```javascript
|
|
110
|
+
* const client = await ArchilClient.connect({
|
|
111
|
+
* region: 'aws-us-east-1',
|
|
112
|
+
* diskName: 'myaccount/mydisk'
|
|
113
|
+
* });
|
|
114
|
+
* ```
|
|
115
|
+
*
|
|
116
|
+
* To enable debug logging:
|
|
117
|
+
* ```javascript
|
|
118
|
+
* const client = await ArchilClient.connect({
|
|
119
|
+
* region: 'aws-us-east-1',
|
|
120
|
+
* diskName: 'myaccount/mydisk',
|
|
121
|
+
* logLevel: 'debug' // Enables Rust debug logs to stderr
|
|
122
|
+
* });
|
|
123
|
+
* ```
|
|
124
|
+
*/
|
|
125
|
+
export interface SimpleConnectionConfig {
|
|
126
|
+
/** Region identifier (e.g., "aws-us-east-1", "gcp-us-central1") */
|
|
127
|
+
region: string
|
|
128
|
+
/** Disk name - either "account/diskname" format or "dsk-xxx" disk ID */
|
|
129
|
+
diskName: string
|
|
130
|
+
/** Optional auth token (uses IAM if not provided) */
|
|
131
|
+
authToken?: string
|
|
132
|
+
/** Optional STS region for IAM authentication (defaults to region from the region parameter) */
|
|
133
|
+
stsRegion?: string
|
|
134
|
+
/** Log level for Rust logging (e.g., "debug", "info", "warn", "error", "trace") */
|
|
135
|
+
logLevel?: string
|
|
136
|
+
}
|
|
137
|
+
/** Inode ID range returned from reserve_inodes */
|
|
138
|
+
export interface InodeRange {
|
|
139
|
+
/** Start of the reserved range (inclusive) */
|
|
140
|
+
start: number
|
|
141
|
+
/** End of the reserved range (exclusive) */
|
|
142
|
+
end: number
|
|
143
|
+
}
|
|
144
|
+
/** Delegation information for an inode */
|
|
145
|
+
export interface DelegationInfo {
|
|
146
|
+
/** Inode ID that the delegation is for */
|
|
147
|
+
inodeId: number
|
|
148
|
+
/** State of the delegation: "Active", "Pending", or "Removing" */
|
|
149
|
+
state: string
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Options for setattr operation
|
|
153
|
+
*
|
|
154
|
+
* All fields are optional - only provided fields will be updated.
|
|
155
|
+
* For atime/mtime: use timestamp in milliseconds, or -1 to set to current time.
|
|
156
|
+
*/
|
|
157
|
+
export interface SetAttrOptions {
|
|
158
|
+
/** New permission mode (e.g., 0o644) */
|
|
159
|
+
mode?: number
|
|
160
|
+
/** New owner user ID */
|
|
161
|
+
uid?: number
|
|
162
|
+
/** New owner group ID */
|
|
163
|
+
gid?: number
|
|
164
|
+
/** New file size (for truncate) */
|
|
165
|
+
size?: number
|
|
166
|
+
/** New access time in milliseconds since epoch (-1 for current time) */
|
|
167
|
+
atimeMs?: number
|
|
168
|
+
/** New modification time in milliseconds since epoch (-1 for current time) */
|
|
169
|
+
mtimeMs?: number
|
|
170
|
+
/** New change time in milliseconds since epoch */
|
|
171
|
+
ctimeMs?: number
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* ArchilClient provides low-level access to Archil filesystem operations.
|
|
175
|
+
*
|
|
176
|
+
* This client uses the headless client mode from archil-client-core to provide
|
|
177
|
+
* direct protocol access without FUSE mount infrastructure.
|
|
178
|
+
*/
|
|
179
|
+
export declare class ArchilClient {
|
|
180
|
+
/**
|
|
181
|
+
* Connect to an Archil server using a simplified configuration.
|
|
182
|
+
*
|
|
183
|
+
* This is the recommended way to connect and mirrors the CLI interface.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```typescript
|
|
187
|
+
* const client = await ArchilClient.connect({
|
|
188
|
+
* region: 'aws-us-east-1',
|
|
189
|
+
* diskName: 'myaccount/mydisk'
|
|
190
|
+
* });
|
|
191
|
+
* ```
|
|
192
|
+
*/
|
|
193
|
+
static connect(config: SimpleConnectionConfig): Promise<ArchilClient>
|
|
194
|
+
/**
|
|
195
|
+
* Connect to an Archil server using direct connection.
|
|
196
|
+
*
|
|
197
|
+
* This is primarily for testing or internal use.
|
|
198
|
+
*/
|
|
199
|
+
static connectDirect(config: DirectConnectionConfig): Promise<ArchilClient>
|
|
200
|
+
/**
|
|
201
|
+
* Close the client connection and release resources.
|
|
202
|
+
*
|
|
203
|
+
* This will sync all pending writes and release all delegations held by
|
|
204
|
+
* this client before closing. Returns the number of delegations that were released.
|
|
205
|
+
*/
|
|
206
|
+
close(): Promise<number>
|
|
207
|
+
/** Get attributes for an inode (uses cache). */
|
|
208
|
+
getAttributes(inodeId: number, user?: UnixUser | undefined | null): Promise<InodeAttributes>
|
|
209
|
+
/** Lookup an entry by name in a directory (uses cache). */
|
|
210
|
+
lookupInode(parentInodeId: number, name: string, user?: UnixUser | undefined | null): Promise<LookupResponse>
|
|
211
|
+
/**
|
|
212
|
+
* Read directory entries.
|
|
213
|
+
*
|
|
214
|
+
* Uses the cache layer via snapshot_and_synchronize_directory to ensure
|
|
215
|
+
* the dirent cache is properly populated. This ensures that subsequent
|
|
216
|
+
* lookup_inode calls can find the entries returned here.
|
|
217
|
+
*/
|
|
218
|
+
readDirectory(inodeId: number, offset?: number | undefined | null, cookie?: number | undefined | null, user?: UnixUser | undefined | null): Promise<Array<DirectoryEntry>>
|
|
219
|
+
/** Get an extended attribute value. */
|
|
220
|
+
getExtendedAttribute(inodeId: number, name: string, user?: UnixUser | undefined | null): Promise<Buffer | null>
|
|
221
|
+
/** List all extended attribute names. */
|
|
222
|
+
listExtendedAttributes(inodeId: number, user?: UnixUser | undefined | null): Promise<Array<string>>
|
|
223
|
+
/**
|
|
224
|
+
* Read data from a file (uses cache).
|
|
225
|
+
*
|
|
226
|
+
* Returns zero-copy Buffer when possible for optimal performance.
|
|
227
|
+
*/
|
|
228
|
+
readInode(inodeId: number, offset: number, length: number, user?: UnixUser | undefined | null): Promise<Buffer>
|
|
229
|
+
/**
|
|
230
|
+
* Checkout (acquire delegation for) an inode for writing.
|
|
231
|
+
*
|
|
232
|
+
* This tracks the delegation locally so that subsequent write operations
|
|
233
|
+
* can proceed without additional server round-trips for permission checks.
|
|
234
|
+
*/
|
|
235
|
+
checkout(inodeId: number, force?: boolean | undefined | null, user?: UnixUser | undefined | null): Promise<void>
|
|
236
|
+
/**
|
|
237
|
+
* Checkin (release delegation for) an inode.
|
|
238
|
+
*
|
|
239
|
+
* This syncs any pending writes and releases the local delegation tracking.
|
|
240
|
+
*/
|
|
241
|
+
checkin(inodeId: number, user?: UnixUser | undefined | null): Promise<void>
|
|
242
|
+
/** Release all delegations held by this client. */
|
|
243
|
+
checkinAll(): Promise<number>
|
|
244
|
+
/**
|
|
245
|
+
* Sync all pending writes to the server.
|
|
246
|
+
*
|
|
247
|
+
* This flushes all buffered writes through the transaction scheduler,
|
|
248
|
+
* ensuring data durability before the method returns.
|
|
249
|
+
*/
|
|
250
|
+
sync(): Promise<void>
|
|
251
|
+
/**
|
|
252
|
+
* Write data to a file.
|
|
253
|
+
*
|
|
254
|
+
* This performs a proper write operation using the transaction scheduler
|
|
255
|
+
* to batch and commit changes. Requires a delegation on the file
|
|
256
|
+
* (call checkout first).
|
|
257
|
+
*
|
|
258
|
+
* @example
|
|
259
|
+
* ```typescript
|
|
260
|
+
* // First checkout to get write delegation
|
|
261
|
+
* await client.checkout(inodeId, false, user);
|
|
262
|
+
* // Then write data
|
|
263
|
+
* await client.writeData(inodeId, 0n, Buffer.from('Hello World'), user);
|
|
264
|
+
* // Optionally checkin when done
|
|
265
|
+
* await client.checkin(inodeId, user);
|
|
266
|
+
* ```
|
|
267
|
+
*/
|
|
268
|
+
writeData(inodeId: number, offset: number, data: Buffer, user?: UnixUser | undefined | null): Promise<void>
|
|
269
|
+
/**
|
|
270
|
+
* Set attributes on an inode.
|
|
271
|
+
*
|
|
272
|
+
* Updates file metadata like mode, timestamps, size, etc.
|
|
273
|
+
* Requires a delegation on the inode (call checkout first).
|
|
274
|
+
*
|
|
275
|
+
* For atime_ms and mtime_ms, use -1 to set to current time.
|
|
276
|
+
*
|
|
277
|
+
* @example
|
|
278
|
+
* ```typescript
|
|
279
|
+
* // First checkout to get write delegation
|
|
280
|
+
* await client.checkout(inodeId, false, user);
|
|
281
|
+
* // Update timestamps (touch)
|
|
282
|
+
* await client.setattr(inodeId, { atimeMs: -1, mtimeMs: -1 }, user);
|
|
283
|
+
* // Or change mode
|
|
284
|
+
* await client.setattr(inodeId, { mode: 0o755 }, user);
|
|
285
|
+
* // Checkin when done
|
|
286
|
+
* await client.checkin(inodeId, user);
|
|
287
|
+
* ```
|
|
288
|
+
*/
|
|
289
|
+
setattr(inodeId: number, options: SetAttrOptions, user: UnixUser): Promise<InodeAttributes>
|
|
290
|
+
/**
|
|
291
|
+
* Unlink (delete) a file or empty directory.
|
|
292
|
+
*
|
|
293
|
+
* Removes the directory entry from the parent directory. Requires
|
|
294
|
+
* write permission on the parent directory.
|
|
295
|
+
*/
|
|
296
|
+
unlink(parentInodeId: number, name: string, user?: UnixUser | undefined | null): Promise<void>
|
|
297
|
+
/**
|
|
298
|
+
* Rename (move) a file or directory.
|
|
299
|
+
*
|
|
300
|
+
* Atomically moves an entry from one location to another. If the destination
|
|
301
|
+
* exists, it will be replaced. Requires write permission on both parent directories.
|
|
302
|
+
*
|
|
303
|
+
* @example
|
|
304
|
+
* ```typescript
|
|
305
|
+
* // Move a file
|
|
306
|
+
* await client.rename(srcParentInodeId, 'oldname.txt', destParentInodeId, 'newname.txt', user);
|
|
307
|
+
* ```
|
|
308
|
+
*/
|
|
309
|
+
rename(parentInodeId: number, name: string, newParentInodeId: number, newName: string, user?: UnixUser | undefined | null): Promise<void>
|
|
310
|
+
/**
|
|
311
|
+
* Create a new file or directory.
|
|
312
|
+
*
|
|
313
|
+
* Automatically chooses between unconditional create (if we have a delegation
|
|
314
|
+
* on the parent) and conditional create (if we need the server to issue a delegation).
|
|
315
|
+
*
|
|
316
|
+
* Returns the inode ID of the created file.
|
|
317
|
+
*/
|
|
318
|
+
create(parentInodeId: number, name: string, attributes: InodeAttributes, user?: UnixUser | undefined | null): Promise<number>
|
|
319
|
+
/** Mark an inode subtree as immutable. */
|
|
320
|
+
setImmutable(inodeId: number): Promise<void>
|
|
321
|
+
/** Mark an inode subtree as mutable (reverse of set_immutable). */
|
|
322
|
+
setMutable(inodeId: number): Promise<void>
|
|
323
|
+
/** List all immutable subtree root inodes. */
|
|
324
|
+
listImmutableSubtrees(): Promise<Array<number>>
|
|
325
|
+
/**
|
|
326
|
+
* List all delegations currently held by this client.
|
|
327
|
+
*
|
|
328
|
+
* Returns a list of delegation info objects containing the inode ID and state.
|
|
329
|
+
* State is one of: "Active", "Pending", "Removing"
|
|
330
|
+
*/
|
|
331
|
+
listDelegations(): Array<DelegationInfo>
|
|
332
|
+
}
|
package/index.js
ADDED
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
/* tslint:disable */
|
|
2
|
+
/* eslint-disable */
|
|
3
|
+
/* prettier-ignore */
|
|
4
|
+
|
|
5
|
+
/* auto-generated by NAPI-RS */
|
|
6
|
+
|
|
7
|
+
const { existsSync, readFileSync } = require('fs')
|
|
8
|
+
const { join } = require('path')
|
|
9
|
+
|
|
10
|
+
const { platform, arch } = process
|
|
11
|
+
|
|
12
|
+
let nativeBinding = null
|
|
13
|
+
let localFileExisted = false
|
|
14
|
+
let loadError = null
|
|
15
|
+
|
|
16
|
+
function isMusl() {
|
|
17
|
+
// For Node 10
|
|
18
|
+
if (!process.report || typeof process.report.getReport !== 'function') {
|
|
19
|
+
try {
|
|
20
|
+
const lddPath = require('child_process').execSync('which ldd').toString().trim()
|
|
21
|
+
return readFileSync(lddPath, 'utf8').includes('musl')
|
|
22
|
+
} catch (e) {
|
|
23
|
+
return true
|
|
24
|
+
}
|
|
25
|
+
} else {
|
|
26
|
+
const { glibcVersionRuntime } = process.report.getReport().header
|
|
27
|
+
return !glibcVersionRuntime
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
switch (platform) {
|
|
32
|
+
case 'android':
|
|
33
|
+
switch (arch) {
|
|
34
|
+
case 'arm64':
|
|
35
|
+
localFileExisted = existsSync(join(__dirname, 'archildata-client.android-arm64.node'))
|
|
36
|
+
try {
|
|
37
|
+
if (localFileExisted) {
|
|
38
|
+
nativeBinding = require('./archildata-client.android-arm64.node')
|
|
39
|
+
} else {
|
|
40
|
+
nativeBinding = require('@archildata/client-android-arm64')
|
|
41
|
+
}
|
|
42
|
+
} catch (e) {
|
|
43
|
+
loadError = e
|
|
44
|
+
}
|
|
45
|
+
break
|
|
46
|
+
case 'arm':
|
|
47
|
+
localFileExisted = existsSync(join(__dirname, 'archildata-client.android-arm-eabi.node'))
|
|
48
|
+
try {
|
|
49
|
+
if (localFileExisted) {
|
|
50
|
+
nativeBinding = require('./archildata-client.android-arm-eabi.node')
|
|
51
|
+
} else {
|
|
52
|
+
nativeBinding = require('@archildata/client-android-arm-eabi')
|
|
53
|
+
}
|
|
54
|
+
} catch (e) {
|
|
55
|
+
loadError = e
|
|
56
|
+
}
|
|
57
|
+
break
|
|
58
|
+
default:
|
|
59
|
+
throw new Error(`Unsupported architecture on Android ${arch}`)
|
|
60
|
+
}
|
|
61
|
+
break
|
|
62
|
+
case 'win32':
|
|
63
|
+
switch (arch) {
|
|
64
|
+
case 'x64':
|
|
65
|
+
localFileExisted = existsSync(
|
|
66
|
+
join(__dirname, 'archildata-client.win32-x64-msvc.node')
|
|
67
|
+
)
|
|
68
|
+
try {
|
|
69
|
+
if (localFileExisted) {
|
|
70
|
+
nativeBinding = require('./archildata-client.win32-x64-msvc.node')
|
|
71
|
+
} else {
|
|
72
|
+
nativeBinding = require('@archildata/client-win32-x64-msvc')
|
|
73
|
+
}
|
|
74
|
+
} catch (e) {
|
|
75
|
+
loadError = e
|
|
76
|
+
}
|
|
77
|
+
break
|
|
78
|
+
case 'ia32':
|
|
79
|
+
localFileExisted = existsSync(
|
|
80
|
+
join(__dirname, 'archildata-client.win32-ia32-msvc.node')
|
|
81
|
+
)
|
|
82
|
+
try {
|
|
83
|
+
if (localFileExisted) {
|
|
84
|
+
nativeBinding = require('./archildata-client.win32-ia32-msvc.node')
|
|
85
|
+
} else {
|
|
86
|
+
nativeBinding = require('@archildata/client-win32-ia32-msvc')
|
|
87
|
+
}
|
|
88
|
+
} catch (e) {
|
|
89
|
+
loadError = e
|
|
90
|
+
}
|
|
91
|
+
break
|
|
92
|
+
case 'arm64':
|
|
93
|
+
localFileExisted = existsSync(
|
|
94
|
+
join(__dirname, 'archildata-client.win32-arm64-msvc.node')
|
|
95
|
+
)
|
|
96
|
+
try {
|
|
97
|
+
if (localFileExisted) {
|
|
98
|
+
nativeBinding = require('./archildata-client.win32-arm64-msvc.node')
|
|
99
|
+
} else {
|
|
100
|
+
nativeBinding = require('@archildata/client-win32-arm64-msvc')
|
|
101
|
+
}
|
|
102
|
+
} catch (e) {
|
|
103
|
+
loadError = e
|
|
104
|
+
}
|
|
105
|
+
break
|
|
106
|
+
default:
|
|
107
|
+
throw new Error(`Unsupported architecture on Windows: ${arch}`)
|
|
108
|
+
}
|
|
109
|
+
break
|
|
110
|
+
case 'darwin':
|
|
111
|
+
localFileExisted = existsSync(join(__dirname, 'archildata-client.darwin-universal.node'))
|
|
112
|
+
try {
|
|
113
|
+
if (localFileExisted) {
|
|
114
|
+
nativeBinding = require('./archildata-client.darwin-universal.node')
|
|
115
|
+
} else {
|
|
116
|
+
nativeBinding = require('@archildata/client-darwin-universal')
|
|
117
|
+
}
|
|
118
|
+
break
|
|
119
|
+
} catch {}
|
|
120
|
+
switch (arch) {
|
|
121
|
+
case 'x64':
|
|
122
|
+
localFileExisted = existsSync(join(__dirname, 'archildata-client.darwin-x64.node'))
|
|
123
|
+
try {
|
|
124
|
+
if (localFileExisted) {
|
|
125
|
+
nativeBinding = require('./archildata-client.darwin-x64.node')
|
|
126
|
+
} else {
|
|
127
|
+
nativeBinding = require('@archildata/client-darwin-x64')
|
|
128
|
+
}
|
|
129
|
+
} catch (e) {
|
|
130
|
+
loadError = e
|
|
131
|
+
}
|
|
132
|
+
break
|
|
133
|
+
case 'arm64':
|
|
134
|
+
localFileExisted = existsSync(
|
|
135
|
+
join(__dirname, 'archildata-client.darwin-arm64.node')
|
|
136
|
+
)
|
|
137
|
+
try {
|
|
138
|
+
if (localFileExisted) {
|
|
139
|
+
nativeBinding = require('./archildata-client.darwin-arm64.node')
|
|
140
|
+
} else {
|
|
141
|
+
nativeBinding = require('@archildata/client-darwin-arm64')
|
|
142
|
+
}
|
|
143
|
+
} catch (e) {
|
|
144
|
+
loadError = e
|
|
145
|
+
}
|
|
146
|
+
break
|
|
147
|
+
default:
|
|
148
|
+
throw new Error(`Unsupported architecture on macOS: ${arch}`)
|
|
149
|
+
}
|
|
150
|
+
break
|
|
151
|
+
case 'freebsd':
|
|
152
|
+
if (arch !== 'x64') {
|
|
153
|
+
throw new Error(`Unsupported architecture on FreeBSD: ${arch}`)
|
|
154
|
+
}
|
|
155
|
+
localFileExisted = existsSync(join(__dirname, 'archildata-client.freebsd-x64.node'))
|
|
156
|
+
try {
|
|
157
|
+
if (localFileExisted) {
|
|
158
|
+
nativeBinding = require('./archildata-client.freebsd-x64.node')
|
|
159
|
+
} else {
|
|
160
|
+
nativeBinding = require('@archildata/client-freebsd-x64')
|
|
161
|
+
}
|
|
162
|
+
} catch (e) {
|
|
163
|
+
loadError = e
|
|
164
|
+
}
|
|
165
|
+
break
|
|
166
|
+
case 'linux':
|
|
167
|
+
switch (arch) {
|
|
168
|
+
case 'x64':
|
|
169
|
+
if (isMusl()) {
|
|
170
|
+
localFileExisted = existsSync(
|
|
171
|
+
join(__dirname, 'archildata-client.linux-x64-musl.node')
|
|
172
|
+
)
|
|
173
|
+
try {
|
|
174
|
+
if (localFileExisted) {
|
|
175
|
+
nativeBinding = require('./archildata-client.linux-x64-musl.node')
|
|
176
|
+
} else {
|
|
177
|
+
nativeBinding = require('@archildata/client-linux-x64-musl')
|
|
178
|
+
}
|
|
179
|
+
} catch (e) {
|
|
180
|
+
loadError = e
|
|
181
|
+
}
|
|
182
|
+
} else {
|
|
183
|
+
localFileExisted = existsSync(
|
|
184
|
+
join(__dirname, 'archildata-client.linux-x64-gnu.node')
|
|
185
|
+
)
|
|
186
|
+
try {
|
|
187
|
+
if (localFileExisted) {
|
|
188
|
+
nativeBinding = require('./archildata-client.linux-x64-gnu.node')
|
|
189
|
+
} else {
|
|
190
|
+
nativeBinding = require('@archildata/client-linux-x64-gnu')
|
|
191
|
+
}
|
|
192
|
+
} catch (e) {
|
|
193
|
+
loadError = e
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
break
|
|
197
|
+
case 'arm64':
|
|
198
|
+
if (isMusl()) {
|
|
199
|
+
localFileExisted = existsSync(
|
|
200
|
+
join(__dirname, 'archildata-client.linux-arm64-musl.node')
|
|
201
|
+
)
|
|
202
|
+
try {
|
|
203
|
+
if (localFileExisted) {
|
|
204
|
+
nativeBinding = require('./archildata-client.linux-arm64-musl.node')
|
|
205
|
+
} else {
|
|
206
|
+
nativeBinding = require('@archildata/client-linux-arm64-musl')
|
|
207
|
+
}
|
|
208
|
+
} catch (e) {
|
|
209
|
+
loadError = e
|
|
210
|
+
}
|
|
211
|
+
} else {
|
|
212
|
+
localFileExisted = existsSync(
|
|
213
|
+
join(__dirname, 'archildata-client.linux-arm64-gnu.node')
|
|
214
|
+
)
|
|
215
|
+
try {
|
|
216
|
+
if (localFileExisted) {
|
|
217
|
+
nativeBinding = require('./archildata-client.linux-arm64-gnu.node')
|
|
218
|
+
} else {
|
|
219
|
+
nativeBinding = require('@archildata/client-linux-arm64-gnu')
|
|
220
|
+
}
|
|
221
|
+
} catch (e) {
|
|
222
|
+
loadError = e
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
break
|
|
226
|
+
case 'arm':
|
|
227
|
+
if (isMusl()) {
|
|
228
|
+
localFileExisted = existsSync(
|
|
229
|
+
join(__dirname, 'archildata-client.linux-arm-musleabihf.node')
|
|
230
|
+
)
|
|
231
|
+
try {
|
|
232
|
+
if (localFileExisted) {
|
|
233
|
+
nativeBinding = require('./archildata-client.linux-arm-musleabihf.node')
|
|
234
|
+
} else {
|
|
235
|
+
nativeBinding = require('@archildata/client-linux-arm-musleabihf')
|
|
236
|
+
}
|
|
237
|
+
} catch (e) {
|
|
238
|
+
loadError = e
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
localFileExisted = existsSync(
|
|
242
|
+
join(__dirname, 'archildata-client.linux-arm-gnueabihf.node')
|
|
243
|
+
)
|
|
244
|
+
try {
|
|
245
|
+
if (localFileExisted) {
|
|
246
|
+
nativeBinding = require('./archildata-client.linux-arm-gnueabihf.node')
|
|
247
|
+
} else {
|
|
248
|
+
nativeBinding = require('@archildata/client-linux-arm-gnueabihf')
|
|
249
|
+
}
|
|
250
|
+
} catch (e) {
|
|
251
|
+
loadError = e
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
break
|
|
255
|
+
case 'riscv64':
|
|
256
|
+
if (isMusl()) {
|
|
257
|
+
localFileExisted = existsSync(
|
|
258
|
+
join(__dirname, 'archildata-client.linux-riscv64-musl.node')
|
|
259
|
+
)
|
|
260
|
+
try {
|
|
261
|
+
if (localFileExisted) {
|
|
262
|
+
nativeBinding = require('./archildata-client.linux-riscv64-musl.node')
|
|
263
|
+
} else {
|
|
264
|
+
nativeBinding = require('@archildata/client-linux-riscv64-musl')
|
|
265
|
+
}
|
|
266
|
+
} catch (e) {
|
|
267
|
+
loadError = e
|
|
268
|
+
}
|
|
269
|
+
} else {
|
|
270
|
+
localFileExisted = existsSync(
|
|
271
|
+
join(__dirname, 'archildata-client.linux-riscv64-gnu.node')
|
|
272
|
+
)
|
|
273
|
+
try {
|
|
274
|
+
if (localFileExisted) {
|
|
275
|
+
nativeBinding = require('./archildata-client.linux-riscv64-gnu.node')
|
|
276
|
+
} else {
|
|
277
|
+
nativeBinding = require('@archildata/client-linux-riscv64-gnu')
|
|
278
|
+
}
|
|
279
|
+
} catch (e) {
|
|
280
|
+
loadError = e
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
break
|
|
284
|
+
case 's390x':
|
|
285
|
+
localFileExisted = existsSync(
|
|
286
|
+
join(__dirname, 'archildata-client.linux-s390x-gnu.node')
|
|
287
|
+
)
|
|
288
|
+
try {
|
|
289
|
+
if (localFileExisted) {
|
|
290
|
+
nativeBinding = require('./archildata-client.linux-s390x-gnu.node')
|
|
291
|
+
} else {
|
|
292
|
+
nativeBinding = require('@archildata/client-linux-s390x-gnu')
|
|
293
|
+
}
|
|
294
|
+
} catch (e) {
|
|
295
|
+
loadError = e
|
|
296
|
+
}
|
|
297
|
+
break
|
|
298
|
+
default:
|
|
299
|
+
throw new Error(`Unsupported architecture on Linux: ${arch}`)
|
|
300
|
+
}
|
|
301
|
+
break
|
|
302
|
+
default:
|
|
303
|
+
throw new Error(`Unsupported OS: ${platform}, architecture: ${arch}`)
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (!nativeBinding) {
|
|
307
|
+
if (loadError) {
|
|
308
|
+
throw loadError
|
|
309
|
+
}
|
|
310
|
+
throw new Error(`Failed to load native binding`)
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
const { initLogging, ArchilClient, JsInodeType } = nativeBinding
|
|
314
|
+
|
|
315
|
+
module.exports.initLogging = initLogging
|
|
316
|
+
module.exports.ArchilClient = ArchilClient
|
|
317
|
+
module.exports.JsInodeType = JsInodeType
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@archildata/client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "High-performance Node.js client for Archil distributed filesystem",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"napi": {
|
|
8
|
+
"name": "archildata-client",
|
|
9
|
+
"triples": {
|
|
10
|
+
"defaults": true,
|
|
11
|
+
"additional": [
|
|
12
|
+
"aarch64-apple-darwin",
|
|
13
|
+
"aarch64-unknown-linux-gnu",
|
|
14
|
+
"x86_64-apple-darwin",
|
|
15
|
+
"x86_64-unknown-linux-gnu"
|
|
16
|
+
]
|
|
17
|
+
}
|
|
18
|
+
},
|
|
19
|
+
"license": "UNLICENSED",
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@napi-rs/cli": "^2.18.0"
|
|
22
|
+
},
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">= 18"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"artifacts": "napi artifacts",
|
|
28
|
+
"build": "napi build --platform --release",
|
|
29
|
+
"build:debug": "napi build --platform",
|
|
30
|
+
"prepublishOnly": "napi prepublish -t npm",
|
|
31
|
+
"test": "node --test test/*.js",
|
|
32
|
+
"universal": "napi universal",
|
|
33
|
+
"version": "napi version"
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"index.js",
|
|
37
|
+
"index.d.ts",
|
|
38
|
+
"*.node"
|
|
39
|
+
],
|
|
40
|
+
"repository": {
|
|
41
|
+
"type": "git",
|
|
42
|
+
"url": "https://github.com/archil-io/archil"
|
|
43
|
+
},
|
|
44
|
+
"keywords": [
|
|
45
|
+
"archil",
|
|
46
|
+
"filesystem",
|
|
47
|
+
"distributed",
|
|
48
|
+
"napi",
|
|
49
|
+
"native"
|
|
50
|
+
],
|
|
51
|
+
"optionalDependencies": {
|
|
52
|
+
"@archildata/client-win32-x64-msvc": "0.1.0",
|
|
53
|
+
"@archildata/client-darwin-x64": "0.1.0",
|
|
54
|
+
"@archildata/client-linux-x64-gnu": "0.1.0",
|
|
55
|
+
"@archildata/client-darwin-arm64": "0.1.0",
|
|
56
|
+
"@archildata/client-linux-arm64-gnu": "0.1.0"
|
|
57
|
+
}
|
|
58
|
+
}
|