alphatheta-connect 0.15.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 (77) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +166 -0
  3. package/lib/artwork/index.d.ts +9 -0
  4. package/lib/artwork/parsers/aiff.d.ts +2 -0
  5. package/lib/artwork/parsers/flac.d.ts +2 -0
  6. package/lib/artwork/parsers/id3.d.ts +2 -0
  7. package/lib/artwork/parsers/index.d.ts +5 -0
  8. package/lib/artwork/parsers/mp4.d.ts +2 -0
  9. package/lib/artwork/parsers/utils.d.ts +3 -0
  10. package/lib/artwork/reader.d.ts +15 -0
  11. package/lib/artwork/types.d.ts +44 -0
  12. package/lib/cli/index.d.ts +1 -0
  13. package/lib/cli.js +11431 -0
  14. package/lib/cli.js.map +1 -0
  15. package/lib/constants.d.ts +40 -0
  16. package/lib/control/index.d.ts +20 -0
  17. package/lib/db/getArtworkFromFile.d.ts +13 -0
  18. package/lib/db/getArtworkThumbnail.d.ts +29 -0
  19. package/lib/db/getFile.d.ts +29 -0
  20. package/lib/db/getMetadata.d.ts +28 -0
  21. package/lib/db/getPlaylist.d.ts +26 -0
  22. package/lib/db/getWaveforms.d.ts +29 -0
  23. package/lib/db/index.d.ts +70 -0
  24. package/lib/db/utils.d.ts +7 -0
  25. package/lib/devices/index.d.ts +66 -0
  26. package/lib/devices/utils.d.ts +5 -0
  27. package/lib/entities.d.ts +122 -0
  28. package/lib/index.d.ts +10 -0
  29. package/lib/index.js +13381 -0
  30. package/lib/index.js.map +1 -0
  31. package/lib/localdb/database-adapter.d.ts +49 -0
  32. package/lib/localdb/index.d.ts +104 -0
  33. package/lib/localdb/onelibrary-schema.d.ts +250 -0
  34. package/lib/localdb/onelibrary.d.ts +185 -0
  35. package/lib/localdb/orm.d.ts +60 -0
  36. package/lib/localdb/rekordbox.d.ts +112 -0
  37. package/lib/localdb/schema.d.ts +1 -0
  38. package/lib/localdb/utils.d.ts +5 -0
  39. package/lib/mixstatus/index.d.ts +109 -0
  40. package/lib/mixstatus/utils.d.ts +9 -0
  41. package/lib/network.d.ts +201 -0
  42. package/lib/nfs/index.d.ts +63 -0
  43. package/lib/nfs/programs.d.ts +61 -0
  44. package/lib/nfs/rpc.d.ts +60 -0
  45. package/lib/nfs/utils.d.ts +4 -0
  46. package/lib/nfs/xdr.d.ts +17 -0
  47. package/lib/passive/alphatheta.d.ts +94 -0
  48. package/lib/passive/devices.d.ts +64 -0
  49. package/lib/passive/index.d.ts +169 -0
  50. package/lib/passive/localdb.d.ts +122 -0
  51. package/lib/passive/pcap-adapter.d.ts +77 -0
  52. package/lib/passive/position.d.ts +32 -0
  53. package/lib/passive/remotedb.d.ts +49 -0
  54. package/lib/passive/status.d.ts +41 -0
  55. package/lib/remotedb/constants.d.ts +8 -0
  56. package/lib/remotedb/fields.d.ts +169 -0
  57. package/lib/remotedb/index.d.ts +160 -0
  58. package/lib/remotedb/message/index.d.ts +39 -0
  59. package/lib/remotedb/message/item.d.ts +530 -0
  60. package/lib/remotedb/message/response.d.ts +18 -0
  61. package/lib/remotedb/message/types.d.ts +227 -0
  62. package/lib/remotedb/queries.d.ts +99 -0
  63. package/lib/remotedb/utils.d.ts +23 -0
  64. package/lib/status/index.d.ts +39 -0
  65. package/lib/status/media.d.ts +22 -0
  66. package/lib/status/position.d.ts +29 -0
  67. package/lib/status/types.d.ts +170 -0
  68. package/lib/status/utils.d.ts +19 -0
  69. package/lib/types.d.ts +457 -0
  70. package/lib/types.js +274 -0
  71. package/lib/types.js.map +1 -0
  72. package/lib/utils/converters.d.ts +17 -0
  73. package/lib/utils/index.d.ts +28 -0
  74. package/lib/utils/telemetry.d.ts +82 -0
  75. package/lib/utils/udp.d.ts +20 -0
  76. package/lib/virtualcdj/index.d.ts +33 -0
  77. package/package.json +93 -0
