@dxos/echo-db 2.29.2-dev.8c2ad8e5 → 2.29.2-dev.f6ed60b8

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 (89) hide show
  1. package/dist/src/api/database.d.ts +11 -7
  2. package/dist/src/api/database.d.ts.map +1 -1
  3. package/dist/src/api/database.js +22 -24
  4. package/dist/src/api/database.js.map +1 -1
  5. package/dist/src/api/database.test.js +13 -13
  6. package/dist/src/api/database.test.js.map +1 -1
  7. package/dist/src/api/item.d.ts.map +1 -1
  8. package/dist/src/api/item.js +1 -1
  9. package/dist/src/api/item.js.map +1 -1
  10. package/dist/src/api/result-set.d.ts.map +1 -1
  11. package/dist/src/api/result-set.js +1 -0
  12. package/dist/src/api/result-set.js.map +1 -1
  13. package/dist/src/api/selection/index.d.ts +5 -0
  14. package/dist/src/api/selection/index.d.ts.map +1 -0
  15. package/dist/src/api/selection/index.js +20 -0
  16. package/dist/src/api/selection/index.js.map +1 -0
  17. package/dist/src/api/selection/queries.d.ts +51 -0
  18. package/dist/src/api/selection/queries.d.ts.map +1 -0
  19. package/dist/src/api/selection/queries.js +70 -0
  20. package/dist/src/api/selection/queries.js.map +1 -0
  21. package/dist/src/api/selection/result.d.ts +50 -0
  22. package/dist/src/api/selection/result.d.ts.map +1 -0
  23. package/dist/src/api/selection/result.js +91 -0
  24. package/dist/src/api/selection/result.js.map +1 -0
  25. package/dist/src/api/selection/selection.d.ts +96 -0
  26. package/dist/src/api/selection/selection.d.ts.map +1 -0
  27. package/dist/src/api/selection/selection.js +164 -0
  28. package/dist/src/api/selection/selection.js.map +1 -0
  29. package/dist/src/api/{selection.test.d.ts → selection/selection.test.d.ts} +0 -0
  30. package/dist/src/api/selection/selection.test.d.ts.map +1 -0
  31. package/dist/src/api/{selection.test.js → selection/selection.test.js} +46 -44
  32. package/dist/src/api/selection/selection.test.js.map +1 -0
  33. package/dist/src/api/selection/util.d.ts +7 -0
  34. package/dist/src/api/selection/util.d.ts.map +1 -0
  35. package/dist/src/api/selection/util.js +25 -0
  36. package/dist/src/api/selection/util.js.map +1 -0
  37. package/dist/src/echo.test.js +20 -20
  38. package/dist/src/echo.test.js.map +1 -1
  39. package/dist/src/halo/contact-manager.js +2 -2
  40. package/dist/src/halo/contact-manager.js.map +1 -1
  41. package/dist/src/halo/halo.d.ts +1 -1
  42. package/dist/src/halo/halo.d.ts.map +1 -1
  43. package/dist/src/halo/halo.js +2 -2
  44. package/dist/src/halo/halo.js.map +1 -1
  45. package/dist/src/halo/preferences.js +6 -6
  46. package/dist/src/halo/preferences.js.map +1 -1
  47. package/dist/src/parties/party-core.test.js +3 -3
  48. package/dist/src/parties/party-core.test.js.map +1 -1
  49. package/dist/src/parties/party-factory.d.ts.map +1 -1
  50. package/dist/src/parties/party-factory.js +3 -3
  51. package/dist/src/parties/party-factory.js.map +1 -1
  52. package/dist/src/parties/party-internal.js +3 -3
  53. package/dist/src/parties/party-internal.js.map +1 -1
  54. package/dist/src/parties/party-manager.js +1 -1
  55. package/dist/src/parties/party-manager.js.map +1 -1
  56. package/dist/src/parties/party-manager.test.js +8 -10
  57. package/dist/src/parties/party-manager.test.js.map +1 -1
  58. package/dist/src/testing/testing-factories.d.ts +2 -2
  59. package/dist/src/testing/testing-factories.d.ts.map +1 -1
  60. package/dist/src/testing/testing-factories.js +1 -1
  61. package/dist/src/testing/testing-factories.js.map +1 -1
  62. package/dist/tsconfig.tsbuildinfo +1 -1
  63. package/package.json +17 -17
  64. package/src/api/database.test.ts +13 -13
  65. package/src/api/database.ts +30 -30
  66. package/src/api/item.ts +2 -2
  67. package/src/api/result-set.ts +1 -0
  68. package/src/api/selection/index.ts +8 -0
  69. package/src/api/selection/queries.ts +108 -0
  70. package/src/api/selection/result.ts +112 -0
  71. package/src/api/{selection.test.ts → selection/selection.test.ts} +50 -48
  72. package/src/api/{selection.ts → selection/selection.ts} +30 -231
  73. package/src/api/selection/util.ts +27 -0
  74. package/src/echo.test.ts +20 -20
  75. package/src/halo/contact-manager.ts +2 -2
  76. package/src/halo/halo.ts +2 -3
  77. package/src/halo/preferences.ts +6 -6
  78. package/src/parties/party-core.test.ts +3 -3
  79. package/src/parties/party-factory.ts +3 -4
  80. package/src/parties/party-internal.ts +3 -3
  81. package/src/parties/party-manager.test.ts +8 -10
  82. package/src/parties/party-manager.ts +1 -1
  83. package/src/testing/testing-factories.ts +3 -3
  84. package/dist/src/api/selection.d.ts +0 -183
  85. package/dist/src/api/selection.d.ts.map +0 -1
  86. package/dist/src/api/selection.js +0 -308
  87. package/dist/src/api/selection.js.map +0 -1
  88. package/dist/src/api/selection.test.d.ts.map +0 -1
  89. package/dist/src/api/selection.test.js.map +0 -1
