@slorenzot/memento-core 2.0.0 → 2.0.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.
Files changed (55) hide show
  1. package/dist/ConfigManager.d.ts +44 -59
  2. package/dist/ConfigManager.d.ts.map +1 -1
  3. package/dist/ConfigManager.js +78 -279
  4. package/dist/ConfigManager.js.map +1 -1
  5. package/dist/MemoryEngine.d.ts +30 -0
  6. package/dist/MemoryEngine.d.ts.map +1 -1
  7. package/dist/MemoryEngine.js +136 -11
  8. package/dist/MemoryEngine.js.map +1 -1
  9. package/dist/auth/device-flow-client.d.ts +48 -0
  10. package/dist/auth/device-flow-client.d.ts.map +1 -0
  11. package/dist/auth/device-flow-client.js +143 -0
  12. package/dist/auth/device-flow-client.js.map +1 -0
  13. package/dist/auth/index.d.ts +4 -0
  14. package/dist/auth/index.d.ts.map +1 -0
  15. package/dist/auth/index.js +9 -0
  16. package/dist/auth/index.js.map +1 -0
  17. package/dist/auth/token-store.d.ts +46 -0
  18. package/dist/auth/token-store.d.ts.map +1 -0
  19. package/dist/auth/token-store.js +117 -0
  20. package/dist/auth/token-store.js.map +1 -0
  21. package/dist/auth/types.d.ts +83 -0
  22. package/dist/auth/types.d.ts.map +1 -0
  23. package/dist/auth/types.js +4 -0
  24. package/dist/auth/types.js.map +1 -0
  25. package/dist/index.d.ts +2 -0
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +2 -0
  28. package/dist/index.js.map +1 -1
  29. package/dist/sync/conflict-resolution.d.ts +26 -0
  30. package/dist/sync/conflict-resolution.d.ts.map +1 -0
  31. package/dist/sync/conflict-resolution.js +64 -0
  32. package/dist/sync/conflict-resolution.js.map +1 -0
  33. package/dist/sync/index.d.ts +5 -0
  34. package/dist/sync/index.d.ts.map +1 -0
  35. package/dist/sync/index.js +12 -0
  36. package/dist/sync/index.js.map +1 -0
  37. package/dist/sync/sync-client.d.ts +41 -0
  38. package/dist/sync/sync-client.d.ts.map +1 -0
  39. package/dist/sync/sync-client.js +101 -0
  40. package/dist/sync/sync-client.js.map +1 -0
  41. package/dist/sync/sync-engine.d.ts +58 -0
  42. package/dist/sync/sync-engine.d.ts.map +1 -0
  43. package/dist/sync/sync-engine.js +370 -0
  44. package/dist/sync/sync-engine.js.map +1 -0
  45. package/dist/sync/types.d.ts +107 -0
  46. package/dist/sync/types.d.ts.map +1 -0
  47. package/dist/sync/types.js +20 -0
  48. package/dist/sync/types.js.map +1 -0
  49. package/dist/token-savings.d.ts +42 -0
  50. package/dist/token-savings.d.ts.map +1 -0
  51. package/dist/token-savings.js +104 -0
  52. package/dist/token-savings.js.map +1 -0
  53. package/dist/types.d.ts +3 -0
  54. package/dist/types.d.ts.map +1 -1
  55. package/package.json +1 -1
