@hops-ops/distributed 4.3.0 → 4.4.1

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.
@@ -13,7 +13,7 @@ function assertActualProjectionCapabilities(contract, delta) {
13
13
  for (const reference of item.projection_refs)
14
14
  references.add(reference);
15
15
  }
16
- let selectedEvent;
16
+ let selectedEvents;
17
17
  for (const reference of references) {
18
18
  const operations = delta.operations.filter((item) => item.occurrence_ordinal === ordinal &&
19
19
  item.projection_refs.includes(reference));
@@ -22,20 +22,27 @@ function assertActualProjectionCapabilities(contract, delta) {
22
22
  const candidates = contract.capabilities.arms.filter((arm) => arm.projection_ref === reference &&
23
23
  operations.every(({ mutation }) => capabilityAllowsMutation(arm, mutation)) &&
24
24
  recoveries.every(({ target }) => capabilityAllowsRecovery(arm, target)));
25
- if (candidates.length !== 1) {
26
- throw new Error('actual projection delta does not identify one generated event arm');
25
+ if (candidates.length === 0) {
26
+ throw new Error('actual projection delta is outside every generated event arm');
27
27
  }
28
- const event = candidates[0].event;
29
- if (selectedEvent !== undefined &&
30
- (event.id !== selectedEvent.id ||
31
- event.name !== selectedEvent.name ||
32
- event.version !== selectedEvent.version)) {
28
+ const candidateEvents = new Map(candidates.map(({ event }) => [eventIdentity(event), event]));
29
+ if (selectedEvents === undefined) {
30
+ selectedEvents = candidateEvents;
31
+ continue;
32
+ }
33
+ for (const identity of selectedEvents.keys()) {
34
+ if (!candidateEvents.has(identity))
35
+ selectedEvents.delete(identity);
36
+ }
37
+ if (selectedEvents.size === 0) {
33
38
  throw new Error('actual projection refs disagree on their generated event arm');
34
39
  }
35
- selectedEvent = event;
36
40
  }
37
41
  }
38
42
  }
43
+ function eventIdentity(event) {
44
+ return JSON.stringify([event.id, event.name, event.version]);
45
+ }
39
46
  function capabilityAllowsMutation(arm, mutation) {
40
47
  switch (mutation.op) {
41
48
  case 'upsert': {
@@ -455,19 +455,23 @@ export function relationshipKeyMapping(value, dependencies, path) {
455
455
  value: Object.freeze({ kind: 'direct', local, remote })
456
456
  };
457
457
  }
458
+ const sourceForeignKey = uniqueStringList(value.sourceForeignKey);
459
+ const targetForeignKey = uniqueStringList(value.targetForeignKey);
458
460
  if (value.kind === 'through' &&
459
461
  isName(value.table) &&
460
462
  dependencies.includes(value.table) &&
461
- isName(value.sourceForeignKey) &&
462
- isName(value.targetForeignKey)) {
463
+ sourceForeignKey !== undefined &&
464
+ targetForeignKey !== undefined &&
465
+ sourceForeignKey.length === local.length &&
466
+ targetForeignKey.length === remote.length) {
463
467
  return {
464
468
  value: Object.freeze({
465
469
  kind: 'through',
466
470
  local,
467
471
  remote,
468
472
  table: value.table,
469
- sourceForeignKey: value.sourceForeignKey,
470
- targetForeignKey: value.targetForeignKey
473
+ sourceForeignKey,
474
+ targetForeignKey
471
475
  })
472
476
  };
473
477
  }
@@ -173,8 +173,8 @@ export type ReplicaRelationshipKeyMapping = {
173
173
  readonly local: readonly string[];
174
174
  readonly remote: readonly string[];
175
175
  readonly table: string;
176
- readonly sourceForeignKey: string;
177
- readonly targetForeignKey: string;
176
+ readonly sourceForeignKey: readonly string[];
177
+ readonly targetForeignKey: readonly string[];
178
178
  } | {
179
179
  readonly kind: 'through_opaque';
180
180
  readonly local: readonly string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hops-ops/distributed",
3
- "version": "4.3.0",
3
+ "version": "4.4.1",
4
4
  "description": "Typed GraphQL client, causal replica, command runtime, and framework adapters for Distributed services",
5
5
  "type": "module",
6
6
  "license": "UNLICENSED",