teraslice 3.3.0 → 3.3.2

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 (108) hide show
  1. package/LICENSE +202 -0
  2. package/package.json +25 -28
  3. package/dist/src/interfaces.js +0 -12
  4. package/dist/src/lib/cluster/cluster_master.js +0 -246
  5. package/dist/src/lib/cluster/node_master.js +0 -355
  6. package/dist/src/lib/cluster/services/api.js +0 -663
  7. package/dist/src/lib/cluster/services/assets.js +0 -224
  8. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/index.js +0 -192
  9. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/interfaces.js +0 -2
  10. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8s.js +0 -419
  11. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sDeploymentResource.js +0 -60
  12. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sJobResource.js +0 -55
  13. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sResource.js +0 -357
  14. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sServiceResource.js +0 -37
  15. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/k8sState.js +0 -60
  16. package/dist/src/lib/cluster/services/cluster/backends/kubernetesV2/utils.js +0 -170
  17. package/dist/src/lib/cluster/services/cluster/backends/native/dispatch.js +0 -13
  18. package/dist/src/lib/cluster/services/cluster/backends/native/index.js +0 -526
  19. package/dist/src/lib/cluster/services/cluster/backends/native/messaging.js +0 -548
  20. package/dist/src/lib/cluster/services/cluster/backends/state-utils.js +0 -26
  21. package/dist/src/lib/cluster/services/cluster/index.js +0 -13
  22. package/dist/src/lib/cluster/services/execution.js +0 -435
  23. package/dist/src/lib/cluster/services/index.js +0 -6
  24. package/dist/src/lib/cluster/services/interfaces.js +0 -2
  25. package/dist/src/lib/cluster/services/jobs.js +0 -458
  26. package/dist/src/lib/config/default-sysconfig.js +0 -25
  27. package/dist/src/lib/config/index.js +0 -20
  28. package/dist/src/lib/config/schemas/system.js +0 -360
  29. package/dist/src/lib/storage/analytics.js +0 -86
  30. package/dist/src/lib/storage/assets.js +0 -401
  31. package/dist/src/lib/storage/backends/elasticsearch_store.js +0 -496
  32. package/dist/src/lib/storage/backends/mappings/analytics.js +0 -20
  33. package/dist/src/lib/storage/backends/mappings/asset.js +0 -32
  34. package/dist/src/lib/storage/backends/mappings/ex.js +0 -53
  35. package/dist/src/lib/storage/backends/mappings/job.js +0 -42
  36. package/dist/src/lib/storage/backends/mappings/state.js +0 -16
  37. package/dist/src/lib/storage/backends/s3_store.js +0 -237
  38. package/dist/src/lib/storage/execution.js +0 -302
  39. package/dist/src/lib/storage/index.js +0 -7
  40. package/dist/src/lib/storage/jobs.js +0 -81
  41. package/dist/src/lib/storage/state.js +0 -254
  42. package/dist/src/lib/utils/api_utils.js +0 -128
  43. package/dist/src/lib/utils/asset_utils.js +0 -94
  44. package/dist/src/lib/utils/date_utils.js +0 -52
  45. package/dist/src/lib/utils/encoding_utils.js +0 -27
  46. package/dist/src/lib/utils/events.js +0 -4
  47. package/dist/src/lib/utils/file_utils.js +0 -124
  48. package/dist/src/lib/utils/id_utils.js +0 -15
  49. package/dist/src/lib/utils/port_utils.js +0 -32
  50. package/dist/src/lib/workers/assets/index.js +0 -3
  51. package/dist/src/lib/workers/assets/loader-executable.js +0 -40
  52. package/dist/src/lib/workers/assets/loader.js +0 -73
  53. package/dist/src/lib/workers/assets/spawn.js +0 -55
  54. package/dist/src/lib/workers/context/execution-context.js +0 -12
  55. package/dist/src/lib/workers/context/terafoundation-context.js +0 -8
  56. package/dist/src/lib/workers/execution-controller/execution-analytics.js +0 -188
  57. package/dist/src/lib/workers/execution-controller/index.js +0 -1024
  58. package/dist/src/lib/workers/execution-controller/recovery.js +0 -151
  59. package/dist/src/lib/workers/execution-controller/scheduler.js +0 -390
  60. package/dist/src/lib/workers/execution-controller/slice-analytics.js +0 -96
  61. package/dist/src/lib/workers/helpers/job.js +0 -80
  62. package/dist/src/lib/workers/helpers/op-analytics.js +0 -22
  63. package/dist/src/lib/workers/helpers/terafoundation.js +0 -34
  64. package/dist/src/lib/workers/helpers/worker-shutdown.js +0 -147
  65. package/dist/src/lib/workers/metrics/index.js +0 -108
  66. package/dist/src/lib/workers/worker/index.js +0 -378
  67. package/dist/src/lib/workers/worker/slice.js +0 -122
  68. package/dist/test/config/schemas/system_schema-spec.js +0 -26
  69. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8s-v2-spec.js +0 -458
  70. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sResource-v2-spec.js +0 -818
  71. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-multicluster-v2-spec.js +0 -67
  72. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/k8sState-v2-spec.js +0 -84
  73. package/dist/test/lib/cluster/services/cluster/backends/kubernetes/v2/utils-v2-spec.js +0 -320
  74. package/dist/test/lib/cluster/services/cluster/backends/state-utils-spec.js +0 -37
  75. package/dist/test/node_master-spec.js +0 -194
  76. package/dist/test/services/api-spec.js +0 -79
  77. package/dist/test/services/assets-spec.js +0 -158
  78. package/dist/test/services/messaging-spec.js +0 -440
  79. package/dist/test/storage/assets_storage-spec.js +0 -95
  80. package/dist/test/storage/s3_store-spec.js +0 -149
  81. package/dist/test/test.config.js +0 -23
  82. package/dist/test/test.setup.js +0 -6
  83. package/dist/test/utils/api_utils-spec.js +0 -25
  84. package/dist/test/utils/asset_utils-spec.js +0 -141
  85. package/dist/test/utils/elastic_utils-spec.js +0 -25
  86. package/dist/test/workers/execution-controller/execution-controller-spec.js +0 -371
  87. package/dist/test/workers/execution-controller/execution-special-test-cases-spec.js +0 -519
  88. package/dist/test/workers/execution-controller/execution-test-cases-spec.js +0 -343
  89. package/dist/test/workers/execution-controller/recovery-spec.js +0 -160
  90. package/dist/test/workers/execution-controller/scheduler-spec.js +0 -249
  91. package/dist/test/workers/execution-controller/slice-analytics-spec.js +0 -121
  92. package/dist/test/workers/fixtures/ops/example-op/processor.js +0 -20
  93. package/dist/test/workers/fixtures/ops/example-op/schema.js +0 -19
  94. package/dist/test/workers/fixtures/ops/example-reader/fetcher.js +0 -20
  95. package/dist/test/workers/fixtures/ops/example-reader/schema.js +0 -41
  96. package/dist/test/workers/fixtures/ops/example-reader/slicer.js +0 -37
  97. package/dist/test/workers/fixtures/ops/new-op/processor.js +0 -29
  98. package/dist/test/workers/fixtures/ops/new-op/schema.js +0 -18
  99. package/dist/test/workers/fixtures/ops/new-reader/fetcher.js +0 -19
  100. package/dist/test/workers/fixtures/ops/new-reader/schema.js +0 -23
  101. package/dist/test/workers/fixtures/ops/new-reader/slicer.js +0 -13
  102. package/dist/test/workers/helpers/configs.js +0 -128
  103. package/dist/test/workers/helpers/execution-controller-helper.js +0 -49
  104. package/dist/test/workers/helpers/index.js +0 -5
  105. package/dist/test/workers/helpers/test-context.js +0 -210
  106. package/dist/test/workers/helpers/zip-directory.js +0 -25
  107. package/dist/test/workers/worker/slice-spec.js +0 -333
  108. package/dist/test/workers/worker/worker-spec.js +0 -356