@@ -0,0 +1,112 @@
1
+ import { Track } from "../entities";
2
+ import { MetadataORM } from "./orm";
3
+ import { BeatGrid, CueAndLoop, ExtendedCue, SongStructure, WaveformHD, WaveformPreviewData } from "../types";
4
+ import { TelemetrySpan as Span } from "../utils/telemetry";
5
+ /**
6
+ * The provided function should resolve ANLZ files into buffers. Typically
7
+ * you would just read the file, but in the case of the prolink network, this
8
+ * would handle loading the file over NFS.
9
+ */
10
+ type AnlzResolver = (path: string) => Promise<Buffer>;
11
+ /**
12
+ * Data returned from loading DAT anlz files
13
+ */
14
+ interface AnlzResponseDAT {
15
+ /**
16
+ * Embedded beat grid information
17
+ */
18
+ beatGrid: BeatGrid | null;
19
+ /**
20
+ * Embedded cue and loop information
21
+ */
22
+ cueAndLoops: CueAndLoop[] | null;
23
+ /**
24
+ * Standard waveform preview (400 bytes, PWAV tag)
25
+ */
26
+ waveformPreview: WaveformPreviewData | null;
27
+ /**
28
+ * Tiny waveform preview (100 bytes, PWV2 tag)
29
+ */
30
+ waveformTiny: WaveformPreviewData | null;
31
+ }
32
+ /**
33
+ * Data returned from loading EXT anlz files
34
+ */
35
+ interface AnlzResponseEXT {
36
+ /**
37
+ * HD Waveform information (PWV5 tag)
38
+ */
39
+ waveformHd: WaveformHD | null;
40
+ /**
41
+ * Extended cues with colors and comments (PCO2 tag)
42
+ */
43
+ extendedCues: ExtendedCue[] | null;
44
+ /**
45
+ * Song structure / phrase analysis (PSSI tag)
46
+ */
47
+ songStructure: SongStructure | null;
48
+ /**
49
+ * Monochrome detailed waveform (PWV3 tag)
50
+ */
51
+ waveformDetail: Uint8Array | null;
52
+ /**
53
+ * Color waveform preview (PWV4 tag, 7200 bytes = 1200 columns × 6 bytes)
54
+ */
55
+ waveformColorPreview: Uint8Array | null;
56
+ }
57
+ interface AnlzResponse {
58
+ DAT: AnlzResponseDAT;
59
+ EXT: AnlzResponseEXT;
60
+ }
61
+ /**
62
+ * Details about the current state of the hydtration task
63
+ */
64
+ export interface HydrationProgress {
65
+ /**
66
+ * The specific table that progress is being reported for
67
+ */
68
+ table: string;
69
+ /**
70
+ * The total progress steps for this table
71
+ */
72
+ total: number;
73
+ /**
74
+ * The completed number of progress steps
75
+ */
76
+ complete: number;
77
+ }
78
+ /**
79
+ * Options to hydrate the database
80
+ */
81
+ interface Options {
82
+ /**
83
+ * The metadata ORM of which the tables will be hydrated
84
+ */
85
+ orm: MetadataORM;
86
+ /**
87
+ * This buffer should contain the Rekordbox pdb file contents. It will be
88
+ * used to do the hydration
89
+ */
90
+ pdbData: Buffer;
91
+ /**
92
+ * Sentry tracing span for the parent transaction
93
+ */
94
+ span?: Span;
95
+ /**
96
+ * For larger music collections, it may take some time to load everything,
97
+ * especially when limited by IO. When hydration progresses this function
98
+ * will be called.
99
+ */
100
+ onProgress?: (progress: HydrationProgress) => void;
101
+ }
102
+ /**
103
+ * Given a rekordbox pdb file contents. This function will hydrate the provided
104
+ * database with all entities from the Rekordbox database. This includes all
105
+ * track metadata, including analyzed metadata (such as beatgrids and waveforms).
106
+ */
107
+ export declare function hydrateDatabase({ pdbData, span, ...options }: Options): Promise<void>;
108
+ /**
109
+ * Loads the ANLZ data of a Track entity from the analyzePath.
110
+ */
111
+ export declare function loadAnlz<T extends keyof AnlzResponse>(track: Track, type: T, anlzResolver: AnlzResolver): Promise<AnlzResponse[T]>;
112
+ export {};
@@ -0,0 +1 @@
1
+ export declare const generateSchema: () => string;
@@ -0,0 +1,5 @@
1
+ import { CueAndLoop, HotcueButton } from "../types";
2
+ /**
3
+ * Create a CueAndLoop entry given common parameters
4
+ */
5
+ export declare const makeCueLoopEntry: (isCue: boolean, isLoop: boolean, offset: number, length: number, button: false | HotcueButton) => null | CueAndLoop;
@@ -0,0 +1,109 @@
1
+ import StrictEventEmitter from 'strict-event-emitter-types';
2
+ import { EventEmitter } from 'events';
3
+ import { CDJStatus, DeviceID, MixstatusMode } from "../types";
4
+ export interface MixstatusConfig {
5
+ /**
6
+ * Selects the mixstatus reporting mode
7
+ */
8
+ mode: MixstatusMode;
9
+ /**
10
+ * Specifies the duration in seconds that no tracks must be on air. This can
11
+ * be thought of as how long 'air silence' is reasonable in a set before a
12
+ * separate one is considered have begun.
13
+ *
14
+ * @default 30 (half a minute)
15
+ */
16
+ timeBetweenSets: number;
17
+ /**
18
+ * Indicates if the status objects reported should have their on-air flag
19
+ * read. Setting this to false will degrade the functionality of the processor
20
+ * such that it will not consider the value of isOnAir and always assume CDJs
21
+ * are live.
22
+ *
23
+ * @default true
24
+ */
25
+ useOnAirStatus: boolean;
26
+ /**
27
+ * Configures how many beats a track may not be live or playing for it to
28
+ * still be considered active.
29
+ *
30
+ * @default 8 (two bars)
31
+ */
32
+ allowedInterruptBeats: number;
33
+ /**
34
+ * Configures how many beats the track must consecutively be playing for
35
+ * (since the beat it was cued at) until the track is considered to be
36
+ * active.
37
+ *
38
+ * Used for MixstatusMode.SmartTiming
39
+ *
40
+ * @default 128 (2 phrases)
41
+ */
42
+ beatsUntilReported: number;
43
+ }
44
+ /**
45
+ * The interface the mix status event emitter should follow
46
+ */
47
+ interface MixstatusEvents {
48
+ /**
49
+ * Fired when a track is considered to be on-air and is being heard by the
50
+ * audience
51
+ */
52
+ nowPlaying: (state: CDJStatus.State) => void;
53
+ /**
54
+ * Fired when a track has stopped and is completely offair
55
+ */
56
+ stopped: (opt: {
57
+ deviceId: DeviceID;
58
+ }) => void;
59
+ /**
60
+ * Fired when a DJ set first starts
61
+ */
62
+ setStarted: () => void;
63
+ /**
64
+ * Fired when tracks have been stopped
65
+ */
66
+ setEnded: () => void;
67
+ }
68
+ type Emitter = StrictEventEmitter<EventEmitter, MixstatusEvents>;
69
+ /**
70
+ * MixstatusProcessor is a configurable processor which when fed device state
71
+ * will attempt to accurately determine events that happen within the DJ set.
72
+ *
73
+ * The following events are fired:
74
+ *
75
+ * - nowPlaying: The track is considered playing and on air to the audience.
76
+ * - stopped: The track was stopped / paused / went off-air.
77
+ *
78
+ * Additionally the following non-track status are reported:
79
+ *
80
+ * - setStarted: The first track has begun playing.
81
+ * - setEnded: The TimeBetweenSets has passed since any tracks were live.
82
+ *
83
+ * See Config for configuration options.
84
+ *
85
+ * Config options may be changed after the processor has been created and is
86
+ * actively receiving state updates.
87
+ */
88
+ export declare class MixstatusProcessor {
89
+ #private;
90
+ constructor(config?: Partial<MixstatusConfig>);
91
+ /**
92
+ * Update the configuration
93
+ */
94
+ configure(config?: Partial<MixstatusConfig>): void;
95
+ on: Emitter['on'];
96
+ off: Emitter['off'];
97
+ once: Emitter['once'];
98
+ removeAllListeners: (event?: keyof MixstatusEvents) => EventEmitter<[never]>;
99
+ /**
100
+ * Feed a CDJStatus state object to the mix state processor
101
+ */
102
+ handleState(state: CDJStatus.State): void;
103
+ /**
104
+ * Manually reports the track that has been playing the longest which has not
105
+ * yet been reported as live.
106
+ */
107
+ triggerNextTrack(): void;
108
+ }
109
+ export {};
@@ -0,0 +1,9 @@
1
+ import { CDJStatus } from "../types";
2
+ /**
3
+ * Returns true if the the status reports a playing state.
4
+ */
5
+ export declare const isPlaying: (s: CDJStatus.State) => boolean;
6
+ /**
7
+ * Returns true if the status reports a stopping state.
8
+ */
9
+ export declare const isStopping: (s: CDJStatus.State) => boolean;
@@ -0,0 +1,201 @@
1
+ import { Socket } from 'dgram';
2
+ import { NetworkInterfaceInfoIPv4 } from 'os';
3
+ import Control from "./control";
4
+ import Database from "./db";
5
+ import DeviceManager from "./devices";
6
+ import LocalDatabase from "./localdb";
7
+ import { DatabasePreference } from "./localdb/database-adapter";
8
+ import { MixstatusProcessor } from "./mixstatus";
9
+ import RemoteDatabase from "./remotedb";
10
+ import StatusEmitter from "./status";
11
+ import PositionEmitter from "./status/position";
12
+ import { NetworkState } from "./types";
13
+ export interface NetworkConfig {
14
+ /**
15
+ * The network interface to listen for devices on the network over
16
+ */
17
+ iface: NetworkInterfaceInfoIPv4;
18
+ /**
19
+ * The ID of the virtual CDJ to pose as.
20
+ *
21
+ * IMPORTANT:
22
+ *
23
+ * You will likely want to configure this to be > 6, however it is important to
24
+ * note, if you choose an ID within the 1-6 range, no other CDJ may exist on the
25
+ * network using that ID. you CAN NOT have 6 CDJs if you're using one of their slots.
26
+ *
27
+ * However, should you want to make metadata queries to a unanalized media
28
+ * device connected to the CDJ, or metadata queries for CD disc data, you MUST
29
+ * use a ID within the 1-6 range, as the CDJs will not respond to metadata
30
+ * requests outside of the range of 1-6
31
+ *
32
+ * Note that rekordbox analyzed media connected to the CDJ is accessed out of
33
+ * band of the networks remote database protocol, and is not limited by this
34
+ * restriction.
35
+ */
36
+ vcdjId: number;
37
+ /**
38
+ * The name to announce the virtual CDJ as on the network.
39
+ *
40
+ * This name will appear in device lists on other Pro DJ Link equipment.
41
+ *
42
+ * @default 'ProLink-Connect'
43
+ */
44
+ vcdjName?: string;
45
+ /**
46
+ * Enable full startup protocol for robust device negotiation.
47
+ * When enabled, the virtual CDJ will go through the complete startup
48
+ * sequence (stages 0x0a → 0x00 → 0x02 → 0x04 → 0x06) before regular
49
+ * keep-alive announcements.
50
+ *
51
+ * This is recommended for production setups with CDJ-3000 and DJM-V10
52
+ * hardware to ensure proper device discovery and network stability.
53
+ */
54
+ fullStartup?: boolean;
55
+ /**
56
+ * Database format preference for loading rekordbox databases.
57
+ *
58
+ * - 'auto': Try OneLibrary first (rekordbox 7.x+), fall back to PDB (rekordbox 6.x)
59
+ * - 'oneLibrary': Only use OneLibrary format (exportLibrary.db)
60
+ * - 'pdb': Only use PDB format (export.pdb)
61
+ *
62
+ * @default 'auto'
63
+ */
64
+ databasePreference?: DatabasePreference;
65
+ }
66
+ interface ConstructOpts {
67
+ config?: NetworkConfig;
68
+ announceSocket: Socket;
69
+ beatSocket: Socket;
70
+ statusSocket: Socket;
71
+ deviceManager: DeviceManager;
72
+ statusEmitter: StatusEmitter;
73
+ positionEmitter: PositionEmitter;
74
+ }
75
+ /**
76
+ * Services that are not accessible until connected
77
+ */
78
+ type ConnectedServices = 'statusEmitter' | 'positionEmitter' | 'control' | 'db' | 'localdb' | 'remotedb' | 'mixstatus';
79
+ export type ConnectedProlinkNetwork = ProlinkNetwork & {
80
+ [P in ConnectedServices]: NonNullable<ProlinkNetwork[P]>;
81
+ } & {
82
+ state: NetworkState.Connected;
83
+ isConfigured: true;
84
+ };
85
+ /**
86
+ * Brings the Prolink network online.
87
+ *
88
+ * This is the primary entrypoint for connecting to the prolink network.
89
+ */
90
+ export declare function bringOnline(config?: NetworkConfig): Promise<ProlinkNetwork>;
91
+ export declare class ProlinkNetwork {
92
+ #private;
93
+ /**
94
+ * @internal
95
+ */
96
+ constructor({ config, announceSocket, beatSocket, statusSocket, deviceManager, statusEmitter, positionEmitter, }: ConstructOpts);
97
+ /**
98
+ * Configure / reconfigure the network with an explicit configuration.
99
+ *
100
+ * You may need to disconnect and re-connect the network after making a
101
+ * networking configuration change.
102
+ */
103
+ configure(config: Partial<NetworkConfig>): void;
104
+ /**
105
+ * Wait for another device to show up on the network to determine which network
106
+ * interface to listen on.
107
+ *
108
+ * Defaults the Virtual CDJ ID to 7.
109
+ */
110
+ autoconfigFromPeers(): Promise<void>;
111
+ /**
112
+ * Connect to the network.
113
+ *
114
+ * The network must first have been configured (either with autoconfigFromPeers
115
+ * or manual configuration). This will then initialize all the network services.
116
+ */
117
+ connect(): void;
118
+ /**
119
+ * Disconnect from the network
120
+ */
121
+ disconnect(): () => Promise<[unknown, unknown, unknown]>;
122
+ /**
123
+ * Close UDP sockets.
124
+ */
125
+ close(): Promise<[unknown, unknown, unknown]>;
126
+ /**
127
+ * Get the current NetworkState of the network.
128
+ *
129
+ * When the network is Online you may use the deviceManager to list and react to
130
+ * devices on the nettwork
131
+ *
132
+ * Once the network is Connected you may use the statusEmitter to listen for
133
+ * player status events, query the media databases of devices using the db
134
+ * service (or specifically query the localdb or remotedb).
135
+ */
136
+ get state(): NetworkState;
137
+ /**
138
+ * Check if the network has been configured. You cannot connect to the network
139
+ * until it has been configured.
140
+ */
141
+ get isConfigured(): boolean;
142
+ /**
143
+ * Typescript discriminate helper. Refines the type of the network to one
144
+ * that reflects the connected status. Useful to avoid having to gaurd the
145
+ * service getters from nulls.
146
+ */
147
+ isConnected(): this is ConnectedProlinkNetwork;
148
+ /**
149
+ * Get the {@link DeviceManager} service. This service is used to monitor and
150
+ * react to devices connecting and disconnecting from the prolink network.
151
+ */
152
+ get deviceManager(): DeviceManager;
153
+ /**
154
+ * Get the {@link StatusEmitter} service. This service is used to monitor
155
+ * status updates on each CDJ.
156
+ */
157
+ get statusEmitter(): StatusEmitter | null;
158
+ /**
159
+ * Get the {@link PositionEmitter} service. This service provides events with
160
+ * absolute playhead position updates from CDJ-3000+ devices.
161
+ *
162
+ * Position packets are sent approximately every 30ms while a track is loaded,
163
+ * providing precise position tracking independent of beat grids. This enables
164
+ * accurate timecode/video sync even during scratching, reverse play, and loops.
165
+ */
166
+ get positionEmitter(): PositionEmitter | null;
167
+ /**
168
+ * Get the {@link Control} service. This service can be used to control the
169
+ * Playstate of CDJs on the network.
170
+ */
171
+ get control(): Control | null;
172
+ /**
173
+ * Get the {@link Database} service. This service is used to retrieve
174
+ * metadata and listings from devices on the network, automatically choosing the
175
+ * best strategy to access the data.
176
+ */
177
+ get db(): Database | null;
178
+ /**
179
+ * Get the {@link LocalDatabase} service. This service is used to query and sync
180
+ * metadata that is downloaded directly from the rekordbox database present
181
+ * on media connected to the CDJs.
182
+ */
183
+ get localdb(): LocalDatabase | null;
184
+ /**
185
+ * Get the {@link RemoteDatabase} service. This service is used to query
186
+ * metadata directly from the database service running on Rekordbox and the CDJs
187
+ * themselves.
188
+ *
189
+ * NOTE: To use this service to access the CDJ remote database service, the
190
+ * Virtual CDJ must report itself as an ID between 1 and 6. This means
191
+ * there cannot be four physical CDJs on the network to access any CDJs
192
+ * remote database.
193
+ */
194
+ get remotedb(): RemoteDatabase | null;
195
+ /**
196
+ * Get (and initialize) the {@link MixstatusProcessor} service. This service can
197
+ * be used to monitor the 'status' of devices on the network as a whole.
198
+ */
199
+ get mixstatus(): MixstatusProcessor | null;
200
+ }
201
+ export {};
@@ -0,0 +1,63 @@
1
+ import { Device } from "../types";
2
+ import { TelemetrySpan as Span } from "../utils/telemetry";
3
+ import { fetchFile as fetchFileCall, FileInfo } from './programs';
4
+ export type { FileInfo } from './programs';
5
+ import { RetryConfig } from './rpc';
6
+ export interface FetchProgress {
7
+ read: number;
8
+ total: number;
9
+ }
10
+ /**
11
+ * The slot <-> mount name mapping is well known.
12
+ */
13
+ declare const slotMountMapping: {
14
+ readonly 3: "/C/";
15
+ readonly 2: "/B/";
16
+ readonly 4: "/";
17
+ };
18
+ /**
19
+ * Media slots that support NFS access.
20
+ */
21
+ export type NfsMediaSlot = keyof typeof slotMountMapping;
22
+ interface FetchFileOptions {
23
+ device: Device;
24
+ slot: keyof typeof slotMountMapping;
25
+ path: string;
26
+ onProgress?: Parameters<typeof fetchFileCall>[2];
27
+ span?: Span;
28
+ chunkSize?: number;
29
+ }
30
+ interface FetchFileRangeOptions {
31
+ device: Device;
32
+ slot: keyof typeof slotMountMapping;
33
+ path: string;
34
+ offset: number;
35
+ length: number;
36
+ span?: Span;
37
+ }
38
+ /**
39
+ * Fetch a range of bytes from a file on a device's NFS server.
40
+ * Optimized for partial reads (e.g., reading file headers for metadata extraction).
41
+ */
42
+ export declare function fetchFileRange({ device, slot, path, offset, length, span, }: FetchFileRangeOptions): Promise<Buffer>;
43
+ /**
44
+ * Get file info (size, handle) without fetching the file content.
45
+ */
46
+ export declare function getFileInfo({ device, slot, path, span, }: Omit<FetchFileOptions, 'onProgress' | 'chunkSize'>): Promise<FileInfo>;
47
+ /**
48
+ * Fetch a file from a devices NFS server.
49
+ *
50
+ * NOTE: The connection and root filehandle (The 'mounted' NFS export on the
51
+ * device) is cached to improve subsequent fetching performance. It's
52
+ * important that when the device disconnects you call the {@link
53
+ * resetDeviceCache} function.
54
+ */
55
+ export declare function fetchFile({ device, slot, path, onProgress, span, chunkSize, }: FetchFileOptions): Promise<Buffer<ArrayBuffer>>;
56
+ /**
57
+ * Clear the cached NFS connection and root filehandle for the given device
58
+ */
59
+ export declare function resetDeviceCache(device: Device): void;
60
+ /**
61
+ * Configure the retry strategy for making NFS calls using this module
62
+ */
63
+ export declare function configureRetryStrategy(config: RetryConfig): void;
@@ -0,0 +1,61 @@
1
+ import { TelemetrySpan as Span } from "../utils/telemetry";
2
+ import { RpcConnection, RpcProgram } from './rpc';
3
+ import { FetchProgress } from '.';
4
+ interface Program {
5
+ id: number;
6
+ version: number;
7
+ }
8
+ /**
9
+ * Queries for the listening port of a RPC program
10
+ */
11
+ export declare function makeProgramClient(conn: RpcConnection, program: Program): Promise<RpcProgram>;
12
+ /**
13
+ * Export represents a NFS export on a remote system
14
+ */
15
+ interface Export {
16
+ /**
17
+ * The name of the exported filesystem
18
+ */
19
+ filesystem: string;
20
+ /**
21
+ * The groups allowed to mount this filesystem
22
+ */
23
+ groups: string[];
24
+ }
25
+ /**
26
+ * Attributes a remote file
27
+ */
28
+ export interface FileInfo {
29
+ handle: Buffer;
30
+ name: string;
31
+ size: number;
32
+ type: 'null' | 'regular' | 'directory' | 'block' | 'char' | 'link';
33
+ }
34
+ /**
35
+ * Request a list of export entries.
36
+ */
37
+ export declare function getExports(conn: RpcProgram, span?: Span): Promise<Export[]>;
38
+ /**
39
+ * Mount the specified export, returning the file handle.
40
+ */
41
+ export declare function mountFilesystem(conn: RpcProgram, { filesystem }: Export, span?: Span): Promise<Buffer<ArrayBufferLike>>;
42
+ /**
43
+ * Lookup a file within the directory of the provided file handle, returning
44
+ * the FileInfo object if the file can be located.
45
+ */
46
+ export declare function lookupFile(conn: RpcProgram, handle: Buffer, filename: string, span?: Span): Promise<FileInfo>;
47
+ /**
48
+ * Lookup the absolute path to a file, given the root file handle and path,
49
+ */
50
+ export declare function lookupPath(conn: RpcProgram, rootHandle: Buffer, filepath: string, span?: Span): Promise<FileInfo>;
51
+ /**
52
+ * Fetch the specified file the remote NFS server. This will read the entire
53
+ * file into memory.
54
+ */
55
+ export declare function fetchFile(conn: RpcProgram, file: FileInfo, onProgress?: (progress: FetchProgress) => void, span?: Span, readSize?: number): Promise<Buffer<ArrayBuffer>>;
56
+ /**
57
+ * Fetch a range of bytes from a file on the remote NFS server.
58
+ * Unlike fetchFile, this only reads the specified range.
59
+ */
60
+ export declare function fetchFileRange(conn: RpcProgram, file: FileInfo, offset: number, length: number, span?: Span): Promise<Buffer>;
61
+ export {};
@@ -0,0 +1,60 @@
1
+ import { Mutex } from 'async-mutex';
2
+ import { OperationOptions } from 'retry';
3
+ import { Socket } from 'dgram';
4
+ interface RpcCall {
5
+ port: number;
6
+ program: number;
7
+ version: number;
8
+ procedure: number;
9
+ data: Buffer;
10
+ }
11
+ /**
12
+ * Configuration for the retry strategy to use when making RPC calls
13
+ *
14
+ * @see https://www.npmjs.com/package/promise-retry#promiseretryfn-options
15
+ */
16
+ export type RetryConfig = OperationOptions & {
17
+ /**
18
+ * Time in milliseconds to wait before a RPC transaction should timeout.
19
+ * @default 1000
20
+ */
21
+ transactionTimeout?: number;
22
+ };
23
+ /**
24
+ * Generic RPC connection. Can be used to make RPC 2 calls to any program
25
+ * specified in the RpcCall.
26
+ */
27
+ export declare class RpcConnection {
28
+ address: string;
29
+ retryConfig: RetryConfig;
30
+ socket: Socket;
31
+ mutex: Mutex;
32
+ xid: number;
33
+ constructor(address: string, retryConfig?: RetryConfig);
34
+ connected: boolean;
35
+ setupRequest({ program, version, procedure, data }: Omit<RpcCall, 'port'>): any;
36
+ /**
37
+ * Execute a RPC transaction (call and response).
38
+ *
39
+ * If a transaction does not complete after the configured timeout it will be
40
+ * retried with the retry configuration.
41
+ */
42
+ call({ port, ...call }: RpcCall): Promise<Buffer<ArrayBufferLike>>;
43
+ disconnect(): Promise<void>;
44
+ }
45
+ type RpcProgramCall = Pick<RpcCall, 'procedure' | 'data'>;
46
+ /**
47
+ * RpcProgram is constructed with specialization details for a specific RPC
48
+ * program. This should be used to avoid having to repeat yourself for calls
49
+ * made using the RpcConnection.
50
+ */
51
+ export declare class RpcProgram {
52
+ program: number;
53
+ version: number;
54
+ port: number;
55
+ conn: RpcConnection;
56
+ constructor(conn: RpcConnection, program: number, version: number, port: number);
57
+ call(data: RpcProgramCall): Promise<Buffer<ArrayBufferLike>>;
58
+ disconnect(): void;
59
+ }
60
+ export {};
@@ -0,0 +1,4 @@
1
+ /**
2
+ * Helper to flatten linked list structures into an array
3
+ */
4
+ export declare const flattenLinkedList: (item: any) => any;
@@ -0,0 +1,17 @@
1
+ /**
2
+ * RPC XDR data types. This implements nearly the entire XDR spec for the
3
+ * ONC-RPC protocol.
4
+ */
5
+ export declare const rpc: any;
6
+ /**
7
+ * Portmap RPC XDR types
8
+ */
9
+ export declare const portmap: any;
10
+ /**
11
+ * Mount RPC XDR types
12
+ */
13
+ export declare const mount: any;
14
+ /**
15
+ * NFS RPC XDR types
16
+ */
17
+ export declare const nfs: any;