@@ -2,82 +2,23 @@
2
2
  // Copyright 2020 DXOS.org
3
3
  //
4
4
 
5
- import assert from 'assert';
6
-
7
5
  import { Event } from '@dxos/async';
8
- import { ItemID } from '@dxos/echo-protocol';
9
-
10
- import { Database } from './database';
11
- import { Entity } from './entity';
12
- import { Item } from './item';
13
- import { Link } from './link';
14
-
15
- export type OneOrMultiple<T> = T | T[]
16
-
17
- //
18
- // Filters
19
- //
20
6
 
21
- export type ItemIdFilter = {
22
- id: ItemID
23
- }
24
-
25
- export type ItemFilter = {
26
- type?: OneOrMultiple<string>
27
- parent?: ItemID | Item
28
- }
29
-
30
- export type LinkFilter = {
31
- type?: OneOrMultiple<string>;
32
- }
33
-
34
- export type Predicate<T extends Entity> = (entity: T) => boolean;
35
-
36
- export type RootFilter = ItemIdFilter | ItemFilter | Predicate<Item>
37
-
38
- export type RootSelector<R = void> = (filter?: RootFilter) => Selection<Item<any>, R>
39
-
40
- /**
41
- * Controls how deleted items are filtered.
42
- */
43
- export enum ItemFilterDeleted {
44
- /**
45
- * Do not return deleted items. Default behaviour.
46
- */
47
- HIDE_DELETED = 0,
48
- /**
49
- * Return deleted and regular items.
50
- */
51
- SHOW_DELETED = 1,
52
- /**
53
- * Return only deleted items.
54
- */
55
- SHOW_DELETED_ONLY = 2
56
- }
57
-
58
- export type QueryOptions = {
59
- /**
60
- * Controls how deleted items are filtered.
61
- */
62
- deleted?: ItemFilterDeleted
63
- }
64
-
65
- /**
66
- * Represents where the selection has started.
67
- */
68
- export type SelectionRoot = Database | Entity;
69
-
70
- /**
71
- * Returned from each stage of the visitor.
72
- */
73
- export type SelectionContext<T extends Entity, R> = [entities: T[], result?: R]
74
-
75
- /**
76
- * Visitor callback.
77
- * The visitor is passed the current entities and result (accumulator),
78
- * which may be modified and returned.
79
- */
80
- export type Callable<T extends Entity, R> = (entities: T[], result: R) => R
7
+ import { Entity } from '../entity';
8
+ import { Item } from '../item';
9
+ import { Link } from '../link';
10
+ import {
11
+ createQueryOptionsFilter,
12
+ filterToPredicate,
13
+ linkFilterToPredicate,
14
+ Callable,
15
+ ItemFilter,
16
+ LinkFilter,
17
+ Predicate,
18
+ QueryOptions,
19
+ RootFilter
20
+ } from './queries';
21
+ import { SelectionContext, SelectionResult, SelectionRoot } from './result';
81
22
 
82
23
  /**
83
24
  * Factory for selector that provides a root set of items.
@@ -87,7 +28,7 @@ export type Callable<T extends Entity, R> = (entities: T[], result: R) => R
87
28
  * @param filter
88
29
  * @param value Initial reducer value.
89
30
  */