@@ -1,360 +0,0 @@
1
- import ip from 'ip';
2
- import path from 'node:path';
3
- import { isPlainObject, isString, isArray, isInteger } from '@terascope/core-utils';
4
- import { cpus } from 'node:os';
5
- const workerCount = cpus().length;
6
- const DEFAULT_ASSET_STORAGE_CONNECTION_TYPE = 'elasticsearch-next';
7
- /**
8
- * This schema object is for the Teraslice configuration settings coming from
9
- * its configuration file.
10
- */
11
- export const schema = {
12
- api_response_timeout: {
13
- doc: 'HTTP response timeout for the Teraslice API server',
14
- default: '5 minutes',
15
- format: 'duration'
16
- },
17
- assets_directory: {
18
- doc: 'directory to look for assets',
19
- default: path.join(process.cwd(), './assets'),
20
- format: (val) => {
21
- if (val) {
22
- if (isArray(val)) {
23
- const containStrings = val.every(isString);
24
- if (!containStrings)
25
- throw new Error('Invalid parameter assets_directory, if specified as an array, it must contain an array of strings');
26
- return;
27
- }
28
- if (!isString(val))
29
- throw new Error('Invalid parameter assets_directory, it must either be a string or an array of strings');
30
- }
31
- }
32
- },
33
- assets_volume: {
34
- doc: 'name of shared asset volume (k8s)',
35
- default: undefined,
36
- format: 'optional_string'
37
- },
38
- autoload_directory: {
39
- doc: 'directory to look for assets to auto deploy when teraslice boots up',
40
- default: path.join(process.cwd(), './autoload'),
41
- format: 'optional_string'
42
- },
43
- hostname: {
44
- doc: 'IP or hostname for server',
45
- default: ip.address(),
46
- format: 'required_string'
47
- },
48
- workers: {
49
- doc: 'Number of workers per server',
50
- default: workerCount,
51
- format: 'nat'
52
- },
53
- master: {
54
- doc: 'boolean for determining if cluster_master should live on this node',
55
- default: false,
56
- format: Boolean
57
- },
58
- master_hostname: {
59
- doc: 'hostname where the cluster_master resides, used to notify all node_masters where to connect',
60
- default: 'localhost',
61
- format: 'required_string'
62
- },
63
- port: {
64
- doc: 'port for the cluster_master to listen on',
65
- default: 5678,
66
- format: 'port'
67
- },
68
- name: {
69
- doc: 'Name for the cluster itself, its used for naming log files/indices',
70
- default: 'teracluster',
71
- format: 'elasticsearch_name'
72
- },
73
- state: {
74
- doc: 'Opensearch cluster where job state, analytics and logs are stored',
75
- default: { connection: 'default' },
76
- format(val) {
77
- if (!val.connection) {
78
- throw new Error('state parameter must be an object with a key named "connection"');
79
- }
80
- if (typeof val.connection !== 'string') {
81
- throw new Error('state parameter object with a key "connection" must be of type String as the value');
82
- }
83
- }
84
- },
85
- index_settings: {
86
- analytics: {
87
- number_of_shards: {
88
- doc: 'The number of shards for the analytics index',
89
- default: 5
90
- },
91
- number_of_replicas: {
92
- doc: 'The number of replicas for the analytics index',
93
- default: 1
94
- }
95
- },
96
- assets: {
97
- number_of_shards: {
98
- doc: 'The number of shards for the assets index',
99
- default: 5
100
- },
101
- number_of_replicas: {
102
- doc: 'The number of replicas for the assets index',
103
- default: 1
104
- }
105
- },
106
- jobs: {
107
- number_of_shards: {
108
- doc: 'The number of shards for the jobs index',
109
- default: 5
110
- },
111
- number_of_replicas: {
112
- doc: 'The number of replicas for the jobs index',
113
- default: 1
114
- }
115
- },
116
- execution: {
117
- number_of_shards: {
118
- doc: 'The number of shards for the execution index',
119
- default: 5
120
- },
121
- number_of_replicas: {
122
- doc: 'The number of replicas for the execution index',
123
- default: 1
124
- }
125
- },
126
- state: {
127
- number_of_shards: {
128
- doc: 'The number of shards for the state index',
129
- default: 5
130
- },
131
- number_of_replicas: {
132
- doc: 'The number of replicas for the state index',
133
- default: 1
134
- }
135
- }
136
- },
137
- shutdown_timeout: {
138
- doc: 'time in milliseconds for workers and slicers to finish operations before forcefully shutting down',
139
- default: '1 minute',
140
- format: 'duration'
141
- },
142
- node_disconnect_timeout: {
143
- doc: 'time in milliseconds that the cluster will wait until it drops that node from state and attempts to provision the lost workers',
144
- default: '5 minutes',
145
- format: 'duration'
146
- },
147
- worker_disconnect_timeout: {
148
- doc: 'time in milliseconds that the slicer will wait after all workers have disconnected before terminating the job',
149
- default: '5 minutes',
150
- format: 'duration'
151
- },
152
- slicer_timeout: {
153
- doc: 'time in milliseconds that the slicer will wait for worker connection before terminating the job',
154
- default: '3 minutes',
155
- format: 'duration'
156
- },
157
- action_timeout: {
158
- doc: 'time in milliseconds for waiting for a network message (pause/stop job, etc) to complete before throwing an error',
159
- default: '2 minutes',
160
- format: 'duration'
161
- },
162
- network_latency_buffer: {
163
- doc: 'time in milliseconds buffer which is combined with action_timeout to determine how long a network message will wait till it throws an error',
164
- default: '15 seconds',
165
- format: 'duration'
166
- },
167
- node_state_interval: {
168
- doc: 'time in milliseconds that indicates when the cluster master will ping nodes for their state',
169
- default: '5 seconds',
170
- format: 'duration'
171
- },
172
- analytics_rate: {
173
- doc: 'time in milliseconds in which to push analytics to cluster master',
174
- default: '1 minute',
175
- format: 'duration'
176
- },
177
- slicer_allocation_attempts: {
178
- doc: 'The number of times a slicer will try to be allocated before failing',
179
- default: 3,
180
- format: 'nat', // integer >=0 (natural number)
181
- },
182
- slicer_port_range: {
183
- doc: 'range of ports that slicers will use per node',
184
- default: '45679:46678',
185
- format(val) {
186
- const arr = val.split(':');
187
- if (arr.length !== 2) {
188
- throw new Error('slicer_port_range is formatted incorrectly');
189
- }
190
- arr.forEach((value) => {
191
- if (isInteger(value) !== false) {
192
- throw new Error('values specified in slicer_port_range must be a number specified as a string');
193
- }
194
- });
195
- }
196
- },
197
- index_rollover_frequency: {
198
- state: {
199
- doc: 'How frequently the teraslice state indices are created',
200
- default: 'monthly',
201
- format: ['daily', 'monthly', 'yearly']
202
- },
203
- analytics: {
204
- doc: 'How frequently the analytics indices are created',
205
- default: 'monthly',
206
- format: ['daily', 'monthly', 'yearly']
207
- }
208
- },
209
- cluster_manager_type: {
210
- doc: 'determines which cluster system should be used',
211
- default: 'native',
212
- format: ['native', 'kubernetesV2']
213
- },
214
- cpu: {
215
- doc: 'number of cpus to reserve per teraslice worker in kubernetes',
216
- default: undefined,
217
- format: 'Number'
218
- },
219
- cpu_execution_controller: {
220
- doc: 'number of cpus to reserve per teraslice execution controller in kubernetes',
221
- default: 0.5,
222
- format: 'Number'
223
- },
224
- ephemeral_storage: {
225
- doc: 'Add ephemeral storage volume to worker and execution controller pods',
226
- default: false,
227
- format: Boolean
228
- },
229
- memory: {
230
- doc: 'memory, in bytes, to reserve per teraslice worker in kubernetes',
231
- default: undefined,
232
- format: 'Number'
233
- },
234
- memory_execution_controller: {
235
- doc: 'memory, in bytes, to reserve per teraslice execution controller in kubernetes',
236
- default: 512000000,
237
- format: 'Number'
238
- },
239
- env_vars: {
240
- default: {},
241
- doc: 'default environment variables to set on each the teraslice worker, in the format, { "EXAMPLE": "test" }',
242
- format(obj) {
243
- if (!isPlainObject(obj)) {
244
- throw new Error('must be object');
245
- }
246
- Object.entries(obj).forEach(([key, val]) => {
247
- if (key == null || key === '') {
248
- throw new Error('key must be not empty');
249
- }
250
- if (val == null || val === '') {
251
- throw new Error(`value for key "${key}" must be not empty`);
252
- }
253
- });
254
- },
255
- },
256
- execution_controller_targets: {
257
- default: null,
258
- doc: 'Specify an array of {"key": ..., "value": ...} targets for execution controllers',
259
- format(arr) {
260
- if (arr != null) {
261
- if (!Array.isArray(arr)) {
262
- throw new Error('labels is required to be an array');
263
- // FIXME: improve input and error handling
264
- }
265
- }
266
- }
267
- },
268
- kubernetes_api_poll_delay: {
269
- doc: 'Specify the delay between attempts to poll the kubernetes API',
270
- default: '1 second',
271
- format: 'duration'
272
- },
273
- kubernetes_image: {
274
- doc: 'Specify a custom image name for kubernetes, this only applies to kubernetes systems',
275
- default: 'terascope/teraslice',
276
- format: 'optional_string'
277
- },
278
- kubernetes_namespace: {
279
- doc: 'Specify a custom kubernetes namespace, this only applies to kubernetes systems',
280
- default: 'default',
281
- format: 'optional_string'
282
- },
283
- kubernetes_overrides_enabled: {
284
- doc: '',
285
- default: false,
286
- format: Boolean
287
- },
288
- kubernetes_priority_class_name: {
289
- doc: 'Priority class that the Teraslice master, execution controller, and stateful workers should run with',
290
- default: undefined,
291
- format: 'optional_string'
292
- },
293
- kubernetes_config_map_name: {
294
- doc: 'Specify the name of the Kubernetes ConfigMap used to configure worker pods',
295
- default: 'teraslice-worker',
296
- format: 'optional_string'
297
- },
298
- kubernetes_image_pull_secret: {
299
- doc: 'Name of Kubernetes secret used to pull docker images from private repository',
300
- default: undefined,
301
- format: 'optional_string'
302
- },
303
- kubernetes_worker_antiaffinity: {
304
- doc: 'Enable Teraslice woker pod AntiAffinity in Kubernetes',
305
- default: false,
306
- format: Boolean
307
- },
308
- asset_storage_connection_type: {
309
- doc: 'Name of the connection type used to store assets',
310
- default: DEFAULT_ASSET_STORAGE_CONNECTION_TYPE,
311
- format: String
312
- },
313
- asset_storage_connection: {
314
- doc: 'Name of the connection used to store assets.',
315
- default: 'default',
316
- format: String
317
- },
318
- asset_storage_bucket: {
319
- doc: 'Name of S3 bucket used to store assets. Can only be used if "asset_storage_connection_type" is "s3".',
320
- default: undefined,
321
- format: 'optional_string'
322
- },
323
- };
324
- export function configSchema() {
325
- return {
326
- schema: { teraslice: schema },
327
- validatorFn: (config, sysconfig) => {
328
- const connectionType = config.asset_storage_connection_type
329
- || DEFAULT_ASSET_STORAGE_CONNECTION_TYPE;
330
- const connectionTypesPresent = Object.keys(sysconfig.terafoundation.connectors);
331
- const validConnectionTypes = ['elasticsearch-next', 's3'];
332
- // checks on asset_storage_connection_type
333
- if (!validConnectionTypes
334
- .includes(connectionType)) {
335
- throw new Error(`Invalid asset_storage_connection_type. Valid types: ${validConnectionTypes.toString()}`);
336
- }
337
- if (!connectionTypesPresent
338
- .includes(connectionType)) {
339
- throw new Error('asset_storage_connection_type not found in terafoundation.connectors');
340
- }
341
- // checks on asset_storage_connection
342
- const connectionsPresent = Object.keys(sysconfig.terafoundation.connectors[`${connectionType}`]);
343
- /// Check to make sure the asset_storage_connection exists inside the connector
344
- /// Exclude elasticsearch as this connection type does not utilize this value
345
- if (connectionType !== 'elasticsearch-next'
346
- && config.asset_storage_connection
347
- && !connectionsPresent.includes(config.asset_storage_connection)) {
348
- throw new Error(`${config.asset_storage_connection} not found in terafoundation.connectors.${connectionType}`);
349
- }
350
- // checks on asset_storage_bucket
351
- if (config.asset_storage_bucket && connectionType !== 's3') {
352
- throw new Error('asset_storage_bucket can only be used if asset_storage_connection_type is set to "s3"');
353
- }
354
- // TODO: add regex to check if valid bucket name
355
- }
356
- };
357
- }
358
- // TODO: fix this
359
- export const config_schema = configSchema;
360
- //# sourceMappingURL=system.js.map
@@ -1,86 +0,0 @@
1
- import { pMap } from '@terascope/core-utils';
2
- import { makeLogger } from '../workers/helpers/terafoundation.js';
3
- import { timeseriesIndex } from '../utils/date_utils.js';
4
- import { TerasliceElasticsearchStorage } from './backends/elasticsearch_store.js';
5
- // Module to manager job states in Elasticsearch.
6
- // All functions in this module return promises that must be resolved to
7
- // get the final result.
8
- export class AnalyticsStorage {
9
- workerId;
10
- timeseriesFormat;
11
- baseIndex;
12
- backend;
13
- logger;
14
- constructor(context) {
15
- const logger = makeLogger(context, 'analytics_storage');
16
- const config = context.sysconfig.teraslice;
17
- const _index = `${config.name}__analytics`;
18
- // making this to pass down to backend for dynamic index searches
19
- const indexName = `${_index}*`;
20
- const backendConfig = {
21
- context,
22
- indexName,
23
- recordType: 'analytics',
24
- idField: '_id',
25
- fullResponse: false,
26
- logRecord: false,
27
- forceRefresh: false,
28
- storageName: 'analytics',
29
- logger
30
- };
31
- this.workerId = `${context.sysconfig.teraslice.hostname}__${context.cluster.worker?.id}`;
32
- this.timeseriesFormat = config.index_rollover_frequency.analytics;
33
- this.baseIndex = _index;
34
- this.logger = logger;
35
- this.backend = new TerasliceElasticsearchStorage(backendConfig);
36
- }
37
- async initialize() {
38
- await this.backend.initialize();
39
- this.logger.info('analytics storage initialized');
40
- }
41
- async log(job, sliceInfo, stats, state = 'completed') {
42
- const { index, timestamp } = timeseriesIndex(this.timeseriesFormat, this.baseIndex);
43
- // These records are uniquely identified by ex_id + slice_id
44
- return pMap(job.config.operations, (op, i) => this.backend.bulk({
45
- '@timestamp': timestamp,
46
- ex_id: job.config.ex_id,
47
- job_id: job.config.job_id,
48
- worker_id: this.workerId,
49
- slice_id: sliceInfo.slice_id,
50
- slicer_id: sliceInfo.slicer_id,
51
- op: op._op,
52
- state,
53
- order: i,
54
- count: stats.size[i],
55
- time: stats.time[i],
56
- memory: stats.memory[i],
57
- }, 'index', index));
58
- }
59
- async get(recordId, index) {
60
- return this.backend.get(recordId, index);
61
- }
62
- async search(query, from = 0, size = 10000, sort, fields) {
63
- return this.backend.search(query, from, size, sort, fields);
64
- }
65
- async update(recordId, updateSpec, index) {
66
- return this.backend.update(recordId, updateSpec, index);
67
- }
68
- async remove(recordId, index) {
69
- return this.backend.remove(recordId, index);
70
- }
71
- async shutdown(forceShutdown) {
72
- this.logger.info('shutting down.');
73
- return this.backend.shutdown(forceShutdown);
74
- }
75
- async refresh() {
76
- const { index } = timeseriesIndex(this.timeseriesFormat, this.baseIndex);
77
- return this.backend.refresh(index);
78
- }
79
- verifyClient() {
80
- return this.backend.verifyClient();
81
- }
82
- async waitForClient() {
83
- return this.backend.waitForClient();
84
- }
85
- }
86
- //# sourceMappingURL=analytics.js.map