@casual-simulation/aux-vm 3.4.6-alpha.14601027727 → 3.5.0-alpha.15117651144

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.
@@ -1,12 +1,3 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
1
  import { Subject, firstValueFrom } from 'rxjs';
11
2
  import { tap, first, startWith } from 'rxjs/operators';
12
3
  import { BOT_SPACE_TAG, iteratePartitions, hasValue, asyncResult, addDebugApi, stateUpdatedEvent, registerBuiltinPortal, defineGlobalBot, merge, asyncError, botAdded, botUpdated, createBot, getBotSpace, remapProgressPercent, PartitionAuthSource, action, ON_COLLABORATION_ENABLED, ON_ALLOW_COLLABORATION_UPGRADE, ON_DISALLOW_COLLABORATION_UPGRADE, } from '@casual-simulation/aux-common';
@@ -14,7 +5,7 @@ import { AuxPartitionRealtimeEditModeProvider, AuxRuntime, isPromise, } from '@c
14
5
  import { AuxHelper } from './AuxHelper';
15
6
  import { buildVersionNumber } from './AuxConfig';
16
7
  import { StatusHelper } from './StatusHelper';
17
- import { flatMap, mapKeys, mapValues, pick, transform, } from 'lodash';
8
+ import { flatMap, mapKeys, mapValues, pick, transform } from 'lodash';
18
9
  import { CustomAppHelper } from '../portals/CustomAppHelper';
19
10
  import { v4 as uuid } from 'uuid';
20
11
  export class BaseAuxChannel {
@@ -107,127 +98,117 @@ export class BaseAuxChannel {
107
98
  });
108
99
  addDebugApi('getChannel', () => this);
109
100
  }
