github.com/hernad/nomad@v1.6.112/ui/app/utils/properties/watch.js (about) 1 /** 2 * Copyright (c) HashiCorp, Inc. 3 * SPDX-License-Identifier: MPL-2.0 4 */ 5 6 // @ts-check 7 8 import Ember from 'ember'; 9 import { get } from '@ember/object'; 10 import { assert } from '@ember/debug'; 11 import RSVP from 'rsvp'; 12 import { task } from 'ember-concurrency'; 13 import { AbortController } from 'fetch'; 14 import wait from 'nomad-ui/utils/wait'; 15 import Watchable from 'nomad-ui/adapters/watchable'; 16 import config from 'nomad-ui/config/environment'; 17 18 const isEnabled = config.APP.blockingQueries !== false; 19 20 /** 21 * @typedef watchRecordOptions 22 * @property {boolean} [shouldSurfaceErrors=false] - If true, the task will throw errors instead of yielding them. 23 */ 24 25 /** 26 * @param {string} modelName - The name of the model to watch. 27 * @param {watchRecordOptions} [options] 28 */ 29 export function watchRecord(modelName, { shouldSurfaceErrors = false } = {}) { 30 return task(function* (id, throttle = 2000) { 31 assert( 32 'To watch a record, the record adapter MUST extend Watchable', 33 this.store.adapterFor(modelName) instanceof Watchable 34 ); 35 if (typeof id === 'object') { 36 id = get(id, 'id'); 37 } 38 while (isEnabled && !Ember.testing) { 39 const controller = new AbortController(); 40 try { 41 yield RSVP.all([ 42 this.store.findRecord(modelName, id, { 43 reload: true, 44 adapterOptions: { watch: true, abortController: controller }, 45 }), 46 wait(throttle), 47 ]); 48 } catch (e) { 49 if (shouldSurfaceErrors) { 50 throw e; 51 } 52 yield e; 53 break; 54 } finally { 55 controller.abort(); 56 } 57 } 58 }).drop(); 59 } 60 61 export function watchRelationship(relationshipName, replace = false) { 62 return task(function* (model, throttle = 2000) { 63 assert( 64 'To watch a relationship, the adapter of the model provided to the watchRelationship task MUST extend Watchable', 65 this.store.adapterFor(model.constructor.modelName) instanceof Watchable 66 ); 67 while (isEnabled && !Ember.testing) { 68 const controller = new AbortController(); 69 try { 70 yield RSVP.all([ 71 this.store 72 .adapterFor(model.constructor.modelName) 73 .reloadRelationship(model, relationshipName, { 74 watch: true, 75 abortController: controller, 76 replace, 77 }), 78 wait(throttle), 79 ]); 80 } catch (e) { 81 yield e; 82 break; 83 } finally { 84 controller.abort(); 85 } 86 } 87 }).drop(); 88 } 89 90 export function watchNonStoreRecords(modelName) { 91 return task(function* (model, asyncCallbackName, throttle = 5000) { 92 assert( 93 'To watch a non-store records, the adapter of the model provided to the watchNonStoreRecords task MUST extend Watchable', 94 this.store.adapterFor(modelName) instanceof Watchable 95 ); 96 while (isEnabled && !Ember.testing) { 97 const controller = new AbortController(); 98 try { 99 yield model[asyncCallbackName](); 100 yield wait(throttle); 101 } catch (e) { 102 yield e; 103 break; 104 } finally { 105 controller.abort(); 106 } 107 } 108 }).drop(); 109 } 110 111 export function watchAll(modelName) { 112 return task(function* (throttle = 2000) { 113 assert( 114 'To watch all, the respective adapter MUST extend Watchable', 115 this.store.adapterFor(modelName) instanceof Watchable 116 ); 117 while (isEnabled && !Ember.testing) { 118 const controller = new AbortController(); 119 try { 120 yield RSVP.all([ 121 this.store.findAll(modelName, { 122 reload: true, 123 adapterOptions: { watch: true, abortController: controller }, 124 }), 125 wait(throttle), 126 ]); 127 } catch (e) { 128 yield e; 129 break; 130 } finally { 131 controller.abort(); 132 } 133 } 134 }).drop(); 135 } 136 137 export function watchQuery(modelName) { 138 return task(function* (params, throttle = 10000) { 139 assert( 140 'To watch a query, the adapter for the type being queried MUST extend Watchable', 141 this.store.adapterFor(modelName) instanceof Watchable 142 ); 143 while (isEnabled && !Ember.testing) { 144 const controller = new AbortController(); 145 try { 146 yield RSVP.all([ 147 this.store.query(modelName, params, { 148 reload: true, 149 adapterOptions: { watch: true, abortController: controller }, 150 }), 151 wait(throttle), 152 ]); 153 } catch (e) { 154 yield e; 155 break; 156 } finally { 157 controller.abort(); 158 } 159 } 160 }).drop(); 161 }