@@ -0,0 +1,58 @@
1
+ import type { MemoryEngine } from '../MemoryEngine.js';
2
+ import type { SyncConfig, SyncMeta, SyncResult, SyncStatusResponse } from './types.js';
3
+ /**
4
+ * SyncEngine — orchestrates bidirectional sync between local DB and memento-web.
5
+ *
6
+ * Protocol: cursor-based, version-tracked, last-write-wins
7
+ *
8
+ * Flow:
9
+ * 1. Pull: fetch remote changes since cursor
10
+ * 2. Apply remote changes locally
11
+ * 3. Push: send local changes since last sync (scope=project only)
12
+ * 4. Save new cursor
13
+ */
14
+ export declare class SyncEngine {
15
+ private config;
16
+ private metaPath;
17
+ private client;
18
+ private tokenStore;
19
+ private deviceFingerprint;
20
+ constructor(config: SyncConfig);
21
+ /**
22
+ * Full bidirectional sync.
23
+ */
24
+ sync(engine: MemoryEngine): Promise<SyncResult>;
25
+ /**
26
+ * Pull-only: download remote changes to local DB.
27
+ */
28
+ pull(engine: MemoryEngine): Promise<SyncResult>;
29
+ /**
30
+ * Push-only: upload local changes to server.
31
+ */
32
+ push(engine: MemoryEngine): Promise<SyncResult>;
33
+ /**
34
+ * Get sync status.
35
+ */
36
+ getStatus(engine: MemoryEngine): Promise<{
37
+ meta: SyncMeta | null;
38
+ remote?: SyncStatusResponse;
39
+ local: {
40
+ totalObservations: number;
41
+ activeObservations: number;
42
+ };
43
+ authenticated: boolean;
44
+ }>;
45
+ private doPull;
46
+ private doPush;
47
+ /**
48
+ * Apply a SyncMemento to the local DB.
49
+ */
50
+ private applyToLocal;
51
+ /**
52
+ * Convert a local Observation to a SyncMemento for the wire.
53
+ */
54
+ private observationToMemento;
55
+ loadMeta(): SyncMeta;
56
+ saveMeta(meta: SyncMeta): void;
57
+ }
58
+ //# sourceMappingURL=sync-engine.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-engine.d.ts","sourceRoot":"","sources":["../../src/sync/sync-engine.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,OAAO,KAAK,EACV,UAAU,EACV,QAAQ,EACR,UAAU,EAEV,kBAAkB,EACnB,MAAM,YAAY,CAAC;AAOpB;;;;;;;;;;GAUG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,QAAQ,CAAS;IACzB,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,iBAAiB,CAAS;gBAEtB,MAAM,EAAE,UAAU;IAgB9B;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IAiCrD;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IA0BrD;;OAEG;IACG,IAAI,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,UAAU,CAAC;IA0BrD;;OAEG;IACG,SAAS,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC;QAC7C,IAAI,EAAE,QAAQ,GAAG,IAAI,CAAC;QACtB,MAAM,CAAC,EAAE,kBAAkB,CAAC;QAC5B,KAAK,EAAE;YAAE,iBAAiB,EAAE,MAAM,CAAC;YAAC,kBAAkB,EAAE,MAAM,CAAA;SAAE,CAAC;QACjE,aAAa,EAAE,OAAO,CAAC;KACxB,CAAC;YA6BY,MAAM;YAmCN,MAAM;IA2DpB;;OAEG;YACW,YAAY;IAiD1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAsB5B,QAAQ,IAAI,QAAQ;IAsBpB,QAAQ,CAAC,IAAI,EAAE,QAAQ,GAAG,IAAI;CAO/B"}
@@ -0,0 +1,370 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.SyncEngine = void 0;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ const os = __importStar(require("os"));
40
+ const crypto = __importStar(require("crypto"));
41
+ const sync_client_js_1 = require("./sync-client.js");
42
+ const token_store_js_1 = require("../auth/token-store.js");
43
+ const DEFAULT_META_PATH = path.join(os.homedir(), '.memento', 'sync-meta.json');
44
+ /**
45
+ * SyncEngine — orchestrates bidirectional sync between local DB and memento-web.
46
+ *
47
+ * Protocol: cursor-based, version-tracked, last-write-wins
48
+ *
49
+ * Flow:
50
+ * 1. Pull: fetch remote changes since cursor
51
+ * 2. Apply remote changes locally
52
+ * 3. Push: send local changes since last sync (scope=project only)
53
+ * 4. Save new cursor
54
+ */
55
+ class SyncEngine {
56
+ config;
57
+ metaPath;
58
+ client;
59
+ tokenStore;
60
+ deviceFingerprint;
61
+ constructor(config) {
62
+ this.config = config;
63
+ this.metaPath = config.metaFilePath || DEFAULT_META_PATH;
64
+ this.tokenStore = new token_store_js_1.TokenStore();
65
+ this.deviceFingerprint = generateDeviceFingerprint();
66
+ this.client = new sync_client_js_1.SyncClient({
67
+ serverUrl: config.serverUrl,
68
+ getToken: () => {
69
+ const t = this.tokenStore.getToken();
70
+ return Promise.resolve(t?.accessToken ?? null);
71
+ },
72
+ fetchFunction: config.fetchFunction,
73
+ });
74
+ }
75
+ /**
76
+ * Full bidirectional sync.
77
+ */
78
+ async sync(engine) {
79
+ const start = Date.now();
80
+ const meta = this.loadMeta();
81
+ // Pull first
82
+ const pullResult = await this.doPull(engine, meta.lastCursor);
83
+ // Then push
84
+ const pushResult = await this.doPush(engine, meta.lastCursor);
85
+ // Save meta with new cursor
86
+ const newCursor = pullResult.newCursor || pushResult.newCursor || meta.lastCursor;
87
+ this.saveMeta({
88
+ lastSyncAt: Date.now(),
89
+ lastSyncDirection: 'bidirectional',
90
+ lastCursor: newCursor,
91
+ lastPullCount: pullResult.applied,
92
+ lastPushCount: pushResult.pushed,
93
+ lastConflictCount: pullResult.conflicts.length + pushResult.conflicts.length,
94
+ serverUrl: this.config.serverUrl,
95
+ updatedAt: Date.now(),
96
+ });
97
+ return {
98
+ direction: 'bidirectional',
99
+ pulled: pullResult.applied,
100
+ pushed: pushResult.pushed,
101
+ conflicts: [...pullResult.conflicts, ...pushResult.conflicts],
102
+ errors: [...pullResult.errors, ...pushResult.errors],
103
+ durationMs: Date.now() - start,
104
+ };
105
+ }
106
+ /**
107
+ * Pull-only: download remote changes to local DB.
108
+ */
109
+ async pull(engine) {
110
+ const start = Date.now();
111
+ const meta = this.loadMeta();
112
+ const result = await this.doPull(engine, meta.lastCursor);
113
+ this.saveMeta({
114
+ lastSyncAt: Date.now(),
115
+ lastSyncDirection: 'pull',
116
+ lastCursor: result.newCursor || meta.lastCursor,
117
+ lastPullCount: result.applied,
118
+ lastPushCount: 0,
119
+ lastConflictCount: result.conflicts.length,
120
+ serverUrl: this.config.serverUrl,
121
+ updatedAt: Date.now(),
122
+ });
123
+ return {
124
+ direction: 'pull',
125
+ pulled: result.applied,
126
+ pushed: 0,
127
+ conflicts: result.conflicts,
128
+ errors: result.errors,
129
+ durationMs: Date.now() - start,
130
+ };
131
+ }
132
+ /**
133
+ * Push-only: upload local changes to server.
134
+ */
135
+ async push(engine) {
136
+ const start = Date.now();
137
+ const meta = this.loadMeta();
138
+ const result = await this.doPush(engine, meta.lastCursor);
139
+ this.saveMeta({
140
+ lastSyncAt: Date.now(),
141
+ lastSyncDirection: 'push',
142
+ lastCursor: result.newCursor || meta.lastCursor,
143
+ lastPullCount: 0,
144
+ lastPushCount: result.pushed,
145
+ lastConflictCount: result.conflicts.length,
146
+ serverUrl: this.config.serverUrl,
147
+ updatedAt: Date.now(),
148
+ });
149
+ return {
150
+ direction: 'push',
151
+ pulled: 0,
152
+ pushed: result.pushed,
153
+ conflicts: result.conflicts,
154
+ errors: result.errors,
155
+ durationMs: Date.now() - start,
156
+ };
157
+ }
158
+ /**
159
+ * Get sync status.
160
+ */
161
+ async getStatus(engine) {
162
+ const meta = this.loadMeta();
163
+ const token = this.tokenStore.getToken();
164
+ const authenticated = !!token;
165
+ // Local stats
166
+ const localActive = (await engine.search({ projectId: this.config.projectId, limit: 0 })).total;
167
+ const localDeleted = (await engine.listDeleted({ limit: 0 })).total;
168
+ let remote;
169
+ if (authenticated) {
170
+ try {
171
+ remote = await this.client.status(this.config.projectId);
172
+ }
173
+ catch {
174
+ // Remote unreachable
175
+ }
176
+ }
177
+ return {
178
+ meta: meta.lastSyncAt ? meta : null,
179
+ remote,
180
+ local: { totalObservations: localActive + localDeleted, activeObservations: localActive },
181
+ authenticated,
182
+ };
183
+ }
184
+ // ── Internal ────────────────────────────────────────────────
185
+ async doPull(engine, cursor) {
186
+ const errors = [];
187
+ const conflicts = [];
188
+ let hasMore = true;
189
+ let totalApplied = 0;
190
+ let latestCursor = cursor;
191
+ // Paginated pull
192
+ while (hasMore) {
193
+ const response = await this.client.pull({
194
+ projectId: this.config.projectId,
195
+ cursor: latestCursor,
196
+ limit: 100,
197
+ });
198
+ for (const change of response.changes) {
199
+ try {
200
+ await this.applyToLocal(engine, change);
201
+ totalApplied++;
202
+ }
203
+ catch (err) {
204
+ errors.push(`Failed to apply ${change.uuid}: ${err}`);
205
+ }
206
+ }
207
+ latestCursor = response.newCursor;
208
+ hasMore = response.hasMore;
209
+ }
210
+ return { applied: totalApplied, conflicts, errors, newCursor: latestCursor || '' };
211
+ }
212
+ async doPush(engine, cursor) {
213
+ // Get local observations with scope=project (personal stays local)
214
+ const active = await engine.search({
215
+ projectId: this.config.projectId,
216
+ limit: 100000,
217
+ });
218
+ const deleted = await engine.listDeleted({
219
+ projectId: this.config.projectId,
220
+ limit: 100000,
221
+ });
222
+ const all = [...active.observations, ...deleted.observations];
223
+ // All items (project + personal scope) get pushed
224
+ // Filter: only items modified since cursor
225
+ let itemsToSync = all;
226
+ if (cursor) {
227
+ const cursorDate = new Date(cursor);
228
+ itemsToSync = all.filter(obs => obs.updatedAt > cursorDate);
229
+ }
230
+ if (itemsToSync.length === 0) {
231
+ return { pushed: 0, conflicts: [], errors: [], newCursor: cursor || '' };
232
+ }
233
+ // Convert to SyncMemento wire format
234
+ const items = itemsToSync.map(obs => this.observationToMemento(obs));
235
+ const result = await this.client.push({
236
+ projectId: this.config.projectId,
237
+ cursor,
238
+ deviceFingerprint: this.deviceFingerprint,
239
+ clientVersion: '1.0.0',
240
+ items,
241
+ });
242
+ // Handle conflicts — apply server data for server_wins
243
+ for (const conflict of result.conflicts) {
244
+ if (conflict.resolution === 'server_wins' && conflict.serverData) {
245
+ try {
246
+ await this.applyToLocal(engine, conflict.serverData);
247
+ }
248
+ catch (err) {
249
+ // Best effort
250
+ }
251
+ }
252
+ }
253
+ return {
254
+ pushed: result.synced,
255
+ conflicts: result.conflicts,
256
+ errors: [],
257
+ newCursor: result.newCursor,
258
+ };
259
+ }
260
+ /**
261
+ * Apply a SyncMemento to the local DB.
262
+ */
263
+ async applyToLocal(engine, memento) {
264
+ const existing = engine.getObservationByUuid(memento.uuid);
265
+ if (existing) {
266
+ if (existing.readOnly)
267
+ return;
268
+ await engine.updateObservation(existing.id, {
269
+ title: memento.title,
270
+ content: memento.content,
271
+ type: memento.type,
272
+ topicKey: memento.topicKey,
273
+ metadata: memento.metadata,
274
+ pinned: memento.pinned,
275
+ readOnly: memento.readOnly,
276
+ });
277
+ }
278
+ else {
279
+ // Find or create session
280
+ const sessions = await engine.listSessions({
281
+ projectId: memento.projectId,
282
+ limit: 1,
283
+ activeOnly: false,
284
+ });
285
+ let sessionId;
286
+ if (sessions.sessions.length > 0) {
287
+ sessionId = sessions.sessions[0].id;
288
+ }
289
+ else {
290
+ const session = await engine.createSession({
291
+ projectId: memento.projectId,
292
+ endedAt: null,
293
+ metadata: { source: 'sync', syncedAt: Date.now() },
294
+ });
295
+ sessionId = session.id;
296
+ }
297
+ await engine.createObservation({
298
+ sessionId,
299
+ title: memento.title,
300
+ content: memento.content,
301
+ type: memento.type,
302
+ topicKey: memento.topicKey,
303
+ projectId: memento.projectId,
304
+ scope: memento.scope,
305
+ pinned: memento.pinned,
306
+ readOnly: memento.readOnly,
307
+ metadata: { ...memento.metadata, syncedUuid: memento.uuid },
308
+ });
309
+ }
310
+ }
311
+ /**
312
+ * Convert a local Observation to a SyncMemento for the wire.
313
+ */
314
+ observationToMemento(obs) {
315
+ return {
316
+ uuid: obs.uuid,
317
+ title: obs.title,
318
+ content: obs.content,
319
+ type: obs.type,
320
+ topicKey: obs.topicKey,
321
+ scope: obs.scope,
322
+ pinned: obs.pinned,
323
+ readOnly: obs.readOnly,
324
+ revisionCount: obs.revisionCount,
325
+ projectId: obs.projectId,
326
+ metadata: obs.metadata,
327
+ localCreatedAt: obs.createdAt.toISOString(),
328
+ localUpdatedAt: obs.updatedAt.toISOString(),
329
+ version: obs.revisionCount + 1, // Version = revisionCount + 1 (first version is 1)
330
+ deletedAt: obs.deletedAt ? obs.deletedAt.toISOString() : null,
331
+ };
332
+ }
333
+ // ── Sync Meta Persistence ────────────────────────────────────
334
+ loadMeta() {
335
+ try {
336
+ if (fs.existsSync(this.metaPath)) {
337
+ const raw = fs.readFileSync(this.metaPath, 'utf-8');
338
+ return JSON.parse(raw);
339
+ }
340
+ }
341
+ catch {
342
+ // Corrupted — start fresh
343
+ }
344
+ return {
345
+ lastSyncAt: null,
346
+ lastSyncDirection: null,
347
+ lastCursor: null,
348
+ lastPullCount: 0,
349
+ lastPushCount: 0,
350
+ lastConflictCount: 0,
351
+ serverUrl: this.config.serverUrl,
352
+ updatedAt: Date.now(),
353
+ };
354
+ }
355
+ saveMeta(meta) {
356
+ const dir = path.dirname(this.metaPath);
357
+ if (!fs.existsSync(dir)) {
358
+ fs.mkdirSync(dir, { recursive: true });
359
+ }
360
+ fs.writeFileSync(this.metaPath, JSON.stringify(meta, null, 2), 'utf-8');
361
+ }
362
+ }
363
+ exports.SyncEngine = SyncEngine;
364
+ /** Generate a stable device fingerprint based on hostname + username */
365
+ function generateDeviceFingerprint() {
366
+ const hostname = os.hostname();
367
+ const username = os.userInfo().username;
368
+ return crypto.createHash('sha256').update(`${hostname}:${username}`).digest('hex').slice(0, 16);
369
+ }
370
+ //# sourceMappingURL=sync-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync-engine.js","sourceRoot":"","sources":["../../src/sync/sync-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ /** Sync direction */
2
+ export type SyncDirection = 'pull' | 'push' | 'bidirectional';
3
+ /**
4
+ * A memento item as transferred over the wire.
5
+ * Matches memento-web SyncMemento exactly.
6
+ */
7
+ export interface SyncMemento {
8
+ uuid: string;
9
+ title: string;
10
+ content: string;
11
+ type: string;
12
+ topicKey: string | null;
13
+ scope: 'project' | 'personal';
14
+ pinned: boolean;
15
+ readOnly: boolean;
16
+ revisionCount: number;
17
+ projectId: string;
18
+ metadata: Record<string, unknown>;
19
+ localCreatedAt: string;
20
+ localUpdatedAt: string;
21
+ version: number;
22
+ deletedAt: string | null;
23
+ }
24
+ /** Push request body — matches memento-web SyncPushRequest */
25
+ export interface SyncPushRequest {
26
+ projectId: string;
27
+ cursor: string | null;
28
+ deviceFingerprint?: string;
29
+ clientVersion?: string;
30
+ items: SyncMemento[];
31
+ }
32
+ /** Push response from memento-web */
33
+ export interface SyncPushResponse {
34
+ synced: number;
35
+ created: number;
36
+ updated: number;
37
+ conflicts: SyncConflict[];
38
+ newCursor: string;
39
+ }
40
+ /** Pull response from memento-web */
41
+ export interface SyncPullResponse {
42
+ changes: SyncMemento[];
43
+ hasMore: boolean;
44
+ totalChanges: number;
45
+ newCursor: string;
46
+ }
47
+ /** Pull query params */
48
+ export interface SyncPullParams {
49
+ projectId: string;
50
+ cursor: string | null;
51
+ limit?: number;
52
+ }
53
+ /** Conflict during push */
54
+ export interface SyncConflict {
55
+ uuid: string;
56
+ localVersion: number;
57
+ serverVersion: number;
58
+ resolution: 'client_wins' | 'server_wins';
59
+ serverData?: SyncMemento;
60
+ }
61
+ /** Status response from memento-web */
62
+ export interface SyncStatusResponse {
63
+ projectId: string;
64
+ lastSyncAt: string | null;
65
+ totalMementos: number;
66
+ pendingChanges: number | null;
67
+ conflicts: number;
68
+ device: {
69
+ fingerprint: string;
70
+ lastSyncAt: string | null;
71
+ } | null;
72
+ }
73
+ /** Sync metadata persisted locally */
74
+ export interface SyncMeta {
75
+ lastSyncAt: number | null;
76
+ lastSyncDirection: SyncDirection | null;
77
+ lastCursor: string | null;
78
+ lastPullCount: number;
79
+ lastPushCount: number;
80
+ lastConflictCount: number;
81
+ serverUrl: string;
82
+ updatedAt: number;
83
+ }
84
+ /** Result of a sync operation */
85
+ export interface SyncResult {
86
+ direction: SyncDirection;
87
+ pulled: number;
88
+ pushed: number;
89
+ conflicts: SyncConflict[];
90
+ errors: string[];
91
+ durationMs: number;
92
+ }
93
+ /** Configuration for the sync engine */
94
+ export interface SyncConfig {
95
+ serverUrl: string;
96
+ projectId: string;
97
+ fetchFunction?: typeof fetch;
98
+ metaFilePath?: string;
99
+ }
100
+ /** HTTP error from sync API */
101
+ export declare class SyncApiError extends Error {
102
+ status: number;
103
+ code?: string | undefined;
104
+ body?: string | undefined;
105
+ constructor(message: string, status: number, code?: string | undefined, body?: string | undefined);
106
+ }
107
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":"AAGA,qBAAqB;AACrB,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,GAAG,eAAe,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,SAAS,GAAG,UAAU,CAAC;IAC9B,MAAM,EAAE,OAAO,CAAC;IAChB,QAAQ,EAAE,OAAO,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,8DAA8D;AAC9D,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,WAAW,EAAE,CAAC;CACtB;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qCAAqC;AACrC,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,OAAO,EAAE,OAAO,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAwB;AACxB,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,2BAA2B;AAC3B,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,aAAa,GAAG,aAAa,CAAC;IAC1C,UAAU,CAAC,EAAE,WAAW,CAAC;CAC1B;AAED,uCAAuC;AACvC,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE;QACN,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;KAC3B,GAAG,IAAI,CAAC;CACV;AAED,sCAAsC;AACtC,MAAM,WAAW,QAAQ;IACvB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,iBAAiB,EAAE,aAAa,GAAG,IAAI,CAAC;IACxC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,iCAAiC;AACjC,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,aAAa,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,YAAY,EAAE,CAAC;IAC1B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wCAAwC;AACxC,MAAM,WAAW,UAAU;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,CAAC,EAAE,OAAO,KAAK,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,+BAA+B;AAC/B,qBAAa,YAAa,SAAQ,KAAK;IAG5B,MAAM,EAAE,MAAM;IACd,IAAI,CAAC,EAAE,MAAM;IACb,IAAI,CAAC,EAAE,MAAM;gBAHpB,OAAO,EAAE,MAAM,EACR,MAAM,EAAE,MAAM,EACd,IAAI,CAAC,EAAE,MAAM,YAAA,EACb,IAAI,CAAC,EAAE,MAAM,YAAA;CAKvB"}
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ // ─── Sync Types — Memento v1 Protocol ──────────────────────────
3
+ // Matches memento-web/src/types/sync.ts
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ exports.SyncApiError = void 0;
6
+ /** HTTP error from sync API */
7
+ class SyncApiError extends Error {
8
+ status;
9
+ code;
10
+ body;
11
+ constructor(message, status, code, body) {
12
+ super(message);
13
+ this.status = status;
14
+ this.code = code;
15
+ this.body = body;
16
+ this.name = 'SyncApiError';
17
+ }
18
+ }
19
+ exports.SyncApiError = SyncApiError;
20
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/sync/types.ts"],"names":[],"mappings":";AAAA,kEAAkE;AAClE,wCAAwC;;;AAgHxC,+BAA+B;AAC/B,MAAa,YAAa,SAAQ,KAAK;IAG5B;IACA;IACA;IAJT,YACE,OAAe,EACR,MAAc,EACd,IAAa,EACb,IAAa;QAEpB,KAAK,CAAC,OAAO,CAAC,CAAC;QAJR,WAAM,GAAN,MAAM,CAAQ;QACd,SAAI,GAAJ,IAAI,CAAS;QACb,SAAI,GAAJ,IAAI,CAAS;QAGpB,IAAI,CAAC,IAAI,GAAG,cAAc,CAAC;IAC7B,CAAC;CACF;AAVD,oCAUC"}
@@ -0,0 +1,42 @@
1
+ import type { Observation } from './types';
2
+ /**
3
+ * Estimate the number of tokens in a string.
4
+ * Uses simple chars/4 ratio — no tokenizer dependency needed.
5
+ */
6
+ export declare function estimateTokens(text: string): number;
7
+ /**
8
+ * Get the multiplier for an observation type.
9
+ */
10
+ export declare function getTypeMultiplier(type: Observation['type']): number;
11
+ /**
12
+ * Estimate token savings for a single observation.
13
+ * Formula: content_tokens × type_multiplier
14
+ */
15
+ export declare function estimateSavingsForObservation(obs: {
16
+ content: string;
17
+ type: Observation['type'];
18
+ }): number;
19
+ /**
20
+ * Estimate total token savings for a list of observations.
21
+ * Returns raw savings without multiplier (contentTokens) and total with multiplier.
22
+ */
23
+ export declare function estimateTotalSavings(observations: Array<{
24
+ content: string;
25
+ type: Observation['type'];
26
+ }>): {
27
+ /** Sum of raw content tokens across all observations */
28
+ contentTokens: number;
29
+ /** Sum of (content_tokens × type_multiplier) across all observations */
30
+ estimatedTokensSaved: number;
31
+ /** Number of observations used in the calculation */
32
+ observationCount: number;
33
+ };
34
+ /**
35
+ * Format token savings as a human-readable string for MCP responses.
36
+ */
37
+ export declare function formatTokenSavings(savings: {
38
+ estimatedTokensSaved: number;
39
+ observationCount: number;
40
+ contentTokens: number;
41
+ }): string;
42
+ //# sourceMappingURL=token-savings.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-savings.d.ts","sourceRoot":"","sources":["../src/token-savings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAsC3C;;;GAGG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,MAAM,CAEnE;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,GAAG,EAAE;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,GAAG,MAAM,CAIzG;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,YAAY,EAAE,KAAK,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,GAAG;IACzG,wDAAwD;IACxD,aAAa,EAAE,MAAM,CAAC;IACtB,wEAAwE;IACxE,oBAAoB,EAAE,MAAM,CAAC;IAC7B,qDAAqD;IACrD,gBAAgB,EAAE,MAAM,CAAC;CAC1B,CAgBA;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE;IAC1C,oBAAoB,EAAE,MAAM,CAAC;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,MAAM,CAsBT"}