@enbox/agent 0.7.6 → 0.7.8

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 (85) hide show
  1. package/dist/browser.mjs +9 -11
  2. package/dist/browser.mjs.map +4 -4
  3. package/dist/esm/dwn-api.js +3 -2
  4. package/dist/esm/dwn-api.js.map +1 -1
  5. package/dist/esm/enbox-connect-protocol.js +5 -5
  6. package/dist/esm/enbox-connect-protocol.js.map +1 -1
  7. package/dist/esm/hd-identity-vault.js +187 -177
  8. package/dist/esm/hd-identity-vault.js.map +1 -1
  9. package/dist/esm/index.js +1 -1
  10. package/dist/esm/index.js.map +1 -1
  11. package/dist/esm/permissions-api.js +7 -34
  12. package/dist/esm/permissions-api.js.map +1 -1
  13. package/dist/esm/sync-closure-resolver.js +229 -110
  14. package/dist/esm/sync-closure-resolver.js.map +1 -1
  15. package/dist/esm/sync-closure-types.js +24 -7
  16. package/dist/esm/sync-closure-types.js.map +1 -1
  17. package/dist/esm/sync-engine-level.js +1961 -764
  18. package/dist/esm/sync-engine-level.js.map +1 -1
  19. package/dist/esm/sync-link-id.js +4 -13
  20. package/dist/esm/sync-link-id.js.map +1 -1
  21. package/dist/esm/sync-link-reconciler.js +26 -8
  22. package/dist/esm/sync-link-reconciler.js.map +1 -1
  23. package/dist/esm/sync-messages.js +218 -154
  24. package/dist/esm/sync-messages.js.map +1 -1
  25. package/dist/esm/sync-permission-grants.js +208 -0
  26. package/dist/esm/sync-permission-grants.js.map +1 -0
  27. package/dist/esm/sync-replication-ledger.js +23 -40
  28. package/dist/esm/sync-replication-ledger.js.map +1 -1
  29. package/dist/esm/sync-scope-acceptance.js +126 -0
  30. package/dist/esm/sync-scope-acceptance.js.map +1 -0
  31. package/dist/esm/sync-topological-sort.js +57 -15
  32. package/dist/esm/sync-topological-sort.js.map +1 -1
  33. package/dist/esm/types/sync.js +130 -22
  34. package/dist/esm/types/sync.js.map +1 -1
  35. package/dist/types/dwn-api.d.ts.map +1 -1
  36. package/dist/types/hd-identity-vault.d.ts +25 -0
  37. package/dist/types/hd-identity-vault.d.ts.map +1 -1
  38. package/dist/types/index.d.ts +1 -1
  39. package/dist/types/index.d.ts.map +1 -1
  40. package/dist/types/permissions-api.d.ts +1 -2
  41. package/dist/types/permissions-api.d.ts.map +1 -1
  42. package/dist/types/sync-closure-resolver.d.ts.map +1 -1
  43. package/dist/types/sync-closure-types.d.ts +14 -3
  44. package/dist/types/sync-closure-types.d.ts.map +1 -1
  45. package/dist/types/sync-engine-level.d.ts +127 -25
  46. package/dist/types/sync-engine-level.d.ts.map +1 -1
  47. package/dist/types/sync-link-id.d.ts +3 -9
  48. package/dist/types/sync-link-id.d.ts.map +1 -1
  49. package/dist/types/sync-link-reconciler.d.ts +12 -2
  50. package/dist/types/sync-link-reconciler.d.ts.map +1 -1
  51. package/dist/types/sync-messages.d.ts +16 -13
  52. package/dist/types/sync-messages.d.ts.map +1 -1
  53. package/dist/types/sync-permission-grants.d.ts +52 -0
  54. package/dist/types/sync-permission-grants.d.ts.map +1 -0
  55. package/dist/types/sync-replication-ledger.d.ts +5 -13
  56. package/dist/types/sync-replication-ledger.d.ts.map +1 -1
  57. package/dist/types/sync-scope-acceptance.d.ts +28 -0
  58. package/dist/types/sync-scope-acceptance.d.ts.map +1 -0
  59. package/dist/types/sync-topological-sort.d.ts +2 -1
  60. package/dist/types/sync-topological-sort.d.ts.map +1 -1
  61. package/dist/types/types/identity-vault.d.ts +9 -0
  62. package/dist/types/types/identity-vault.d.ts.map +1 -1
  63. package/dist/types/types/permissions.d.ts +2 -0
  64. package/dist/types/types/permissions.d.ts.map +1 -1
  65. package/dist/types/types/sync.d.ts +137 -75
  66. package/dist/types/types/sync.d.ts.map +1 -1
  67. package/package.json +3 -3
  68. package/src/dwn-api.ts +3 -2
  69. package/src/enbox-connect-protocol.ts +5 -5
  70. package/src/hd-identity-vault.ts +244 -212
  71. package/src/index.ts +10 -1
  72. package/src/permissions-api.ts +11 -42
  73. package/src/sync-closure-resolver.ts +306 -126
  74. package/src/sync-closure-types.ts +38 -9
  75. package/src/sync-engine-level.ts +2560 -797
  76. package/src/sync-link-id.ts +9 -14
  77. package/src/sync-link-reconciler.ts +43 -10
  78. package/src/sync-messages.ts +263 -159
  79. package/src/sync-permission-grants.ts +297 -0
  80. package/src/sync-replication-ledger.ts +55 -50
  81. package/src/sync-scope-acceptance.ts +186 -0
  82. package/src/sync-topological-sort.ts +89 -21
  83. package/src/types/identity-vault.ts +8 -1
  84. package/src/types/permissions.ts +2 -0
  85. package/src/types/sync.ts +235 -62