90
- export const createSelector = <R>(
31
+ export const createSelection = <R>(
91
32
  // Provider is called each time the query is executed.
92
33
  itemsProvider: () => Item[],
93
34
  // TODO(burdon): Replace with direct event handler.
@@ -97,6 +38,8 @@ export const createSelector = <R>(
97
38
  value: R
98
39
  ): Selection<Item<any>, R> => {
99
40
  const predicate = filter ? filterToPredicate(filter) : () => true;
41
+
42
+ // TODO(burdon): Option to filter out system types.
100
43
  const visitor = (options: QueryOptions): SelectionContext<any, any> => {
101
44
  const items = itemsProvider()
102
45
  .filter(createQueryOptionsFilter(options))
@@ -114,11 +57,13 @@ export const createSelector = <R>(
114
57
  * @param update
115
58
  * @param value Initial reducer value.
116
59
  */
117
- export const createItemSelector = <R>(
60
+ export const createItemSelection = <R>(
118
61
  root: Item<any>,
119
62
  update: Event<Entity[]>,
120
63
  value: R
121
- ): Selection<Item<any>, R> => new Selection(() => [[root], value], update, root, value !== undefined);
64
+ ): Selection<Item<any>, R> => {
65
+ return new Selection(() => [[root], value], update, root, value !== undefined);
66
+ };
122
67
 
123
68
  /**
124
69
  * Selections are used to construct database subscriptions.
@@ -155,7 +100,14 @@ export class Selection<T extends Entity<any>, R = void> {
155
100
  /**
156
101
  * Finish the selection and return the result.
157
102
  */
158
- // TODO(burdon): Rename exec.
103
+ exec (options: QueryOptions = {}): SelectionResult<T, R> {
104
+ return this.query(options);
105
+ }
106
+
107
+ /**
108
+ * @deprecated
109
+ */
110
+ // TODO(burdon): Remove.
159
111
  query (options: QueryOptions = {}): SelectionResult<T, R> {
160
112
  return new SelectionResult<T, R>(() => this._visitor(options), this._update, this._root, this._reducer);
161
113
  }
@@ -254,156 +206,3 @@ export class Selection<T extends Entity<any>, R = void> {
254
206
  ]);
255
207
  }
256
208
  }
257
-
258
- /**
259
- * Query subscription.
260
- * Represents a live-query (subscription) that can notify about future updates to the relevant subset of items.
261
- */
262
- export class SelectionResult<T extends Entity, R = any> {
263
- /**
264
- * Fired when there are updates in the selection.
265
- * Only update that are relevant to the selection cause the update.
266
- */
267
- readonly update = new Event<SelectionResult<T>>(); // TODO(burdon): Result result object.
268
-
269
- private _lastResult: SelectionContext<T, R> = [[]];
270
-
271
- constructor (
272
- private readonly _execute: () => SelectionContext<T, R>,
273
- private readonly _update: Event<Entity[]>,
274
- private readonly _root: SelectionRoot,
275
- private readonly _reducer: boolean
276
- ) {
277
- this.refresh();
278
-
279
- // Re-run if deps change.
280
- this.update.addEffect(() => _update.on(currentEntities => {
281
- const [previousEntities] = this._lastResult;
282
-
283
- this.refresh();
284
-
285
- // Filters mutation events only if selection (since we can't reason about deps of call methods).
286
- const set = new Set([...previousEntities, ...this._lastResult![0]]);
287
- if (this._reducer || currentEntities.some(entity => set.has(entity as any))) {
288
- this.update.emit(this);
289
- }
290
- }));
291
- }
292
-
293
- /**
294
- * Re-run query.
295
- */
296
- refresh () {
297
- const [entities, result] = this._execute();
298
- this._lastResult = [dedupe(entities), result];
299
- return this;
300
- }
301
-
302
- /**
303
- * The root of the selection. Either a database or an item. Must be a stable reference.
304
- */
305
- get root (): SelectionRoot {
306
- return this._root;
307
- }
308
-
309
- /**
310
- * @deprecated
311
- */
312
- // TODO(burdon): Remove.
313
- // get result () {
314
- // return this.entities;
315
- // }
316
-
317
- /**
318
- * Get the result of this selection.
319
- */
320
- get entities (): T[] {
321
- if (!this._lastResult) {
322
- this.refresh();
323
- }
324
-
325
- const [entities] = this._lastResult!;
326
- return entities;
327
- }
328
-
329
- /**
330
- * Returns the selection or reducer result.
331
- */
332
- get value (): R extends void ? T[] : R {
333
- if (!this._lastResult) {
334
- this.refresh();
335
- }
336
-
337
- const [entities, value] = this._lastResult!;
338
- return (this._reducer ? value : entities) as any;
339
- }
340
-
341
- /**
342
- * Return the first element if the set has exactly one element.
343
- */
344
- expectOne (): T {
345
- const entities = this.entities;
346
- assert(entities.length === 1, `Expected one result; got ${entities.length}`);
347
- return entities[0];
348
- }
349
- }
350
-
351
- //
352
- // Utils
353
- //
354
-
355
- const dedupe = <T>(values: T[]) => Array.from(new Set(values));
356
-
357
- const coerceToId = (item: Item | ItemID): ItemID => {
358
- if (typeof item === 'string') {
359
- return item;
360
- }
361
-
362
- return item.id;
363
- };
364
-
365
- const testOneOrMultiple = <T>(expected: OneOrMultiple<T>, value: T) => {
366
- if (Array.isArray(expected)) {
367
- return expected.includes(value);
368
- } else {
369
- return expected === value;
370
- }
371
- };
372
-
373
- const filterToPredicate = (filter: ItemFilter | ItemIdFilter | Predicate<any>): Predicate<any> => {
374
- if (typeof filter === 'function') {
375
- return filter;
376
- }
377
-
378
- return itemFilterToPredicate(filter);
379
- };
380
-
381
- const itemFilterToPredicate = (filter: ItemFilter | ItemIdFilter): Predicate<Item> => {
382
- if ('id' in filter) {
383
- return item => item.id === filter.id;
384
- } else {
385
- return item =>
386
- (!filter.type || testOneOrMultiple(filter.type, item.type)) &&
387
- (!filter.parent || item.parent?.id === coerceToId(filter.parent));
388
- }
389
- };
390
-
391
- const linkFilterToPredicate = (filter: LinkFilter): Predicate<Link> =>
392
- link => (!filter.type || testOneOrMultiple(filter.type, link.type));
393
-
394
- const createQueryOptionsFilter = ({ deleted = ItemFilterDeleted.HIDE_DELETED }: QueryOptions): Predicate<Entity> => {
395
- return entity => {
396
- if (entity.model === null) {
397
- return false;
398
- }
399
-
400
- switch (deleted) {
401
- case ItemFilterDeleted.HIDE_DELETED:
402
- return !(entity instanceof Item) || !entity.deleted;
403
- case ItemFilterDeleted.SHOW_DELETED:
404
- return true;
405
- case ItemFilterDeleted.SHOW_DELETED_ONLY:
406
- return entity instanceof Item && entity.deleted;
407
- }
408
- };
409
- };
@@ -0,0 +1,27 @@
1
+ //
2
+ // Copyright 2020 DXOS.org
3
+ //
4
+
5
+ import { ItemID } from '@dxos/echo-protocol';
6
+
7
+ import { Item } from '../item';
8
+
9
+ export type OneOrMultiple<T> = T | T[]
10
+
11
+ export const dedupe = <T>(values: T[]) => Array.from(new Set(values));
12
+
13
+ export const coerceToId = (item: Item | ItemID): ItemID => {
14
+ if (typeof item === 'string') {
15
+ return item;
16
+ }
17
+
18
+ return item.id;
19
+ };
20
+
21
+ export const testOneOrMultiple = <T>(expected: OneOrMultiple<T>, value: T) => {
22
+ if (Array.isArray(expected)) {
23
+ return expected.includes(value);
24
+ } else {
25
+ return expected === value;
26
+ }
27
+ };
package/src/echo.test.ts CHANGED
@@ -66,13 +66,13 @@ describe('ECHO', () => {
66
66
  // TODO(burdon): Update currently called after all mutations below have completed?
67
67
  expect(parties).toHaveLength(1);
68
68
  parties.map(async party => {
69
- const result1 = party.database.select().query();
69
+ const result1 = party.database.select().exec();
70
70
  result1.entities.forEach(item => {
71
71
  log('Item:', String(item));
72
72
  });
73
73
 
74
74
  // TODO(burdon): Check item mutations.
75
- const result2 = party.database.select({ type: 'dxos:item/document' }).query();
75
+ const result2 = party.database.select({ type: 'example:item/document' }).exec();
76
76
  expect(result2.entities).toHaveLength(2);
77
77
  onUpdate();
78
78
  });
@@ -87,9 +87,9 @@ describe('ECHO', () => {
87
87
  expect(members[0].displayName).toEqual(members[0].publicKey.humanize());
88
88
 
89
89
  // TODO(burdon): Test item mutations.
90
- await party.database.createItem({ model: ObjectModel, type: 'dxos:item/document' });
91
- await party.database.createItem({ model: ObjectModel, type: 'dxos:item/document' });
92
- await party.database.createItem({ model: ObjectModel, type: 'dxos:item/kanban' });
90
+ await party.database.createItem({ model: ObjectModel, type: 'example:item/document' });
91
+ await party.database.createItem({ model: ObjectModel, type: 'example:item/document' });
92
+ await party.database.createItem({ model: ObjectModel, type: 'example:item/kanban' });
93
93
 
94
94
  await updated;
95
95
  unsubscribe();
@@ -108,12 +108,12 @@ describe('ECHO', () => {
108
108
 
109
109
  expect(parties).toHaveLength(1);
110
110
  parties.map(async party => {
111
- const items = party.database.select().query().entities;
111
+ const items = party.database.select().exec().entities;
112
112
  items.forEach(item => {
113
113
  log('Item:', String(item));
114
114
  });
115
115
 
116
- const item = party.database.select({ type: 'dxos:item/document' }).query().entities[0];
116
+ const item = party.database.select({ type: 'example:item/document' }).exec().entities[0];
117
117
  expect(item.children).toHaveLength(1);
118
118
  expect(item.children[0].type).toBe(undefined);
119
119
  // TODO(burdon): Test parent.
@@ -129,7 +129,7 @@ describe('ECHO', () => {
129
129
  // Within this test, we use the humanized key as the name.
130
130
  expect(members[0].displayName).toEqual(members[0].publicKey.humanize());
131
131
 
132
- const parent = await party.database.createItem({ model: ObjectModel, type: 'dxos:item/document' });
132
+ const parent = await party.database.createItem({ model: ObjectModel, type: 'example:item/document' });
133
133
  await party.database.createItem({ model: ObjectModel, parent: parent.id });
134
134
 
135
135
  await updated;
@@ -151,12 +151,12 @@ describe('ECHO', () => {
151
151
  // Within this test, we use the humanized key as the name.
152
152
  expect(members[0].displayName).toEqual(members[0].publicKey.humanize());
153
153
 
154
- const parentA = await party.database.createItem({ model: ObjectModel, type: 'dxos:item/document' });
154
+ const parentA = await party.database.createItem({ model: ObjectModel, type: 'example:item/document' });
155
155
  const childA = await party.database.createItem({ model: ObjectModel, parent: parentA.id });
156
156
  expect(parentA.children).toHaveLength(1);
157
157
  expect(parentA.children[0].id).toEqual(childA.id);
158
158
 
159
- const parentB = await party.database.createItem({ model: ObjectModel, type: 'dxos:item/document' });
159
+ const parentB = await party.database.createItem({ model: ObjectModel, type: 'example:item/document' });
160
160
  const childB = await party.database.createItem({ model: ObjectModel, parent: parentB.id });
161
161
  expect(parentB.children).toHaveLength(1);
162
162
  expect(parentB.children[0].id).toEqual(childB.id);
@@ -199,7 +199,7 @@ describe('ECHO', () => {
199
199
  assert(party);
200
200
  log('Initialized party');
201
201
 
202
- const items = party.database.select().query().entities;
202
+ const items = party.database.select().exec().entities;
203
203
  await waitForCondition(() => items.length > 0);
204
204
  expect(items.length).toBeGreaterThan(0);
205
205
  });
@@ -301,7 +301,7 @@ describe('ECHO', () => {
301
301
  let itemA: Item<any> | null = null;
302
302
 
303
303
  // Subscribe to Item updates on B.
304
- const updated = partyB.database.select({ type: 'example:item/test' }).query()
304
+ const updated = partyB.database.select({ type: 'example:item/test' }).exec()
305
305
  .update.waitFor(result => !!itemA && !!result.entities.find(item => item.id === itemA?.id));
306
306
 
307
307
  // Create a new Item on A.
@@ -398,7 +398,7 @@ describe('ECHO', () => {
398
398
  // Empty across the board.
399
399
  for (const node of [a1, a2, b1, b2]) {
400
400
  const [party] = node.queryParties().value;
401
- expect(party.database.select({ type: 'example:item/test' }).query().entities.length).toBe(0);
401
+ expect(party.database.select({ type: 'example:item/test' }).exec().entities.length).toBe(0);
402
402
  }
403
403
 
404
404
  for await (const node of [a1, a2, b1, b2]) {
@@ -409,7 +409,7 @@ describe('ECHO', () => {
409
409
  for (const otherNode of [a1, a2, b1, b2].filter(x => x !== node)) {
410
410
  const [otherParty] = otherNode.queryParties().value;
411
411
  const [updated, onUpdate] = latch();
412
- otherParty.database.select({ type: 'example:item/test' }).query()
412
+ otherParty.database.select({ type: 'example:item/test' }).exec()
413
413
  .update.on(result => {
414
414
  if (result.entities.find(current => current.id === item?.id)) {
415
415
  log(`other has ${item?.id}`);
@@ -460,8 +460,8 @@ describe('ECHO', () => {
460
460
  let itemA: Item<any> | null = null;
461
461
 
462
462
  // Subscribe to Item updates on B.
463
- const updated = b.queryParties().value[0].database.select({ type: 'example:item/test' })
464
- .query().update.waitFor(items => !!itemA && !!items.entities.find(item => item.id === itemA?.id));
463
+ const result = b.queryParties().value[0].database.select({ type: 'example:item/test' }).exec();
464
+ const updated = result.update.waitFor(items => !!itemA && !!items.entities.find(item => item.id === itemA?.id));
465
465
 
466
466
  // Create a new Item on A.
467
467
  itemA = await a.queryParties().value[0].database
@@ -592,7 +592,7 @@ describe('ECHO', () => {
592
592
  let itemA: Item<any> | null = null;
593
593
  const [updated, onUpdate] = latch();
594
594
 
595
- partyA.database.select({ type: 'example:item/test' }).query()
595
+ partyA.database.select({ type: 'example:item/test' }).exec()
596
596
  .update.on(result => {
597
597
  if (result.entities.length) {
598
598
  const [receivedItem] = result.entities;
@@ -605,7 +605,7 @@ describe('ECHO', () => {
605
605
  itemA = await partyA.database.createItem({ model: ObjectModel, type: 'example:item/test' }) as Item<any>;
606
606
  await updated; // Wait for update.
607
607
 
608
- expect(partyA.database.select({ type: 'example:item/test' }).query().entities.length).toEqual(1);
608
+ expect(partyA.database.select({ type: 'example:item/test' }).exec().entities.length).toEqual(1);
609
609
 
610
610
  await partyA.deactivate({ global: true });
611
611
  await partyA.activate({ global: true });
@@ -615,9 +615,9 @@ describe('ECHO', () => {
615
615
 
616
616
  await partyA.database
617
617
  .select({ type: 'example:item/test' })
618
- .query()
618
+ .exec()
619
619
  .update.waitFor(result => result.entities.length > 0);
620
- expect(partyA.database.select({ type: 'example:item/test' }).query().entities.length).toEqual(1);
620
+ expect(partyA.database.select({ type: 'example:item/test' }).exec().entities.length).toEqual(1);
621
621
  }).timeout(10_000);
622
622
 
623
623
  test('Deactivate Party - multi device', async () => {
@@ -22,12 +22,12 @@ export class ContactManager {
22
22
  ) {}
23
23
 
24
24
  getContactListItem (): Item<ObjectModel> | undefined {
25
- return this._party.database.select({ type: HALO_PARTY_CONTACT_LIST_TYPE }).query().entities[0];
25
+ return this._party.database.select({ type: HALO_PARTY_CONTACT_LIST_TYPE }).exec().entities[0];
26
26
  }
27
27
 
28
28
  queryContacts (): ResultSet<Contact> {
29
29
  const event = new Event();
30
- const result = this._party.database.select({ type: HALO_PARTY_CONTACT_LIST_TYPE }).query();
30
+ const result = this._party.database.select({ type: HALO_PARTY_CONTACT_LIST_TYPE }).exec();
31
31
  result.update.on(() => {
32
32
  event.emit();
33
33
  });
package/src/halo/halo.ts CHANGED
@@ -246,7 +246,6 @@ export class HALO {
246
246
 
247
247
  const keyPair = publicKey ? { publicKey: Buffer.from(publicKey), secretKey: Buffer.from(secretKey!) } : createKeyPair();
248
248
  await this.createIdentity(keyPair);
249
-
250
249
  await this.create(username);
251
250
 
252
251
  const profile = this.getProfile();
@@ -270,7 +269,7 @@ export class HALO {
270
269
  }
271
270
 
272
271
  // TODO(burdon): Should be part of profile object. Or use standard Result object.
273
- subscribeToProfile (cb: () => void): () => void {
274
- return this.identityReady.on(cb);
272
+ subscribeToProfile (callback: () => void): () => void {
273
+ return this.identityReady.on(callback);
275
274
  }
276
275
  }
@@ -42,8 +42,8 @@ export class Preferences {
42
42
  }
43
43
 
44
44
  subscribeToPreferences (callback: (preferences: any) => void) {
45
- const globalResults = this._party.database.select({ type: HALO_PARTY_PREFERENCES_TYPE }).query();
46
- const deviceResults = this._party.database.select({ type: HALO_PARTY_DEVICE_PREFERENCES_TYPE }).query();
45
+ const globalResults = this._party.database.select({ type: HALO_PARTY_PREFERENCES_TYPE }).exec();
46
+ const deviceResults = this._party.database.select({ type: HALO_PARTY_DEVICE_PREFERENCES_TYPE }).exec();
47
47
 
48
48
  const event = new Event<any>();
49
49
 
@@ -77,7 +77,7 @@ export class Preferences {
77
77
  if (!this._party.isOpen) {
78
78
  return null;
79
79
  }
80
- const [globalItem] = this._party.database.select({ type: HALO_PARTY_PREFERENCES_TYPE }).query().entities;
80
+ const [globalItem] = this._party.database.select({ type: HALO_PARTY_PREFERENCES_TYPE }).exec().entities;
81
81
  return globalItem;
82
82
  }
83
83
 
@@ -85,7 +85,7 @@ export class Preferences {
85
85
  if (!this._party.isOpen) {
86
86
  return null;
87
87
  }
88
- const deviceItems = this._party.database.select({ type: HALO_PARTY_DEVICE_PREFERENCES_TYPE }).query().entities;
88
+ const deviceItems = this._party.database.select({ type: HALO_PARTY_DEVICE_PREFERENCES_TYPE }).exec().entities;
89
89
  return deviceItems.find(item => this._deviceKey.equals(item.model.get('publicKey')));
90
90
  }
91
91
 
@@ -133,7 +133,7 @@ export class Preferences {
133
133
  const [partyDesc] = this._party.database
134
134
  .select({ type: HALO_PARTY_DESCRIPTOR_TYPE })
135
135
  .filter(partyMarker => joinedParty.partyKey.equals(partyMarker.model.get('publicKey')))
136
- .query().entities;
136
+ .exec().entities;
137
137
  assert(!partyDesc, `Descriptor already exists for Party: ${joinedParty.partyKey.toHex()}`);
138
138
 
139
139
  await this._party.database.createItem({
@@ -159,7 +159,7 @@ export class Preferences {
159
159
  };
160
160
  };
161
161
 
162
- const result = this._party.database.select({ type: HALO_PARTY_DESCRIPTOR_TYPE }).query();
162
+ const result = this._party.database.select({ type: HALO_PARTY_DESCRIPTOR_TYPE }).exec();
163
163
 
164
164
  // Wrap the query event so we can have manual control.
165
165
  const event = new Event();
@@ -107,9 +107,9 @@ describe('PartyCore', () => {
107
107
  await party.open();
108
108
 
109
109
  {
110
- await party.database.select().query().update.waitFor(result => result.entities.length === 2);
111
- const parent = party.database.select({ type: 'parent' }).query().entities[0];
112
- const child = party.database.select({ type: 'child' }).query().entities[0];
110
+ await party.database.select().exec().update.waitFor(result => result.entities.length === 2);
111
+ const parent = party.database.select({ type: 'parent' }).exec().entities[0];
112
+ const child = party.database.select({ type: 'child' }).exec().entities[0];
113
113
 
114
114
  expect(child.parent).toEqual(parent);
115
115
  expect(parent.children).toContain(child);
@@ -51,10 +51,9 @@ export class PartyFactory {
51
51
  @timed(5_000)
52
52
  async createParty (): Promise<PartyInternal> {
53
53
  const identity = this._identityProvider();
54
-
55
- assert(!this._options.readOnly, 'PartyFactory is read-only');
56
- assert(identity.identityGenesis, 'IdentityGenesis must exist');
57
- assert(identity.deviceKeyChain, 'Device KeyChain must exist');
54
+ assert(identity.identityGenesis, 'HALO not initialized.');
55
+ assert(identity.deviceKeyChain, 'Device KeyChain not initialized.');
56
+ assert(!this._options.readOnly, 'PartyFactory is read-only.');
58
57
 
59
58
  const partyKey = await identity.keyring.createKeyRecord({ type: KeyType.PARTY });
60
59
  const party = await this.constructParty(partyKey.publicKey);
@@ -186,7 +186,7 @@ export class PartyInternal {
186
186
  await this._protocol.start();
187
187
 
188
188
  // Issue an 'update' whenever the properties change.
189
- this.database.select({ type: PARTY_ITEM_TYPE }).query().update.on(() => this.update.emit());
189
+ this.database.select({ type: PARTY_ITEM_TYPE }).exec().update.on(() => this.update.emit());
190
190
 
191
191
  this.update.emit();
192
192
  return this;
@@ -246,7 +246,7 @@ export class PartyInternal {
246
246
  assert(this.isOpen, 'Party not open.');
247
247
 
248
248
  await this.database.waitForItem({ type: PARTY_ITEM_TYPE });
249
- const items = this.database.select({ type: PARTY_ITEM_TYPE }).query().entities;
249
+ const items = this.database.select({ type: PARTY_ITEM_TYPE }).exec().entities;
250
250
  assert(items.length === 1, 'Party properties missing.');
251
251
  return items[0] as Item<ObjectModel>;
252
252
  }
@@ -256,7 +256,7 @@ export class PartyInternal {
256
256
  */
257
257
  getPropertiesSet () {
258
258
  assert(this.isOpen, 'Party not open.');
259
- return this.database.select({ type: PARTY_ITEM_TYPE }).query();
259
+ return this.database.select({ type: PARTY_ITEM_TYPE }).exec();
260
260
  }
261
261
 
262
262
  /**
@@ -263,14 +263,12 @@ describe('Party manager', () => {
263
263
  expect(partyB).toBeDefined();
264
264
 
265
265
  const [updated, onUpdate] = latch();
266
- partyB.database.select({ type: 'example:item/test' }).query()
266
+ partyB.database.select({ type: 'example:item/test' }).exec()
267
267
  .update.on(result => {
268
- if (result.entities.length) {
269
- const [itemB] = result.entities;
270
- if (itemA && itemA.id === itemB.id) {
271
- log(`B has ${itemB.id}`);
272
- onUpdate();
273
- }
268
+ const [itemB] = result.entities;
269
+ if (itemA && itemA.id === itemB.id) {
270
+ log(`B has ${itemB.id}`);
271
+ onUpdate();
274
272
  }
275
273
  });
276
274
 
@@ -318,7 +316,7 @@ describe('Party manager', () => {
318
316
 
319
317
  // Subscribe to Item updates on B.
320
318
  const [updated, onUpdate] = latch();
321
- partyB.database.select({ type: 'example:item/test' }).query()
319
+ partyB.database.select({ type: 'example:item/test' }).exec()
322
320
  .update.on(result => {
323
321
  if (result.entities.length) {
324
322
  const [itemB] = result.entities;
@@ -399,7 +397,7 @@ describe('Party manager', () => {
399
397
  const [updated, onUpdate] = latch();
400
398
 
401
399
  // Subscribe to Item updates on B.
402
- partyB.database.select({ type: 'example:item/test' }).query()
400
+ partyB.database.select({ type: 'example:item/test' }).exec()
403
401
  .update.on(result => {
404
402
  if (result.entities.length) {
405
403
  const [itemB] = result.entities;
@@ -458,7 +456,7 @@ describe('Party manager', () => {
458
456
  const [updated, onUpdate] = latch();
459
457
 
460
458
  // Subscribe to Item updates on B.
461
- partyB.database.select({ type: 'example:item/test' }).query()
459
+ partyB.database.select({ type: 'example:item/test' }).exec()
462
460
  .update.on(result => {
463
461
  if (result.entities.length) {
464
462
  const [itemB] = result.entities;
@@ -244,7 +244,7 @@ export class PartyManager {
244
244
  const attachUpdateListeners = () => {
245
245
  const debouncedContacts = party.processor.keyOrInfoAdded.debounce(CONTACT_DEBOUNCE_INTERVAL).discardParameter();
246
246
  debouncedContacts.on(updateContact);
247
- party.database.select({ type: PARTY_ITEM_TYPE }).query().update.on(updateTitle);
247
+ party.database.select({ type: PARTY_ITEM_TYPE }).exec().update.on(updateTitle);
248
248
  };
249
249
 
250
250
  if (party.isOpen) {