110
- init(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage) {
111
- return __awaiter(this, void 0, void 0, function* () {
112
- if (onLocalEvents) {
113
- this.onLocalEvents.subscribe(handleTransferError((e) => onLocalEvents(e), 'onLocalEvents'));
114
- }
115
- if (onStateUpdated) {
116
- this.onStateUpdated.subscribe(handleTransferError((s) => onStateUpdated(s), 'onStateUpdated'));
117
- }
118
- if (onVersionUpdated) {
119
- this.onVersionUpdated.subscribe(handleTransferError((v) => onVersionUpdated(v), 'onVersionUpdated'));
120
- }
121
- if (onConnectionStateChanged) {
122
- this.onConnectionStateChanged.subscribe(handleTransferError((s) => onConnectionStateChanged(s), 'onConnectionStateChanged'));
123
- }
124
- if (onDeviceEvents) {
125
- this.onDeviceEvents.subscribe(handleTransferError((e) => onDeviceEvents(e), 'onDeviceEvents'));
126
- }
127
- if (onSubChannelAdded) {
128
- this.onSubChannelAdded.subscribe(handleTransferError((s) => onSubChannelAdded(s), 'onSubChannelAdded'));
129
- }
130
- if (onSubChannelRemoved) {
131
- this.onSubChannelRemoved.subscribe(handleTransferError((s) => onSubChannelRemoved(s), 'onSubChannelRemoved'));
132
- }
133
- if (onAuthMessage) {
134
- this.onAuthMessage.subscribe(handleTransferError((m) => onAuthMessage(m), 'onAuthMessage'));
135
- }
136
- // if (onError) {
137
- // this.onError.subscribe(onError);
138
- // }
139
- return yield this._init();
140
- });
101
+ async init(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage) {
102
+ if (onLocalEvents) {
103
+ this.onLocalEvents.subscribe(handleTransferError((e) => onLocalEvents(e), 'onLocalEvents'));
104
+ }
105
+ if (onStateUpdated) {
106
+ this.onStateUpdated.subscribe(handleTransferError((s) => onStateUpdated(s), 'onStateUpdated'));
107
+ }
108
+ if (onVersionUpdated) {
109
+ this.onVersionUpdated.subscribe(handleTransferError((v) => onVersionUpdated(v), 'onVersionUpdated'));
110
+ }
111
+ if (onConnectionStateChanged) {
112
+ this.onConnectionStateChanged.subscribe(handleTransferError((s) => onConnectionStateChanged(s), 'onConnectionStateChanged'));
113
+ }
114
+ if (onDeviceEvents) {
115
+ this.onDeviceEvents.subscribe(handleTransferError((e) => onDeviceEvents(e), 'onDeviceEvents'));
116
+ }
117
+ if (onSubChannelAdded) {
118
+ this.onSubChannelAdded.subscribe(handleTransferError((s) => onSubChannelAdded(s), 'onSubChannelAdded'));
119
+ }
120
+ if (onSubChannelRemoved) {
121
+ this.onSubChannelRemoved.subscribe(handleTransferError((s) => onSubChannelRemoved(s), 'onSubChannelRemoved'));
122
+ }
123
+ if (onAuthMessage) {
124
+ this.onAuthMessage.subscribe(handleTransferError((m) => onAuthMessage(m), 'onAuthMessage'));
125
+ }
126
+ // if (onError) {
127
+ // this.onError.subscribe(onError);
128
+ // }
129
+ return await this._init();
130
+ }
131
+ async initAndWait(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage) {
132
+ const promise = firstValueFrom(this.onConnectionStateChanged.pipe(first((s) => s.type === 'init')));
133
+ await this.init(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage);
134
+ await promise;
135
+ }
136
+ async registerListeners(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage) {
137
+ if (onLocalEvents) {
138
+ this.onLocalEvents.subscribe(handleTransferError((e) => onLocalEvents(e), 'onLocalEvents'));
139
+ }
140
+ if (onStateUpdated) {
141
+ this.onStateUpdated
142
+ .pipe(startWith(stateUpdatedEvent(this._helper.botsState)))
143
+ .subscribe(handleTransferError((s) => onStateUpdated(s), 'onStateUpdated'));
144
+ }
145
+ if (onVersionUpdated) {
146
+ this.onVersionUpdated
147
+ .pipe(startWith(this._version))
148
+ .subscribe(handleTransferError((v) => onVersionUpdated(v), 'onVersionUpdated'));
149
+ }
150
+ if (onConnectionStateChanged) {
151
+ this.onConnectionStateChanged
152
+ .pipe(startWith({
153
+ type: 'init',
154
+ }, { type: 'sync', synced: true }))
155
+ .subscribe(handleTransferError((s) => onConnectionStateChanged(s), 'onConnectionStateChanged'));
156
+ }
157
+ if (onDeviceEvents) {
158
+ this.onDeviceEvents.subscribe(handleTransferError((e) => onDeviceEvents(e), 'onDeviceEvents'));
159
+ }
160
+ if (onSubChannelAdded) {
161
+ this.onSubChannelAdded.subscribe(handleTransferError((s) => onSubChannelAdded(s), 'onSubChannelAdded'));
162
+ }
163
+ if (onSubChannelRemoved) {
164
+ this.onSubChannelRemoved.subscribe(handleTransferError((s) => onSubChannelRemoved(s), 'onSubChannelRemoved'));
165
+ }
166
+ if (onAuthMessage) {
167
+ this.onAuthMessage.subscribe(handleTransferError((m) => onAuthMessage(m), 'onAuthMessage'));
168
+ }
141
169
  }
142
- initAndWait(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage) {
143
- return __awaiter(this, void 0, void 0, function* () {
144
- const promise = firstValueFrom(this.onConnectionStateChanged.pipe(first((s) => s.type === 'init')));
145
- yield this.init(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage);
146
- yield promise;
170
+ async _init() {
171
+ this._initStartTime = performance.now();
172
+ this._handleStatusUpdated({
173
+ type: 'progress',
174
+ message: 'Creating causal tree...',
175
+ progress: 0.1,
147
176
  });
148
- }
149
- registerListeners(onLocalEvents, onDeviceEvents, onStateUpdated, onVersionUpdated, onConnectionStateChanged, onError, onSubChannelAdded, onSubChannelRemoved, onAuthMessage) {
150
- return __awaiter(this, void 0, void 0, function* () {
151
- if (onLocalEvents) {
152
- this.onLocalEvents.subscribe(handleTransferError((e) => onLocalEvents(e), 'onLocalEvents'));
153
- }
154
- if (onStateUpdated) {
155
- this.onStateUpdated
156
- .pipe(startWith(stateUpdatedEvent(this._helper.botsState)))
157
- .subscribe(handleTransferError((s) => onStateUpdated(s), 'onStateUpdated'));
158
- }
159
- if (onVersionUpdated) {
160
- this.onVersionUpdated
161
- .pipe(startWith(this._version))
162
- .subscribe(handleTransferError((v) => onVersionUpdated(v), 'onVersionUpdated'));
163
- }
164
- if (onConnectionStateChanged) {
165
- this.onConnectionStateChanged
166
- .pipe(startWith({
167
- type: 'init',
168
- }, { type: 'sync', synced: true }))
169
- .subscribe(handleTransferError((s) => onConnectionStateChanged(s), 'onConnectionStateChanged'));
170
- }
171
- if (onDeviceEvents) {
172
- this.onDeviceEvents.subscribe(handleTransferError((e) => onDeviceEvents(e), 'onDeviceEvents'));
173
- }
174
- if (onSubChannelAdded) {
175
- this.onSubChannelAdded.subscribe(handleTransferError((s) => onSubChannelAdded(s), 'onSubChannelAdded'));
176
- }
177
- if (onSubChannelRemoved) {
178
- this.onSubChannelRemoved.subscribe(handleTransferError((s) => onSubChannelRemoved(s), 'onSubChannelRemoved'));
179
- }
180
- if (onAuthMessage) {
181
- this.onAuthMessage.subscribe(handleTransferError((m) => onAuthMessage(m), 'onAuthMessage'));
182
- }
183
- });
184
- }
185
- _init() {
186
- return __awaiter(this, void 0, void 0, function* () {
187
- this._initStartTime = performance.now();
188
- this._handleStatusUpdated({
189
- type: 'progress',
190
- message: 'Creating causal tree...',
191
- progress: 0.1,
192
- });
193
- this._partitions = {};
194
- this._partitionEditModeProvider =
195
- new AuxPartitionRealtimeEditModeProvider(this._partitions);
196
- this._authSource = new PartitionAuthSource();
197
- this._subs.push(this._authSource.onAuthMessage.subscribe(this._onAuthMessage));
198
- this._services = {
199
- authSource: this._authSource,
200
- };
201
- let partitions = [];
202
- for (let [key, partitionConfig] of iteratePartitions(this._config.partitions)) {
203
- if (!Object.prototype.hasOwnProperty.call(this._config.partitions, key)) {
204
- continue;
205
- }
206
- const partition = yield this._createPartition(partitionConfig, this._services);
207
- if (partition) {
208
- partition.space = key;
209
- this._partitions[key] = partition;
210
- partitions.push(partition);
211
- }
212
- else {
213
- throw new Error(`[BaseAuxChannel] Unable to build partition: ${key}`);
214
- }
177
+ this._partitions = {};
178
+ this._partitionEditModeProvider =
179
+ new AuxPartitionRealtimeEditModeProvider(this._partitions);
180
+ this._authSource = new PartitionAuthSource();
181
+ this._subs.push(this._authSource.onAuthMessage.subscribe(this._onAuthMessage));
182
+ this._services = {
183
+ authSource: this._authSource,
184
+ };
185
+ let partitions = [];
186
+ for (let [key, partitionConfig] of iteratePartitions(this._config.partitions)) {
187
+ const partition = await this._createPartition(partitionConfig, this._services);
188
+ if (partition) {
189
+ partition.space = key;
190
+ this._partitions[key] = partition;
191
+ partitions.push(partition);
215
192
  }
216
- this._statusHelper = new StatusHelper(partitions.map((p) => p.onStatusUpdated));
217
- let statusMapper = remapProgressPercent(0.3, 0.6);
218
- this._subs.push(this._statusHelper, this._statusHelper.updates
219
- .pipe(tap((state) => this._handleStatusUpdated(statusMapper(state))))
220
- .subscribe({ error: (e) => console.error(e) }), ...flatMap(partitions, (p) => this._getCleanupSubscriptionsForPartition(p)));
221
- this._handleStatusUpdated({
222
- type: 'progress',
223
- message: 'Initializing causal tree...',
224
- progress: 0.2,
225
- });
226
- for (let partition of partitions) {
227
- partition.connect();
193
+ else {
194
+ console.error('[BaseAuxChannel] Unable to create partition:', key, partitionConfig);
195
+ throw new Error(`[BaseAuxChannel] Unable to build partition: ${key}`);
228
196
  }
229
- return null;
197
+ }
198
+ this._statusHelper = new StatusHelper(partitions.map((p) => p.onStatusUpdated));
199
+ let statusMapper = remapProgressPercent(0.3, 0.6);
200
+ this._subs.push(this._statusHelper, this._statusHelper.updates
201
+ .pipe(tap((state) => this._handleStatusUpdated(statusMapper(state))))
202
+ .subscribe({ error: (e) => console.error(e) }), ...flatMap(partitions, (p) => this._getCleanupSubscriptionsForPartition(p)));
203
+ this._handleStatusUpdated({
204
+ type: 'progress',
205
+ message: 'Initializing causal tree...',
206
+ progress: 0.2,
230
207
  });
208
+ for (let partition of partitions) {
209
+ partition.connect();
210
+ }
211
+ return null;
231
212
  }
232
213
  _getCleanupSubscriptionsForPartition(partition) {
233
214
  return [
@@ -241,126 +222,106 @@ export class BaseAuxChannel {
241
222
  _getCleanupSubscriptionsForSharedDocument(doc) {
242
223
  return [doc, doc.onError.subscribe((err) => this._handleError(err))];
243
224
  }
244
- sendEvents(events) {
245
- return __awaiter(this, void 0, void 0, function* () {
246
- if (this._hasInitialState) {
247
- if (this._tagNameMapper) {
248
- let mappedEvents = [];
249
- for (let event of events) {
250
- if (event.type === 'update_bot') {
251
- mappedEvents.push(botUpdated(event.id, mapBotTagsAndSpace(event.update, this._tagNameMapper.reverse, (s) => s, null)));
252
- }
253
- else if (event.type === 'add_bot') {
254
- mappedEvents.push(botAdded(mapBotTagsAndSpace(event.bot, this._tagNameMapper.reverse, (s) => s, 'shared')));
255
- }
256
- else {
257
- mappedEvents.push(event);
258
- }
225
+ async sendEvents(events) {
226
+ if (this._hasInitialState) {
227
+ if (this._tagNameMapper) {
228
+ let mappedEvents = [];
229
+ for (let event of events) {
230
+ if (event.type === 'update_bot') {
231
+ mappedEvents.push(botUpdated(event.id, mapBotTagsAndSpace(event.update, this._tagNameMapper.reverse, (s) => s, null)));
232
+ }
233
+ else if (event.type === 'add_bot') {
234
+ mappedEvents.push(botAdded(mapBotTagsAndSpace(event.bot, this._tagNameMapper.reverse, (s) => s, 'shared')));
235
+ }
236
+ else {
237
+ mappedEvents.push(event);
259
238
  }
260
- events = mappedEvents;
261
239
  }
262
- yield this._helper.transaction(...events);
263
- }
264
- else {
265
- this._eventBuffer.push(...events);
266
- }
267
- });
268
- }
269
- shout(eventName, botIds, arg) {
270
- return __awaiter(this, void 0, void 0, function* () {
271
- if (!this._runtime) {
272
- throw new Error('Unable to execute a shout without being initialized.');
240
+ events = mappedEvents;
273
241
  }
274
- const result = this._runtime.shout(eventName, botIds, arg);
275
- const final = isPromise(result) ? yield result : result;
276
- return {
277
- actions: final.actions,
278
- results: yield Promise.all(final.results),
279
- };
280
- });
242
+ await this._helper.transaction(...events);
243
+ }
244
+ else {
245
+ this._eventBuffer.push(...events);
246
+ }
281
247
  }
282
- formulaBatch(formulas) {
283
- return __awaiter(this, void 0, void 0, function* () {
284
- return this._helper.formulaBatch(formulas);
285
- });
248
+ async shout(eventName, botIds, arg) {
249
+ if (!this._runtime) {
250
+ throw new Error('Unable to execute a shout without being initialized.');
251
+ }
252
+ const result = this._runtime.shout(eventName, botIds, arg);
253
+ const final = isPromise(result) ? await result : result;
254
+ return {
255
+ actions: final.actions,
256
+ results: await Promise.all(final.results),
257
+ };
286
258
  }
287
- forkAux(newId) {
288
- return __awaiter(this, void 0, void 0, function* () { });
259
+ async formulaBatch(formulas) {
260
+ return this._helper.formulaBatch(formulas);
289
261
  }
290
- exportBots(botIds) {
291
- return __awaiter(this, void 0, void 0, function* () {
292
- return this._helper.exportBots(botIds);
293
- });
262
+ async forkAux(newId) { }
263
+ async exportBots(botIds) {
264
+ return this._helper.exportBots(botIds);
294
265
  }
295
266
  /**
296
267
  * Exports the causal tree for the simulation.
297
268
  */
298
- export() {
299
- return __awaiter(this, void 0, void 0, function* () {
300
- let final = {};
301
- const state = this._helper.publicBotsState;
302
- for (let key in state) {
303
- const bot = state[key];
304
- final[key] = pick(bot, 'id', 'tags', BOT_SPACE_TAG);
305
- }
306
- return {
307
- version: 1,
308
- state: final,
309
- };
310
- });
269
+ async export() {
270
+ let final = {};
271
+ const state = this._helper.publicBotsState;
272
+ for (let key in state) {
273
+ const bot = state[key];
274
+ final[key] = pick(bot, 'id', 'tags', BOT_SPACE_TAG);
275
+ }
276
+ return {
277
+ version: 1,
278
+ state: final,
279
+ };
311
280
  }
312
- getTags() {
313
- return __awaiter(this, void 0, void 0, function* () {
314
- return this._helper.getTags();
315
- });
281
+ async getTags() {
282
+ return this._helper.getTags();
316
283
  }
317
- updateDevice(device) {
318
- return __awaiter(this, void 0, void 0, function* () {
319
- let previousDevice = this._config.config.device;
320
- this._config.config.device = device;
321
- if (this._runtime) {
322
- this._runtime.context.device = device;
323
- }
324
- if (this._helper) {
325
- if (!previousDevice.isCollaborative) {
326
- if (!device.isCollaborative) {
327
- if (device.allowCollaborationUpgrade &&
328
- !previousDevice.allowCollaborationUpgrade) {
329
- yield this.sendEvents([
330
- action(ON_ALLOW_COLLABORATION_UPGRADE),
331
- ]);
332
- }
333
- else if (!device.allowCollaborationUpgrade &&
334
- previousDevice.allowCollaborationUpgrade) {
335
- yield this.sendEvents([
336
- action(ON_DISALLOW_COLLABORATION_UPGRADE),
337
- ]);
338
- }
284
+ async updateDevice(device) {
285
+ let previousDevice = this._config.config.device;
286
+ this._config.config.device = device;
287
+ if (this._runtime) {
288
+ this._runtime.context.device = device;
289
+ }
290
+ if (this._helper) {
291
+ if (!previousDevice.isCollaborative) {
292
+ if (!device.isCollaborative) {
293
+ if (device.allowCollaborationUpgrade &&
294
+ !previousDevice.allowCollaborationUpgrade) {
295
+ await this.sendEvents([
296
+ action(ON_ALLOW_COLLABORATION_UPGRADE),
297
+ ]);
339
298
  }
340
- else {
341
- yield this.sendEvents([action(ON_COLLABORATION_ENABLED)]);
299
+ else if (!device.allowCollaborationUpgrade &&
300
+ previousDevice.allowCollaborationUpgrade) {
301
+ await this.sendEvents([
302
+ action(ON_DISALLOW_COLLABORATION_UPGRADE),
303
+ ]);
342
304
  }
343
305
  }
306
+ else {
307
+ await this.sendEvents([action(ON_COLLABORATION_ENABLED)]);
308
+ }
344
309
  }
345
- });
310
+ }
346
311
  }
347
- sendAuthMessage(message) {
348
- return __awaiter(this, void 0, void 0, function* () {
349
- this._authSource.sendAuthMessage(message);
350
- });
312
+ async sendAuthMessage(message) {
313
+ this._authSource.sendAuthMessage(message);
351
314
  }
352
315
  /**
353
316
  * Sends the given list of remote events to their destinations.
354
317
  * @param events The events.
355
318
  */
356
- _sendRemoteEvents(events) {
357
- return __awaiter(this, void 0, void 0, function* () {
358
- for (let [, partition] of iteratePartitions(this._partitions)) {
359
- if (partition.sendRemoteEvents) {
360
- yield partition.sendRemoteEvents(events);
361
- }
319
+ async _sendRemoteEvents(events) {
320
+ for (let [, partition] of iteratePartitions(this._partitions)) {
321
+ if (partition.sendRemoteEvents) {
322
+ await partition.sendRemoteEvents(events);
362
323
  }
363
- });
324
+ }
364
325
  }
365
326
  _createAuxHelper() {
366
327
  const partitions = this._partitions;
@@ -416,73 +377,67 @@ export class BaseAuxChannel {
416
377
  }))
417
378
  .subscribe({ error: (e) => console.error(e) }));
418
379
  }
419
- _ensureSetup() {
420
- return __awaiter(this, void 0, void 0, function* () {
421
- // console.log('[AuxChannel] Got Tree:', this._aux.tree.site.id);
422
- if (!this._runtime) {
423
- this._runtime = this._createRuntime();
424
- this._subs.push(this._runtime);
425
- }
426
- if (!this._helper) {
427
- this._helper = this._createAuxHelper();
428
- }
429
- if (!this._portalHelper) {
430
- this._portalHelper = new CustomAppHelper(this._helper);
431
- }
432
- if (!this._timeSync) {
433
- this._timeSync = this._createTimeSyncController();
434
- }
435
- this._handleStatusUpdated({
436
- type: 'progress',
437
- message: 'Initializing user bot...',
438
- progress: 0.8,
439
- });
440
- yield this._initUserBot();
441
- this._handleStatusUpdated({
442
- type: 'progress',
443
- message: 'Launching interface...',
444
- progress: 0.9,
445
- });
446
- if (!this._hasRegisteredSubs) {
447
- this._hasRegisteredSubs = true;
448
- this._registerSubscriptions();
449
- }
450
- yield this._initPortalBots();
451
- yield this._initBuilderBots();
452
- this._runtime.context.setLoadTime('load', performance.now() - this._initStartTime);
453
- console.log('[BaseAuxChannel] Sending init event');
454
- this._onConnectionStateChanged.next({
455
- type: 'init',
456
- });
380
+ async _ensureSetup() {
381
+ // console.log('[AuxChannel] Got Tree:', this._aux.tree.site.id);
382
+ if (!this._runtime) {
383
+ this._runtime = this._createRuntime();
384
+ this._subs.push(this._runtime);
385
+ }
386
+ if (!this._helper) {
387
+ this._helper = this._createAuxHelper();
388
+ }
389
+ if (!this._portalHelper) {
390
+ this._portalHelper = new CustomAppHelper(this._helper);
391
+ }
392
+ if (!this._timeSync) {
393
+ this._timeSync = this._createTimeSyncController();
394
+ }
395
+ this._handleStatusUpdated({
396
+ type: 'progress',
397
+ message: 'Initializing user bot...',
398
+ progress: 0.8,
457
399
  });
458
- }
459
- _handleStatusUpdated(state) {
460
- return __awaiter(this, void 0, void 0, function* () {
461
- if (state.type === 'progress') {
462
- console.log(`[BaseAuxChannel] Loading Progress (${state.progress * 100}%): ${state.message}`);
463
- }
464
- if (state.type === 'authentication') {
465
- console.log(`[BaseAuxChannel] Authentication (${state.authenticated}):`, state.info);
466
- this._deviceInfo = state.info;
467
- }
468
- else if (state.type === 'sync' && state.synced) {
469
- console.log(`[BaseAuxChannel] Sync (${state.synced})`);
470
- yield this._ensureSetup();
471
- }
472
- this._onConnectionStateChanged.next(state);
400
+ await this._initUserBot();
401
+ this._handleStatusUpdated({
402
+ type: 'progress',
403
+ message: 'Launching interface...',
404
+ progress: 0.9,
405
+ });
406
+ if (!this._hasRegisteredSubs) {
407
+ this._hasRegisteredSubs = true;
408
+ this._registerSubscriptions();
409
+ }
410
+ await this._initPortalBots();
411
+ await this._initBuilderBots();
412
+ this._runtime.context.setLoadTime('load', performance.now() - this._initStartTime);
413
+ console.log('[BaseAuxChannel] Sending init event');
414
+ this._onConnectionStateChanged.next({
415
+ type: 'init',
473
416
  });
474
417
  }
418
+ async _handleStatusUpdated(state) {
419
+ if (state.type === 'progress') {
420
+ console.log(`[BaseAuxChannel] Loading Progress (${state.progress * 100}%): ${state.message}`);
421
+ }
422
+ if (state.type === 'authentication') {
423
+ console.log(`[BaseAuxChannel] Authentication (${state.authenticated}):`, state.info);
424
+ this._deviceInfo = state.info;
425
+ }
426
+ else if (state.type === 'sync' && state.synced) {
427
+ console.log(`[BaseAuxChannel] Sync (${state.synced})`);
428
+ await this._ensureSetup();
429
+ }
430
+ this._onConnectionStateChanged.next(state);
431
+ }
475
432
  /**
476
433
  * Decides what to do with device events from partitions.
477
434
  * By default the events are processed as-is.
478
435
  * This means that the events are sent directly to the AuxHelper via this.sendEvents().
479
436
  * @param events The events.
480
437
  */
481
- _handlePartitionEvents(events) {
482
- return __awaiter(this, void 0, void 0, function* () {
483
- const actions = events;
484
- yield this.sendEvents(actions);
485
- });
438
+ async _handlePartitionEvents(events) {
439
+ const actions = events;
440
+ await this.sendEvents(actions);
486
441
  }
487
442
  _handleStateUpdated(event) {
488
443
  this._onStateUpdated.next(event);
@@ -528,83 +483,79 @@ export class BaseAuxChannel {
528
483
  const copiableEvents = e.filter((e) => !e.uncopiable);
529
484
  this._onLocalEvents.next(copiableEvents);
530
485
  }
531
- _enableCollaboration(event) {
532
- return __awaiter(this, void 0, void 0, function* () {
533
- try {
534
- if (!this._runtime.context.device) {
535
- if (hasValue(event.taskId)) {
536
- this.sendEvents([asyncResult(event.taskId, null)]);
537
- }
538
- return;
539
- }
540
- if (this._runtime.context.device.isCollaborative) {
541
- if (hasValue(event.taskId)) {
542
- this.sendEvents([asyncResult(event.taskId, null)]);
543
- }
544
- return;
545
- }
546
- if (!this._runtime.context.device.allowCollaborationUpgrade) {
547
- if (hasValue(event.taskId)) {
548
- this.sendEvents([
549
- asyncError(event.taskId, new Error('Collaboration upgrades are not allowed.')),
550
- ]);
551
- }
552
- return;
553
- }
554
- let promises = [];
555
- for (let [_, partition] of iteratePartitions(this._partitions)) {
556
- if (partition.enableCollaboration) {
557
- promises.push(partition.enableCollaboration());
558
- }
559
- }
560
- yield Promise.all(promises);
561
- this._runtime.context.device.isCollaborative = true;
562
- this._runtime.context.device.allowCollaborationUpgrade = false;
486
+ async _enableCollaboration(event) {
487
+ try {
488
+ if (!this._runtime.context.device) {
563
489
  if (hasValue(event.taskId)) {
564
490
  this.sendEvents([asyncResult(event.taskId, null)]);
565
491
  }
566
- this.sendEvents([action(ON_COLLABORATION_ENABLED)]);
492
+ return;
567
493
  }
568
- catch (err) {
569
- console.error('[BaseAuxChannel] Error enabling collaboration', err);
494
+ if (this._runtime.context.device.isCollaborative) {
570
495
  if (hasValue(event.taskId)) {
571
- this.sendEvents([asyncError(event.taskId, err)]);
496
+ this.sendEvents([asyncResult(event.taskId, null)]);
572
497
  }
498
+ return;
573
499
  }
574
- });
575
- }
576
- _handleDeviceEvents(e) {
577
- this._onDeviceEvents.next(e);
578
- }
579
- _loadPartition(space, config, event) {
580
- return __awaiter(this, void 0, void 0, function* () {
581
- if (space in this._partitions) {
582
- console.log(`[BaseAuxChannel] Cannot load partition for "${space}" since the space is already occupied`);
500
+ if (!this._runtime.context.device.allowCollaborationUpgrade) {
583
501
  if (hasValue(event.taskId)) {
584
- this.sendEvents([asyncResult(event.taskId, null)]);
502
+ this.sendEvents([
503
+ asyncError(event.taskId, new Error('Collaboration upgrades are not allowed.')),
504
+ ]);
585
505
  }
586
506
  return;
587
507
  }
588
- let partition = yield this._createPartition(config, this._services);
589
- if (!partition) {
590
- return;
508
+ let promises = [];
509
+ for (let [_, partition] of iteratePartitions(this._partitions)) {
510
+ if (partition.enableCollaboration) {
511
+ promises.push(partition.enableCollaboration());
512
+ }
591
513
  }
592
- this._partitions[space] = partition;
593
- this.helper.addPartition(space, partition);
594
- this._subs.push(...this._getCleanupSubscriptionsForPartition(partition));
514
+ await Promise.all(promises);
515
+ this._runtime.context.device.isCollaborative = true;
516
+ this._runtime.context.device.allowCollaborationUpgrade = false;
595
517
  if (hasValue(event.taskId)) {
596
- // Wait for initial connection
597
- partition.onStatusUpdated
598
- .pipe(first((status) => status.type === 'sync' && status.synced === true))
599
- .subscribe(() => {
600
- this.sendEvents([asyncResult(event.taskId, null)]);
601
- });
518
+ this.sendEvents([asyncResult(event.taskId, null)]);
602
519
  }
603
- partition.connect();
604
- if (this._hasRegisteredSubs) {
605
- this._registerStateSubscriptionsForPartition(partition, this._runtime);
520
+ this.sendEvents([action(ON_COLLABORATION_ENABLED)]);
521
+ }
522
+ catch (err) {
523
+ console.error('[BaseAuxChannel] Error enabling collaboration', err);
524
+ if (hasValue(event.taskId)) {
525
+ this.sendEvents([asyncError(event.taskId, err)]);
606
526
  }
607
- });
527
+ }
528
+ }
529
+ _handleDeviceEvents(e) {
530
+ this._onDeviceEvents.next(e);
531
+ }
532
+ async _loadPartition(space, config, event) {
533
+ if (space in this._partitions) {
534
+ console.log(`[BaseAuxChannel] Cannot load partition for "${space}" since the space is already occupied`);
535
+ if (hasValue(event.taskId)) {
536
+ this.sendEvents([asyncResult(event.taskId, null)]);
537
+ }
538
+ return;
539
+ }
540
+ let partition = await this._createPartition(config, this._services);
541
+ if (!partition) {
542
+ return;
543
+ }
544
+ this._partitions[space] = partition;
545
+ this.helper.addPartition(space, partition);
546
+ this._subs.push(...this._getCleanupSubscriptionsForPartition(partition));
547
+ if (hasValue(event.taskId)) {
548
+ // Wait for initial connection
549
+ partition.onStatusUpdated
550
+ .pipe(first((status) => status.type === 'sync' && status.synced === true))
551
+ .subscribe(() => {
552
+ this.sendEvents([asyncResult(event.taskId, null)]);
553
+ });
554
+ }
555
+ partition.connect();
556
+ if (this._hasRegisteredSubs) {
557
+ this._registerStateSubscriptionsForPartition(partition, this._runtime);
558
+ }
608
559
  }
609
560
  /**
610
561
  * Gets the ID of the shared document that should be loaded.
@@ -619,139 +570,133 @@ export class BaseAuxChannel {
619
570
  }
620
571
  return null;
621
572
  }
622
- _loadSharedDocument(event) {
623
- return __awaiter(this, void 0, void 0, function* () {
624
- const id = this._getSharedDocId(event);
625
- if (id) {
626
- const doc = this._documents.get(id);
627
- if (doc && !doc.closed) {
628
- if (hasValue(event.taskId)) {
629
- this.sendEvents([
630
- asyncResult(event.taskId, doc, false, true),
631
- ]);
632
- }
633
- return;
634
- }
635
- }
636
- const config = {
637
- recordName: event.recordName,
638
- inst: event.inst,
639
- branch: event.branch,
640
- host: this._config.config.causalRepoConnectionUrl,
641
- connectionProtocol: this._config.config.causalRepoConnectionProtocol,
642
- };
643
- if (!hasValue(event.inst) && hasValue(event.branch)) {
644
- config.localPersistence = {
645
- saveToIndexedDb: true,
646
- };
647
- }
648
- let doc = yield this._createSharedDocument(config, this._services);
649
- if (!doc) {
650
- return;
651
- }
652
- if (id) {
653
- this._documents.set(id, doc);
654
- }
655
- this._subs.push(...this._getCleanupSubscriptionsForSharedDocument(doc));
656
- if (hasValue(event.taskId)) {
657
- // Wait for initial connection
658
- doc.onStatusUpdated
659
- .pipe(first((status) => status.type === 'sync' && status.synced === true))
660
- .subscribe(() => {
573
+ async _loadSharedDocument(event) {
574
+ const id = this._getSharedDocId(event);
575
+ if (id) {
576
+ const doc = this._documents.get(id);
577
+ if (doc && !doc.closed) {
578
+ if (hasValue(event.taskId)) {
661
579
  this.sendEvents([
662
580
  asyncResult(event.taskId, doc, false, true),
663
581
  ]);
664
- });
582
+ }
583
+ return;
665
584
  }
666
- doc.connect();
667
- });
585
+ }
586
+ const config = {
587
+ recordName: event.recordName,
588
+ inst: event.inst,
589
+ branch: event.branch,
590
+ host: this._config.config.causalRepoConnectionUrl,
591
+ connectionProtocol: this._config.config.causalRepoConnectionProtocol,
592
+ };
593
+ if (!hasValue(event.inst) && hasValue(event.branch)) {
594
+ config.localPersistence = {
595
+ saveToIndexedDb: true,
596
+ };
597
+ }
598
+ let doc = await this._createSharedDocument(config, this._services);
599
+ if (!doc) {
600
+ return;
601
+ }
602
+ if (id) {
603
+ this._documents.set(id, doc);
604
+ }
605
+ this._subs.push(...this._getCleanupSubscriptionsForSharedDocument(doc));
606
+ if (hasValue(event.taskId)) {
607
+ // Wait for initial connection
608
+ doc.onStatusUpdated
609
+ .pipe(first((status) => status.type === 'sync' && status.synced === true))
610
+ .subscribe(() => {
611
+ this.sendEvents([
612
+ asyncResult(event.taskId, doc, false, true),
613
+ ]);
614
+ });
615
+ }
616
+ doc.connect();
668
617
  }
669
- _attachRuntime(runtime, event) {
670
- return __awaiter(this, void 0, void 0, function* () {
671
- try {
672
- const newConfigBotId = uuid();
673
- const channelId = uuid();
674
- let initialStates = {};
675
- for (let id in runtime.currentState) {
676
- const bot = runtime.currentState[id];
677
- const space = getBotSpace(bot);
678
- if (!initialStates[space]) {
679
- initialStates[space] = {};
680
- }
681
- initialStates[space][id] = createBot(id, bot.tags, space);
618
+ async _attachRuntime(runtime, event) {
619
+ try {
620
+ const newConfigBotId = uuid();
621
+ const channelId = uuid();
622
+ let initialStates = {};
623
+ for (let id in runtime.currentState) {
624
+ const bot = runtime.currentState[id];
625
+ const space = getBotSpace(bot);
626
+ if (!initialStates[space]) {
627
+ initialStates[space] = {};
682
628
  }
683
- const partitions = mapValues(this._config.partitions, (p, space) => {
684
- var _a;
685
- return {
686
- type: 'memory',
687
- initialState: (_a = initialStates[space]) !== null && _a !== void 0 ? _a : {},
688
- };
689
- });
690
- const channel = this._createSubChannel(runtime, {
691
- configBotId: newConfigBotId,
692
- config: Object.assign({}, this._config.config),
693
- // Map all partitions to memory partitions for now
694
- partitions,
695
- });
696
- channel._runtime.userId = newConfigBotId;
697
- channel._tagNameMapper = this._createTagNameMapper(event.tagNameMapper);
698
- const subChannel = {
699
- getInfo: () => __awaiter(this, void 0, void 0, function* () {
700
- return ({
701
- id: channelId,
702
- configBotId: newConfigBotId,
703
- indicator: {
704
- connectionId: newConfigBotId,
705
- },
706
- });
707
- }),
708
- getChannel: () => __awaiter(this, void 0, void 0, function* () { return channel; }),
629
+ initialStates[space][id] = createBot(id, bot.tags, space);
630
+ }
631
+ const partitions = mapValues(this._config.partitions, (p, space) => {
632
+ var _a;
633
+ return {
634
+ type: 'memory',
635
+ initialState: (_a = initialStates[space]) !== null && _a !== void 0 ? _a : {},
709
636
  };
710
- this._subChannels.push({
711
- channel,
637
+ });
638
+ const channel = this._createSubChannel(runtime, {
639
+ configBotId: newConfigBotId,
640
+ config: {
641
+ ...this._config.config,
642
+ },
643
+ // Map all partitions to memory partitions for now
644
+ partitions,
645
+ });
646
+ channel._runtime.userId = newConfigBotId;
647
+ channel._tagNameMapper = this._createTagNameMapper(event.tagNameMapper);
648
+ const subChannel = {
649
+ getInfo: async () => ({
712
650
  id: channelId,
713
- });
714
- this._subs.push(channel);
715
- this._handleSubChannelAdded(subChannel);
716
- if (hasValue(event.taskId)) {
717
- this.sendEvents([asyncResult(event.taskId, null)]);
718
- }
651
+ configBotId: newConfigBotId,
652
+ indicator: {
653
+ connectionId: newConfigBotId,
654
+ },
655
+ }),
656
+ getChannel: async () => channel,
657
+ };
658
+ this._subChannels.push({
659
+ channel,
660
+ id: channelId,
661
+ });
662
+ this._subs.push(channel);
663
+ this._handleSubChannelAdded(subChannel);
664
+ if (hasValue(event.taskId)) {
665
+ this.sendEvents([asyncResult(event.taskId, null)]);
719
666
  }
720
- catch (err) {
721
- if (hasValue(event.taskId)) {
722
- this.sendEvents([asyncError(event.taskId, err)]);
723
- }
667
+ }
668
+ catch (err) {
669
+ if (hasValue(event.taskId)) {
670
+ this.sendEvents([asyncError(event.taskId, err)]);
724
671
  }
725
- });
672
+ }
726
673
  }
727
- _detachRuntime(runtime, event) {
728
- return __awaiter(this, void 0, void 0, function* () {
729
- try {
730
- const index = this._subChannels.findIndex((c) => c.channel._runtime === runtime);
731
- if (index < 0) {
732
- if (hasValue(event.taskId)) {
733
- this.sendEvents([asyncResult(event.taskId, null)]);
734
- }
735
- return;
736
- }
737
- const { channel, id } = this._subChannels[index];
738
- channel.unsubscribe();
739
- this._subChannels.splice(index, 1);
740
- const subIndex = this._subs.indexOf(channel);
741
- if (subIndex >= 0) {
742
- this._subs.splice(subIndex, 1);
743
- }
744
- this._handleSubChannelRemoved(id);
674
+ async _detachRuntime(runtime, event) {
675
+ try {
676
+ const index = this._subChannels.findIndex((c) => c.channel._runtime === runtime);
677
+ if (index < 0) {
745
678
  if (hasValue(event.taskId)) {
746
679
  this.sendEvents([asyncResult(event.taskId, null)]);
747
680
  }
681
+ return;
748
682
  }
749
- catch (err) {
750
- if (hasValue(event.taskId)) {
751
- this.sendEvents([asyncError(event.taskId, err)]);
752
- }
683
+ const { channel, id } = this._subChannels[index];
684
+ channel.unsubscribe();
685
+ this._subChannels.splice(index, 1);
686
+ const subIndex = this._subs.indexOf(channel);
687
+ if (subIndex >= 0) {
688
+ this._subs.splice(subIndex, 1);
753
689
  }
754
- });
690
+ this._handleSubChannelRemoved(id);
691
+ if (hasValue(event.taskId)) {
692
+ this.sendEvents([asyncResult(event.taskId, null)]);
693
+ }
694
+ }
695
+ catch (err) {
696
+ if (hasValue(event.taskId)) {
697
+ this.sendEvents([asyncError(event.taskId, err)]);
698
+ }
699
+ }
755
700
  }
756
701
  _handleSubChannelAdded(subChannel) {
757
702
  this._onSubChannelAdded.next(subChannel);
@@ -817,7 +762,9 @@ export class BaseAuxChannel {
817
762
  }
818
763
  _mapTagAndSpaceNames(update, tagNameMapper) {
819
764
  const u = {
820
- state: Object.assign({}, update.state),
765
+ state: {
766
+ ...update.state,
767
+ },
821
768
  addedBots: update.addedBots,
822
769
  removedBots: update.removedBots,
823
770
  updatedBots: update.updatedBots,
@@ -831,61 +778,55 @@ export class BaseAuxChannel {
831
778
  }
832
779
  return u;
833
780
  }
834
- _initUserBot() {
835
- return __awaiter(this, void 0, void 0, function* () {
836
- try {
837
- const userBot = this._helper.userBot;
838
- yield this._helper.createOrUpdateUserBot(this._config.configBotId, userBot);
839
- }
840
- catch (err) {
841
- console.error('[BaseAuxChannel] Unable to init user bot:', err);
842
- }
843
- });
781
+ async _initUserBot() {
782
+ try {
783
+ const userBot = this._helper.userBot;
784
+ await this._helper.createOrUpdateUserBot(this._config.configBotId, userBot);
785
+ }
786
+ catch (err) {
787
+ console.error('[BaseAuxChannel] Unable to init user bot:', err);
788
+ }
844
789
  }
845
- _initPortalBots() {
790
+ async _initPortalBots() {
846
791
  var _a, _b;
847
- return __awaiter(this, void 0, void 0, function* () {
792
+ try {
793
+ if (((_a = this._config.config) === null || _a === void 0 ? void 0 : _a.builtinPortals) &&
794
+ ((_b = this._config.config) === null || _b === void 0 ? void 0 : _b.builtinPortals.length) > 0) {
795
+ let actions = this._config.config.builtinPortals.map((portal) => registerBuiltinPortal(portal));
796
+ this._runtime.process([
797
+ ...actions,
798
+ // Define the authBot with a random UUID so that it will be
799
+ // referencable but return undefined until it is actually loaded.
800
+ defineGlobalBot('auth', uuid()),
801
+ ]);
802
+ }
803
+ }
804
+ catch (err) {
805
+ console.error('[BaseAuxChannel] Unable to init portal bots:', err);
806
+ }
807
+ }
808
+ async _initBuilderBots() {
809
+ if (!this._config ||
810
+ !this._config.config ||
811
+ !this._config.config.builder) {
812
+ return;
813
+ }
814
+ if (!!this._config.config.bootstrapState) {
848
815
  try {
849
- if (((_a = this._config.config) === null || _a === void 0 ? void 0 : _a.builtinPortals) &&
850
- ((_b = this._config.config) === null || _b === void 0 ? void 0 : _b.builtinPortals.length) > 0) {
851
- let actions = this._config.config.builtinPortals.map((portal) => registerBuiltinPortal(portal));
852
- this._runtime.process([
853
- ...actions,
854
- // Define the authBot with a random UUID so that it will be
855
- // referencable but return undefined until it is actually loaded.
856
- defineGlobalBot('auth', uuid()),
857
- ]);
858
- }
816
+ await this._helper.destroyBuilderBots(this._config.config.builder);
859
817
  }
860
818
  catch (err) {
861
- console.error('[BaseAuxChannel] Unable to init portal bots:', err);
862
- }
863
- });
864
- }
865
- _initBuilderBots() {
866
- return __awaiter(this, void 0, void 0, function* () {
867
- if (!this._config ||
868
- !this._config.config ||
869
- !this._config.config.builder) {
870
- return;
819
+ console.error('[BaseAuxChannel] Unable to destroy builder bot:', err);
871
820
  }
872
- if (!!this._config.config.bootstrapState) {
873
- try {
874
- yield this._helper.destroyBuilderBots(this._config.config.builder);
875
- }
876
- catch (err) {
877
- console.error('[BaseAuxChannel] Unable to destroy builder bot:', err);
878
- }
821
+ }
822
+ else {
823
+ try {
824
+ await this._helper.createOrUpdateBuilderBots(this._config.config.builder);
879
825
  }
880
- else {
881
- try {
882
- yield this._helper.createOrUpdateBuilderBots(this._config.config.builder);
883
- }
884
- catch (err) {
885
- console.error('[BaseAuxChannel] Unable to init builder bot:', err);
886
- }
826
+ catch (err) {
827
+ console.error('[BaseAuxChannel] Unable to init builder bot:', err);
887
828
  }
888
- });
829
+ }
889
830
  }
890
831
  unsubscribe() {
891
832
  if (this.closed) {