@@ -1,4 +1,4 @@
1
- /** Separator used in compound runtime/legacy cursor keys. */
1
+ /** Separator used in compound replication link identifiers. */
2
2
  export const LINK_ID_SEPARATOR = '^';
3
3
 
4
4
  /** Opaque runtime identifier for a replication link. */
@@ -7,18 +7,13 @@ export type LinkId = string;
7
7
  /**
8
8
  * Build the runtime identifier for a replication link.
9
9
  *
10
- * Runtime identity is `(tenantDid, remoteEndpoint, scopeId)`.
10
+ * Runtime identity is `(tenantDid, remoteEndpoint, projectionId, authorizationEpoch)`.
11
11
  */
12
- export function buildLinkId(tenantDid: string, remoteEndpoint: string, scopeId: string): LinkId {
13
- return `${tenantDid}${LINK_ID_SEPARATOR}${remoteEndpoint}${LINK_ID_SEPARATOR}${scopeId}`;
14
- }
15
-
16
- /**
17
- * Build the legacy cursor key used by the deprecated `syncCursors` sublevel.
18
- *
19
- * This remains only for one-time migration of pre-Phase-1f data.
20
- */
21
- export function buildLegacyCursorKey(tenantDid: string, remoteEndpoint: string, protocol?: string): string {
22
- const base = `${tenantDid}${LINK_ID_SEPARATOR}${remoteEndpoint}`;
23
- return protocol ? `${base}${LINK_ID_SEPARATOR}${protocol}` : base;
12
+ export function buildLinkId(
13
+ tenantDid: string,
14
+ remoteEndpoint: string,
15
+ projectionId: string,
16
+ authorizationEpoch: string,
17
+ ): LinkId {
18
+ return `${tenantDid}${LINK_ID_SEPARATOR}${remoteEndpoint}${LINK_ID_SEPARATOR}${projectionId}${LINK_ID_SEPARATOR}${authorizationEpoch}`;
24
19
  }
@@ -2,6 +2,8 @@ import type { GenericMessage, MessagesSyncDiffEntry } from '@enbox/dwn-sdk-js';
2
2
 
3
3
  import type { PushResult } from './types/sync.js';
4
4
 
5
+ import { SyncPullAbortedError } from './sync-messages.js';
6
+
5
7
  export type ReconcileDirection = 'pull' | 'push';
6
8
 
7
9
  export type ReconcileTarget = {
@@ -9,6 +11,7 @@ export type ReconcileTarget = {
9
11
  dwnUrl: string;
10
12
  delegateDid?: string;
11
13
  protocol?: string;
14
+ permissionGrantIds?: string[];
12
15
  };
13
16
 
14
17
  export type ReconcileOutcome = {
@@ -25,28 +28,42 @@ export type ReconcileOutcome = {
25
28
  };
26
29
 
27
30
  type ReconcileDeps = {
28
- getLocalRoot: (did: string, delegateDid?: string, protocol?: string) => Promise<string>;
29
- getRemoteRoot: (did: string, dwnUrl: string, delegateDid?: string, protocol?: string) => Promise<string>;
31
+ getLocalRoot: (
32
+ did: string,
33
+ delegateDid?: string,
34
+ protocol?: string,
35
+ permissionGrantIds?: string[],
36
+ ) => Promise<string>;
37
+ getRemoteRoot: (
38
+ did: string,
39
+ dwnUrl: string,
40
+ delegateDid?: string,
41
+ protocol?: string,
42
+ permissionGrantIds?: string[],
43
+ ) => Promise<string>;
30
44
  diffWithRemote: (target: ReconcileTarget) => Promise<{ onlyRemote: MessagesSyncDiffEntry[]; onlyLocal: string[] }>;
31
45
  pullMessages: (params: {
32
46
  did: string;
33
47
  dwnUrl: string;
34
48
  delegateDid?: string;
35
49
  protocol?: string;
50
+ permissionGrantIds?: string[];
36
51
  messageCids: string[];
37
52
  prefetched: (MessagesSyncDiffEntry & { message: GenericMessage })[];
53
+ shouldContinue?: () => boolean;
38
54
  }) => Promise<void>;
39
55
  pushMessages: (params: {
40
56
  did: string;
41
57
  dwnUrl: string;
42
58
  delegateDid?: string;
43
59
  protocol?: string;
60
+ permissionGrantIds?: string[];
44
61
  messageCids: string[];
45
62
  }) => Promise<PushResult>;
46
63
  shouldContinue?: () => boolean;
47
64
  };
48
65
 
49
- function partitionRemoteEntries(entries: MessagesSyncDiffEntry[]): {
66
+ export function partitionRemoteEntries(entries: MessagesSyncDiffEntry[]): {
50
67
  prefetched: (MessagesSyncDiffEntry & { message: GenericMessage })[];
51
68
  needsFetchCids: string[];
52
69
  } {
@@ -82,15 +99,15 @@ export class SyncLinkReconciler {
82
99
  direction?: ReconcileDirection;
83
100
  verifyConvergence?: boolean;
84
101
  }): Promise<ReconcileOutcome> {
85
- const { did, dwnUrl, delegateDid, protocol } = target;
102
+ const { did, dwnUrl, delegateDid, protocol, permissionGrantIds } = target;
86
103
  const direction = options?.direction;
87
104
  const verifyConvergence = options?.verifyConvergence ?? false;
88
105
  const shouldContinue = this._deps.shouldContinue;
89
106
 
90
- const localRoot = await this._deps.getLocalRoot(did, delegateDid, protocol);
107
+ const localRoot = await this._deps.getLocalRoot(did, delegateDid, protocol, permissionGrantIds);
91
108
  if (shouldContinue && !shouldContinue()) { return { aborted: true, changed: false, didPull: false, didPush: false }; }
92
109
 
93
- const remoteRoot = await this._deps.getRemoteRoot(did, dwnUrl, delegateDid, protocol);
110
+ const remoteRoot = await this._deps.getRemoteRoot(did, dwnUrl, delegateDid, protocol, permissionGrantIds);
94
111
  if (shouldContinue && !shouldContinue()) { return { aborted: true, changed: false, didPull: false, didPush: false }; }
95
112
 
96
113
  let didPull = false;
@@ -103,14 +120,30 @@ export class SyncLinkReconciler {
103
120
 
104
121
  if ((!direction || direction === 'pull') && diff.onlyRemote.length > 0) {
105
122
  const { prefetched, needsFetchCids } = partitionRemoteEntries(diff.onlyRemote);
106
- await this._deps.pullMessages({ did, dwnUrl, delegateDid, protocol, messageCids: needsFetchCids, prefetched });
123
+ try {
124
+ await this._deps.pullMessages({
125
+ did,
126
+ dwnUrl,
127
+ delegateDid,
128
+ protocol,
129
+ permissionGrantIds,
130
+ messageCids: needsFetchCids,
131
+ prefetched,
132
+ shouldContinue,
133
+ });
134
+ } catch (error) {
135
+ if (error instanceof SyncPullAbortedError) {
136
+ return { aborted: true, changed: true, didPull: false, didPush: false, localRoot, remoteRoot };
137
+ }
138
+ throw error;
139
+ }
107
140
  if (shouldContinue && !shouldContinue()) { return { aborted: true, changed: true, didPull: true, didPush: false, localRoot, remoteRoot }; }
108
141
  didPull = true;
109
142
  }
110
143
 
111
144
  if ((!direction || direction === 'push') && diff.onlyLocal.length > 0) {
112
145
  pushResult = await this._deps.pushMessages({
113
- did, dwnUrl, delegateDid, protocol, messageCids: diff.onlyLocal,
146
+ did, dwnUrl, delegateDid, protocol, permissionGrantIds, messageCids: diff.onlyLocal,
114
147
  });
115
148
  if (shouldContinue && !shouldContinue()) {
116
149
  return { aborted: true, changed: true, didPull, didPush: true, localRoot, remoteRoot, pushResult };
@@ -130,12 +163,12 @@ export class SyncLinkReconciler {
130
163
  };
131
164
  }
132
165
 
133
- const postLocalRoot = await this._deps.getLocalRoot(did, delegateDid, protocol);
166
+ const postLocalRoot = await this._deps.getLocalRoot(did, delegateDid, protocol, permissionGrantIds);
134
167
  if (shouldContinue && !shouldContinue()) {
135
168
  return { aborted: true, changed: localRoot !== remoteRoot, didPull, didPush, localRoot, remoteRoot, pushResult };
136
169
  }
137
170
 
138
- const postRemoteRoot = await this._deps.getRemoteRoot(did, dwnUrl, delegateDid, protocol);
171
+ const postRemoteRoot = await this._deps.getRemoteRoot(did, dwnUrl, delegateDid, protocol, permissionGrantIds);
139
172
  if (shouldContinue && !shouldContinue()) {
140
173
  return { aborted: true, changed: localRoot !== remoteRoot, didPull, didPush, localRoot, remoteRoot, pushResult };
141
174
  }