addons/isl-server/src/__generated__/node-edenfs-notifications-client/example.jsblame
View source
b69ab311/**
b69ab312 * This software contains information and intellectual property that is
b69ab313 * confidential and proprietary to Facebook, Inc. and its affiliates.
b69ab314 *
b69ab315 * @generated
b69ab316 */
b69ab317
b69ab318/*
b69ab319 * This file is synced between fbcode/eden/fs/facebook/prototypes/node-edenfs-notifications-client/example.js.
b69ab3110 * The authoritative copy is the one in eden/fs/.
b69ab3111 * Use `yarn sync-edenfs-notifications` to perform the sync.
b69ab3112 *
b69ab3113 * This file is intended to be self contained so it may be copied/referenced from other extensions,
b69ab3114 * which is why it should not import anything and why it reimplements many types.
b69ab3115 */
b69ab3116
b69ab3117/**
b69ab3118 * Example usage of the EdenFS Notify JavaScript interface
b69ab3119 */
b69ab3120
b69ab3121const {EdenFSNotificationsClient, EdenFSUtils} = require('./index.js');
b69ab3122
b69ab3123async function basicExample() {
b69ab3124 console.log('=== Basic EdenFS Notify Example ===');
b69ab3125
b69ab3126 // Create a client instance
b69ab3127 const client = new EdenFSNotificationsClient({
b69ab3128 mountPoint: null,
b69ab3129 timeout: 1000, // 1 second timeout
b69ab3130 edenBinaryPath: process.env.EDEN_PATH ? process.env.EDEN_PATH : 'eden',
b69ab3131 });
b69ab3132
b69ab3133 try {
b69ab3134 // Get current journal position
b69ab3135 console.log('Getting current journal position...');
b69ab3136 const position = await client.getPosition();
b69ab3137 console.log('Current position:', position);
b69ab3138 } catch (error) {
b69ab3139 console.error('Error:', error.message);
b69ab3140 }
b69ab3141}
b69ab3142
b69ab3143async function waitReadyExample() {
b69ab3144 console.log('\n=== EdenFS Wait Ready Example ===');
b69ab3145
b69ab3146 // Create a client instance with a short timeout for demonstration
b69ab3147 const client = new EdenFSNotificationsClient({
b69ab3148 mountPoint: null,
b69ab3149 timeout: 5000, // 5 second default timeout
b69ab3150 edenBinaryPath: process.env.EDEN_PATH ? process.env.EDEN_PATH : 'eden',
b69ab3151 });
b69ab3152
b69ab3153 try {
b69ab3154 // Wait for EdenFS to be ready (useful after restart or initial setup)
b69ab3155 console.log('Waiting for EdenFS to be ready...');
b69ab3156 const isReady = await client.waitReady({
b69ab3157 timeout: 10000, // Wait up to 10 seconds
b69ab3158 });
b69ab3159
b69ab3160 if (isReady) {
b69ab3161 console.log('EdenFS is ready!');
b69ab3162 // Now safe to perform operations
b69ab3163 const position = await client.getPosition();
b69ab3164 console.log('Current position:', position);
b69ab3165 } else {
b69ab3166 console.log('EdenFS did not become ready within timeout');
b69ab3167 }
b69ab3168 } catch (error) {
b69ab3169 console.error('Error:', error.message);
b69ab3170 }
b69ab3171}
b69ab3172
b69ab3173async function changesExample(position) {
b69ab3174 console.log('=== EdenFS Notify changesSince Example ===');
b69ab3175
b69ab3176 // Create a client instance
b69ab3177 const client = new EdenFSNotificationsClient({
b69ab3178 mountPoint: null,
b69ab3179 timeout: 1000, // 1 second timeout
b69ab3180 edenBinaryPath: process.env.EDEN_PATH ? process.env.EDEN_PATH : 'eden',
b69ab3181 });
b69ab3182
b69ab3183 try {
b69ab3184 // Get changes since a specific position (if you have one)
b69ab3185 console.log('\nGetting recent changes...');
b69ab3186 const changes = await client.getChangesSince({
b69ab3187 position: position, // Start from current position
b69ab3188 });
b69ab3189 console.log('Changes:', JSON.stringify(changes, null, 2));
b69ab3190
b69ab3191 // Extract file paths from changes
b69ab3192 if (changes.changes && changes.changes.length > 0) {
b69ab3193 const paths = EdenFSUtils.extractPaths(changes.changes);
b69ab3194 console.log('Changed files:', paths);
b69ab3195 }
b69ab3196 } catch (error) {
b69ab3197 console.error('Error:', error.message);
b69ab3198 }
b69ab3199}
b69ab31100
b69ab31101async function subscriptionExample() {
b69ab31102 console.log('\n=== Subscription Example ===');
b69ab31103
b69ab31104 const client = new EdenFSNotificationsClient({
b69ab31105 // mountPoint: '/path/to/your/eden/mount' // Replace with your actual mount point
b69ab31106 edenBinaryPath: process.env.EDEN_PATH ? process.env.EDEN_PATH : 'eden',
b69ab31107 });
b69ab31108
b69ab31109 try {
b69ab31110 // Create a subscription for real-time changes
b69ab31111 const subscription = client.subscribe(
b69ab31112 {
b69ab31113 throttle: 100, // 100ms throttle between events
b69ab31114 includedSuffixes: ['.js', '.ts', '.py'], // Only watch specific file types
b69ab31115 excludedRoots: ['node_modules', '.git'], // Exclude certain directories
b69ab31116 deferredStates: ['test'], // Wait for these states to be deasserted
b69ab31117 },
b69ab31118 (error, resp) => {
b69ab31119 if (error) {
b69ab31120 console.error('Subscription error:', error.message);
b69ab31121 return;
b69ab31122 } else if (resp === null) {
b69ab31123 console.error('Subscription closed');
b69ab31124 return;
b69ab31125 } else {
b69ab31126 console.log('\n--- File System Change Detected ---');
b69ab31127 if (resp.to_position) {
b69ab31128 console.log('Position:', resp.to_position);
b69ab31129 } else if (resp.position) {
b69ab31130 console.log('Position:', resp.position);
b69ab31131 } else {
b69ab31132 console.error('Unknown response');
b69ab31133 }
b69ab31134
b69ab31135 if (resp.changes && resp.changes.length > 0) {
b69ab31136 resp.changes.forEach(change => {
b69ab31137 const changeType = EdenFSUtils.getChangeType(change);
b69ab31138 if (change.SmallChange) {
b69ab31139 const paths = EdenFSUtils.extractPaths([change]);
b69ab31140 console.log(`${changeType.toUpperCase()}: ${paths.join(', ')}`);
b69ab31141 } else if (change.LargeChange) {
b69ab31142 if (changeType == 'directory renamed') {
b69ab31143 console.log(
b69ab31144 `${changeType.toUpperCase()}: From ${EdenFSUtils.bytesToPath(change.LargeChange.DirectoryRenamed.from)} to ${EdenFSUtils.bytesToPath(change.LargeChange.DirectoryRenamed.to)}`,
b69ab31145 );
b69ab31146 } else if (changeType == 'commit transition') {
b69ab31147 console.log(
b69ab31148 `${changeType.toUpperCase()}: From ${EdenFSUtils.bytesToHex(change.LargeChange.CommitTransition.from)} to ${EdenFSUtils.bytesToHex(change.LargeChange.CommitTransition.to)}`,
b69ab31149 );
b69ab31150 } else if (changeType == 'lost changes') {
b69ab31151 console.log(
b69ab31152 `${changeType.toUpperCase()}: ${change.LargeChange.LostChanges.reason}`,
b69ab31153 );
b69ab31154 } else {
b69ab31155 console.log(`Unknown large change: ${JSON.stringify(change)}`);
b69ab31156 }
b69ab31157 }
b69ab31158 });
b69ab31159 } else if (resp.state) {
b69ab31160 console.log(`State change: ${resp.event_type} ${resp.state}`);
b69ab31161 } else {
b69ab31162 console.error(`Unknown response: ${JSON.stringify(resp)}`);
b69ab31163 }
b69ab31164 }
b69ab31165 },
b69ab31166 );
b69ab31167
b69ab31168 // Start the subscription
b69ab31169 console.log('Starting subscription...');
b69ab31170 await subscription.start();
b69ab31171 console.log('Subscription active. Make some file changes to see events.');
b69ab31172 console.log('Press Ctrl+C to stop.');
b69ab31173
b69ab31174 // Keep the process running
b69ab31175 process.on('SIGINT', async () => {
b69ab31176 console.log('\nStopping subscription...');
b69ab31177 // Wait until the subscription has fully exited before terminating
b69ab31178 subscription.on('exit', () => {
b69ab31179 console.log('Subscription exited');
b69ab31180 process.exit(0);
b69ab31181 });
b69ab31182 subscription.stop();
b69ab31183 });
b69ab31184
b69ab31185 // Prevent the script from exiting
b69ab31186 await new Promise(() => {});
b69ab31187 } catch (error) {
b69ab31188 console.error('Subscription error:', error.message);
b69ab31189 }
b69ab31190}
b69ab31191
b69ab31192async function stateExample() {
b69ab31193 console.log('\n=== State Management Example ===');
b69ab31194
b69ab31195 const client = new EdenFSNotificationsClient({
b69ab31196 // mountPoint: '/path/to/your/eden/mount' // Replace with your actual mount point
b69ab31197 edenBinaryPath: process.env.EDEN_PATH ? process.env.EDEN_PATH : 'eden',
b69ab31198 });
b69ab31199
b69ab31200 try {
b69ab31201 // Enter a state for 10 seconds
b69ab31202 console.log('Entering "build" state for 10 seconds...');
b69ab31203 await client.enterState('build', {duration: 10});
b69ab31204 console.log('State entered successfully');
b69ab31205 } catch (error) {
b69ab31206 console.error('State error:', error.message);
b69ab31207 }
b69ab31208}
b69ab31209
b69ab31210async function advancedSubscriptionExample() {
b69ab31211 console.log('\n=== Advanced Subscription with States ===');
b69ab31212
b69ab31213 const client = new EdenFSNotificationsClient({
b69ab31214 // mountPoint: '/path/to/your/eden/mount' // Replace with your actual mount point
b69ab31215 edenBinaryPath: process.env.EDEN_PATH ? process.env.EDEN_PATH : 'eden',
b69ab31216 });
b69ab31217
b69ab31218 try {
b69ab31219 // Create a subscription that waits for certain states to be deasserted
b69ab31220 const subscription = client.subscribe(
b69ab31221 {
b69ab31222 deferredStates: ['build', 'test'], // Wait for these states to be deasserted
b69ab31223 throttle: 50,
b69ab31224 includedSuffixes: ['.js', '.ts', '.json'],
b69ab31225 },
b69ab31226 (error, resp) => {
b69ab31227 if (error) {
b69ab31228 console.error('Subscription error:', error.message);
b69ab31229 return;
b69ab31230 }
b69ab31231
b69ab31232 console.log('\n--- File System Change Detected ---');
b69ab31233 if (resp.to_position) {
b69ab31234 console.log('Position:', resp.to_position);
b69ab31235 } else if (resp.position) {
b69ab31236 console.log('Position:', resp.position);
b69ab31237 } else {
b69ab31238 console.error('Unknown response: ', resp);
b69ab31239 }
b69ab31240
b69ab31241 if (resp.changes) {
b69ab31242 if (resp.changes.length === 0) {
b69ab31243 console.log('no changes');
b69ab31244 }
b69ab31245 resp.changes.forEach(change => {
b69ab31246 const changeType = EdenFSUtils.getChangeType(change);
b69ab31247 if (change.SmallChange) {
b69ab31248 const paths = EdenFSUtils.extractPaths([change]);
b69ab31249 console.log(`${changeType.toUpperCase()}: ${paths.join(', ')}`);
b69ab31250 } else if (change.LargeChange) {
b69ab31251 if (changeType == 'directory renamed') {
b69ab31252 console.log(
b69ab31253 `${changeType.toUpperCase()}: From ${EdenFSUtils.bytesToPath(change.LargeChange.DirectoryRenamed.from)} to ${EdenFSUtils.bytesToPath(change.LargeChange.DirectoryRenamed.to)}`,
b69ab31254 );
b69ab31255 } else if (changeType == 'commit transition') {
b69ab31256 console.log(
b69ab31257 `${changeType.toUpperCase()}: From ${EdenFSUtils.bytesToHex(change.LargeChange.CommitTransition.from)} to ${EdenFSUtils.bytesToHex(change.LargeChange.CommitTransition.to)}`,
b69ab31258 );
b69ab31259 } else if (changeType == 'lost changes') {
b69ab31260 console.log(
b69ab31261 `${changeType.toUpperCase()}: ${change.LargeChange.LostChanges.reason}`,
b69ab31262 );
b69ab31263 } else {
b69ab31264 console.log(`Unknown large change: ${JSON.stringify(change)}`);
b69ab31265 }
b69ab31266 }
b69ab31267 });
b69ab31268 } else if (resp.state) {
b69ab31269 console.log(`State change: ${resp.event_type} ${resp.state}`);
b69ab31270 } else {
b69ab31271 console.error(`Unknown response: ${JSON.stringify(resp)}`);
b69ab31272 }
b69ab31273 },
b69ab31274 );
b69ab31275
b69ab31276 await subscription.start();
b69ab31277 console.log('Advanced subscription started. Try entering/exiting states.');
b69ab31278
b69ab31279 // Simulate entering and exiting states
b69ab31280 setTimeout(async () => {
b69ab31281 console.log('\nEntering build state...');
b69ab31282 await client.enterState('build', {duration: 5});
b69ab31283 }, 2000);
b69ab31284
b69ab31285 setTimeout(async () => {
b69ab31286 console.log('\nEntering test state...');
b69ab31287 await client.enterState('test', {duration: 3});
b69ab31288 }, 8000);
b69ab31289
b69ab31290 // Keep running for demo
b69ab31291 setTimeout(() => {
b69ab31292 subscription.stop();
b69ab31293 console.log('\nDemo completed');
b69ab31294 process.exit(0);
b69ab31295 }, 15000);
b69ab31296 } catch (error) {
b69ab31297 console.error('Advanced subscription error:', error.message);
b69ab31298 }
b69ab31299}
b69ab31300
b69ab31301async function utilityExample() {
b69ab31302 console.log('\n=== Utility Functions Example ===');
b69ab31303
b69ab31304 // Example change data (as returned by EdenFS)
b69ab31305 const exampleChanges = [
b69ab31306 {
b69ab31307 SmallChange: {
b69ab31308 Added: {
b69ab31309 file_type: 'Regular',
b69ab31310 path: [104, 101, 108, 108, 111, 46, 116, 120, 116], // "hello.txt" in bytes
b69ab31311 },
b69ab31312 },
b69ab31313 },
b69ab31314 {
b69ab31315 SmallChange: {
b69ab31316 Modified: {
b69ab31317 file_type: 'Regular',
b69ab31318 path: [119, 111, 114, 108, 100, 46, 106, 115], // "world.js" in bytes
b69ab31319 },
b69ab31320 },
b69ab31321 },
b69ab31322 {
b69ab31323 SmallChange: {
b69ab31324 Renamed: {
b69ab31325 file_type: 'Regular',
b69ab31326 from: [111, 108, 100, 46, 116, 120, 116], // "old.txt" in bytes
b69ab31327 to: [110, 101, 119, 46, 116, 120, 116], // "new.txt" in bytes
b69ab31328 },
b69ab31329 },
b69ab31330 },
b69ab31331 {
b69ab31332 LargeChange: {
b69ab31333 CommitTransition: {
b69ab31334 from: [111, 108, 100, 46, 116, 120, 116], // "old.txt" in bytes
b69ab31335 to: [110, 101, 119, 46, 116, 120, 116], // "new.txt" in bytes
b69ab31336 },
b69ab31337 },
b69ab31338 },
b69ab31339 {
b69ab31340 StateChange: {
b69ab31341 StateEntered: {
b69ab31342 name: 'meerkat',
b69ab31343 },
b69ab31344 },
b69ab31345 },
b69ab31346 ];
b69ab31347
b69ab31348 // Extract paths from changes
b69ab31349 console.log('Extracting single path');
b69ab31350 const [path1, path2] = EdenFSUtils.extractPath(exampleChanges[0].SmallChange);
b69ab31351 console.log('Extracted paths:', path1, path2);
b69ab31352 console.log('Extracting multiple paths:');
b69ab31353 const paths = EdenFSUtils.extractPaths(exampleChanges);
b69ab31354 console.log('Extracted paths:', paths);
b69ab31355 console.log('Extracting types:');
b69ab31356 const type = EdenFSUtils.extractFileType(exampleChanges[0].SmallChange);
b69ab31357 console.log('Extracted file type:', type);
b69ab31358
b69ab31359 // Get change types
b69ab31360 exampleChanges.forEach((change, index) => {
b69ab31361 const changeType = EdenFSUtils.getChangeType(change);
b69ab31362 console.log(`Change ${index + 1} type:`, changeType);
b69ab31363 });
b69ab31364}
b69ab31365
b69ab31366// Run examples
b69ab31367async function runExamples() {
b69ab31368 console.log('EdenFS Notify JavaScript Interface Examples');
b69ab31369 console.log('==========================================');
b69ab31370
b69ab31371 // Note: Update the mount point in each example before running
b69ab31372 console.log('\nNOTE: Please update the mount point paths in the examples before running!');
b69ab31373
b69ab31374 try {
b69ab31375 await basicExample();
b69ab31376 await waitReadyExample();
b69ab31377 if (process.argv.length > 2) {
b69ab31378 await changesExample(process.argv[2]);
b69ab31379 }
b69ab31380 await utilityExample();
b69ab31381
b69ab31382 // Uncomment these to run interactive examples:
b69ab31383 // await subscriptionExample();
b69ab31384 // await stateExample();
b69ab31385 // await advancedSubscriptionExample();
b69ab31386 } catch (error) {
b69ab31387 console.error('Example error:', error.message);
b69ab31388 }
b69ab31389}
b69ab31390
b69ab31391// Run if this file is executed directly
b69ab31392if (require.main === module) {
b69ab31393 runExamples();
b69ab31394}