@spool-lab/core 0.4.0 → 0.4.12

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 (171) hide show
  1. package/dist/db/db.d.ts +19 -0
  2. package/dist/db/db.d.ts.map +1 -1
  3. package/dist/db/db.js +210 -15
  4. package/dist/db/db.js.map +1 -1
  5. package/dist/db/queries.d.ts +36 -10
  6. package/dist/db/queries.d.ts.map +1 -1
  7. package/dist/db/queries.js +96 -75
  8. package/dist/db/queries.js.map +1 -1
  9. package/dist/db/share-drafts.d.ts +51 -0
  10. package/dist/db/share-drafts.d.ts.map +1 -0
  11. package/dist/db/share-drafts.js +47 -0
  12. package/dist/db/share-drafts.js.map +1 -0
  13. package/dist/doctor/checks/config.d.ts +3 -0
  14. package/dist/doctor/checks/config.d.ts.map +1 -0
  15. package/dist/doctor/checks/config.js +123 -0
  16. package/dist/doctor/checks/config.js.map +1 -0
  17. package/dist/doctor/checks/db.d.ts +3 -0
  18. package/dist/doctor/checks/db.d.ts.map +1 -0
  19. package/dist/doctor/checks/db.js +225 -0
  20. package/dist/doctor/checks/db.js.map +1 -0
  21. package/dist/doctor/checks/env.d.ts +3 -0
  22. package/dist/doctor/checks/env.d.ts.map +1 -0
  23. package/dist/doctor/checks/env.js +70 -0
  24. package/dist/doctor/checks/env.js.map +1 -0
  25. package/dist/doctor/checks/index.d.ts +3 -0
  26. package/dist/doctor/checks/index.d.ts.map +1 -0
  27. package/dist/doctor/checks/index.js +13 -0
  28. package/dist/doctor/checks/index.js.map +1 -0
  29. package/dist/doctor/checks/native.d.ts +3 -0
  30. package/dist/doctor/checks/native.d.ts.map +1 -0
  31. package/dist/doctor/checks/native.js +42 -0
  32. package/dist/doctor/checks/native.js.map +1 -0
  33. package/dist/doctor/checks/versions.d.ts +3 -0
  34. package/dist/doctor/checks/versions.d.ts.map +1 -0
  35. package/dist/doctor/checks/versions.js +79 -0
  36. package/dist/doctor/checks/versions.js.map +1 -0
  37. package/dist/doctor/index.d.ts +3 -0
  38. package/dist/doctor/index.d.ts.map +1 -0
  39. package/dist/doctor/index.js +3 -0
  40. package/dist/doctor/index.js.map +1 -0
  41. package/dist/doctor/preflight.d.ts +18 -0
  42. package/dist/doctor/preflight.d.ts.map +1 -0
  43. package/dist/doctor/preflight.js +27 -0
  44. package/dist/doctor/preflight.js.map +1 -0
  45. package/dist/doctor/runner.d.ts +12 -0
  46. package/dist/doctor/runner.d.ts.map +1 -0
  47. package/dist/doctor/runner.js +37 -0
  48. package/dist/doctor/runner.js.map +1 -0
  49. package/dist/doctor/types.d.ts +27 -0
  50. package/dist/doctor/types.d.ts.map +1 -0
  51. package/dist/doctor/types.js +2 -0
  52. package/dist/doctor/types.js.map +1 -0
  53. package/dist/index.d.ts +5 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +5 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/migrations/agent-search-cleanup.d.ts +36 -0
  58. package/dist/migrations/agent-search-cleanup.d.ts.map +1 -0
  59. package/dist/migrations/agent-search-cleanup.js +182 -0
  60. package/dist/migrations/agent-search-cleanup.js.map +1 -0
  61. package/dist/migrations/worktree-identity-upgrade.d.ts +31 -0
  62. package/dist/migrations/worktree-identity-upgrade.d.ts.map +1 -0
  63. package/dist/migrations/worktree-identity-upgrade.js +22 -0
  64. package/dist/migrations/worktree-identity-upgrade.js.map +1 -0
  65. package/dist/parsers/claude.d.ts.map +1 -1
  66. package/dist/parsers/claude.js +25 -12
  67. package/dist/parsers/claude.js.map +1 -1
  68. package/dist/parsers/codex.d.ts.map +1 -1
  69. package/dist/parsers/codex.js +32 -5
  70. package/dist/parsers/codex.js.map +1 -1
  71. package/dist/parsers/gemini.d.ts.map +1 -1
  72. package/dist/parsers/gemini.js +5 -5
  73. package/dist/parsers/gemini.js.map +1 -1
  74. package/dist/parsers/spool-prelude.d.ts +16 -0
  75. package/dist/parsers/spool-prelude.d.ts.map +1 -0
  76. package/dist/parsers/spool-prelude.js +21 -0
  77. package/dist/parsers/spool-prelude.js.map +1 -0
  78. package/dist/projects/display-name.d.ts +2 -0
  79. package/dist/projects/display-name.d.ts.map +1 -0
  80. package/dist/projects/display-name.js +8 -0
  81. package/dist/projects/display-name.js.map +1 -0
  82. package/dist/projects/fs.d.ts +3 -0
  83. package/dist/projects/fs.d.ts.map +1 -0
  84. package/dist/projects/fs.js +20 -0
  85. package/dist/projects/fs.js.map +1 -0
  86. package/dist/projects/groups.d.ts +4 -0
  87. package/dist/projects/groups.d.ts.map +1 -0
  88. package/dist/projects/groups.js +20 -0
  89. package/dist/projects/groups.js.map +1 -0
  90. package/dist/projects/identity-synthesizers.d.ts +22 -0
  91. package/dist/projects/identity-synthesizers.d.ts.map +1 -0
  92. package/dist/projects/identity-synthesizers.js +29 -0
  93. package/dist/projects/identity-synthesizers.js.map +1 -0
  94. package/dist/projects/identity.d.ts +16 -0
  95. package/dist/projects/identity.d.ts.map +1 -0
  96. package/dist/projects/identity.js +172 -0
  97. package/dist/projects/identity.js.map +1 -0
  98. package/dist/projects/sessions.d.ts +12 -0
  99. package/dist/projects/sessions.d.ts.map +1 -0
  100. package/dist/projects/sessions.js +47 -0
  101. package/dist/projects/sessions.js.map +1 -0
  102. package/dist/projects/worktree-resolvers.d.ts +19 -0
  103. package/dist/projects/worktree-resolvers.d.ts.map +1 -0
  104. package/dist/projects/worktree-resolvers.js +65 -0
  105. package/dist/projects/worktree-resolvers.js.map +1 -0
  106. package/dist/sync/syncer.d.ts.map +1 -1
  107. package/dist/sync/syncer.js +11 -3
  108. package/dist/sync/syncer.js.map +1 -1
  109. package/dist/types.d.ts +15 -6
  110. package/dist/types.d.ts.map +1 -1
  111. package/package.json +2 -2
  112. package/dist/connectors/capabilities/cookies-chrome.d.ts +0 -19
  113. package/dist/connectors/capabilities/cookies-chrome.d.ts.map +0 -1
  114. package/dist/connectors/capabilities/cookies-chrome.js +0 -199
  115. package/dist/connectors/capabilities/cookies-chrome.js.map +0 -1
  116. package/dist/connectors/capabilities/exec-impl.d.ts +0 -3
  117. package/dist/connectors/capabilities/exec-impl.d.ts.map +0 -1
  118. package/dist/connectors/capabilities/exec-impl.js +0 -108
  119. package/dist/connectors/capabilities/exec-impl.js.map +0 -1
  120. package/dist/connectors/capabilities/fetch-impl.d.ts +0 -3
  121. package/dist/connectors/capabilities/fetch-impl.d.ts.map +0 -1
  122. package/dist/connectors/capabilities/fetch-impl.js +0 -4
  123. package/dist/connectors/capabilities/fetch-impl.js.map +0 -1
  124. package/dist/connectors/capabilities/index.d.ts +0 -6
  125. package/dist/connectors/capabilities/index.d.ts.map +0 -1
  126. package/dist/connectors/capabilities/index.js +0 -6
  127. package/dist/connectors/capabilities/index.js.map +0 -1
  128. package/dist/connectors/capabilities/log-impl.d.ts +0 -3
  129. package/dist/connectors/capabilities/log-impl.d.ts.map +0 -1
  130. package/dist/connectors/capabilities/log-impl.js +0 -26
  131. package/dist/connectors/capabilities/log-impl.js.map +0 -1
  132. package/dist/connectors/capabilities/sqlite-impl.d.ts +0 -3
  133. package/dist/connectors/capabilities/sqlite-impl.d.ts.map +0 -1
  134. package/dist/connectors/capabilities/sqlite-impl.js +0 -19
  135. package/dist/connectors/capabilities/sqlite-impl.js.map +0 -1
  136. package/dist/connectors/loader.d.ts +0 -47
  137. package/dist/connectors/loader.d.ts.map +0 -1
  138. package/dist/connectors/loader.js +0 -328
  139. package/dist/connectors/loader.js.map +0 -1
  140. package/dist/connectors/npm-install.d.ts +0 -26
  141. package/dist/connectors/npm-install.d.ts.map +0 -1
  142. package/dist/connectors/npm-install.js +0 -74
  143. package/dist/connectors/npm-install.js.map +0 -1
  144. package/dist/connectors/prerequisites.d.ts +0 -14
  145. package/dist/connectors/prerequisites.d.ts.map +0 -1
  146. package/dist/connectors/prerequisites.js +0 -109
  147. package/dist/connectors/prerequisites.js.map +0 -1
  148. package/dist/connectors/registry-fetch.d.ts +0 -22
  149. package/dist/connectors/registry-fetch.d.ts.map +0 -1
  150. package/dist/connectors/registry-fetch.js +0 -54
  151. package/dist/connectors/registry-fetch.js.map +0 -1
  152. package/dist/connectors/registry.d.ts +0 -23
  153. package/dist/connectors/registry.d.ts.map +0 -1
  154. package/dist/connectors/registry.js +0 -59
  155. package/dist/connectors/registry.js.map +0 -1
  156. package/dist/connectors/sync-engine.d.ts +0 -31
  157. package/dist/connectors/sync-engine.d.ts.map +0 -1
  158. package/dist/connectors/sync-engine.js +0 -604
  159. package/dist/connectors/sync-engine.js.map +0 -1
  160. package/dist/connectors/sync-scheduler.d.ts +0 -56
  161. package/dist/connectors/sync-scheduler.d.ts.map +0 -1
  162. package/dist/connectors/sync-scheduler.js +0 -238
  163. package/dist/connectors/sync-scheduler.js.map +0 -1
  164. package/dist/connectors/trust-store.d.ts +0 -13
  165. package/dist/connectors/trust-store.d.ts.map +0 -1
  166. package/dist/connectors/trust-store.js +0 -48
  167. package/dist/connectors/trust-store.js.map +0 -1
  168. package/dist/connectors/types.d.ts +0 -111
  169. package/dist/connectors/types.d.ts.map +0 -1
  170. package/dist/connectors/types.js +0 -50
  171. package/dist/connectors/types.js.map +0 -1
@@ -1,604 +0,0 @@
1
- import { randomUUID } from 'node:crypto';
2
- import { Clock, Deferred, Duration, Effect } from 'effect';
3
- import { SyncError, DEFAULT_SCHEDULE } from './types.js';
4
- /**
5
- * Bridge an optional AbortSignal into a CancelSignal registered in the
6
- * ambient Scope. The listener is cleaned up by the scope's finalizer.
7
- */
8
- function bridgeAbortSignal(signal, cancel) {
9
- if (!signal)
10
- return Effect.void;
11
- if (signal.aborted)
12
- return Deferred.succeed(cancel, undefined).pipe(Effect.asVoid);
13
- return Effect.acquireRelease(Effect.sync(() => {
14
- const handler = () => {
15
- Deferred.unsafeDone(cancel, Effect.void);
16
- };
17
- signal.addEventListener('abort', handler, { once: true });
18
- return handler;
19
- }), (handler) => Effect.sync(() => signal.removeEventListener('abort', handler))).pipe(Effect.asVoid);
20
- }
21
- function cancelDeferredToSignal(cancel) {
22
- return Effect.sync(() => {
23
- const controller = new AbortController();
24
- Effect.runFork(Effect.gen(function* () {
25
- yield* Deferred.await(cancel);
26
- controller.abort();
27
- }));
28
- return controller.signal;
29
- });
30
- }
31
- /**
32
- * Sleep `ms` milliseconds but wake immediately if the cancel signal fires.
33
- * The loop top still polls the cancel signal for a graceful
34
- * `stopReason='cancelled'` return; this racer just cuts the sleep short.
35
- */
36
- function interruptibleSleep(ms, cancel) {
37
- return Effect.race(Effect.sleep(Duration.millis(ms)), Deferred.await(cancel)).pipe(Effect.asVoid);
38
- }
39
- const nowIso = Effect.map(Clock.currentTimeMillis, (ms) => new Date(ms).toISOString());
40
- // ── Sync State Persistence ──────────────────────────────────────────────────
41
- export function loadSyncState(db, connectorId) {
42
- const row = db.prepare('SELECT * FROM connector_sync_state WHERE connector_id = ?')
43
- .get(connectorId);
44
- if (!row) {
45
- return {
46
- connectorId,
47
- headCursor: null,
48
- headItemId: null,
49
- tailCursor: null,
50
- tailComplete: false,
51
- lastForwardSyncAt: null,
52
- lastBackfillSyncAt: null,
53
- totalSynced: 0,
54
- consecutiveErrors: 0,
55
- enabled: false,
56
- configJson: {},
57
- lastErrorAt: null,
58
- lastErrorCode: null,
59
- lastErrorMessage: null,
60
- };
61
- }
62
- let configJson = {};
63
- try {
64
- configJson = JSON.parse(row['config_json']);
65
- }
66
- catch { }
67
- return {
68
- connectorId,
69
- headCursor: row['head_cursor'],
70
- headItemId: row['head_item_id'],
71
- tailCursor: row['tail_cursor'],
72
- tailComplete: Boolean(row['tail_complete']),
73
- lastForwardSyncAt: row['last_forward_sync_at'],
74
- lastBackfillSyncAt: row['last_backfill_sync_at'],
75
- totalSynced: row['total_synced'],
76
- consecutiveErrors: row['consecutive_errors'],
77
- enabled: Boolean(row['enabled']),
78
- configJson,
79
- lastErrorAt: row['last_error_at'],
80
- lastErrorCode: row['last_error_code'],
81
- lastErrorMessage: row['last_error_message'],
82
- };
83
- }
84
- export function saveSyncState(db, state) {
85
- db.prepare(`
86
- INSERT INTO connector_sync_state
87
- (connector_id, head_cursor, head_item_id, tail_cursor, tail_complete,
88
- last_forward_sync_at, last_backfill_sync_at, total_synced,
89
- consecutive_errors, enabled, config_json,
90
- last_error_at, last_error_code, last_error_message)
91
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
92
- ON CONFLICT(connector_id) DO UPDATE SET
93
- head_cursor = excluded.head_cursor,
94
- head_item_id = excluded.head_item_id,
95
- tail_cursor = excluded.tail_cursor,
96
- tail_complete = excluded.tail_complete,
97
- last_forward_sync_at = excluded.last_forward_sync_at,
98
- last_backfill_sync_at = excluded.last_backfill_sync_at,
99
- total_synced = excluded.total_synced,
100
- consecutive_errors = excluded.consecutive_errors,
101
- enabled = excluded.enabled,
102
- config_json = excluded.config_json,
103
- last_error_at = excluded.last_error_at,
104
- last_error_code = excluded.last_error_code,
105
- last_error_message = excluded.last_error_message
106
- `).run(state.connectorId, state.headCursor, state.headItemId, state.tailCursor, state.tailComplete ? 1 : 0, state.lastForwardSyncAt, state.lastBackfillSyncAt, state.totalSynced, state.consecutiveErrors, state.enabled ? 1 : 0, JSON.stringify(state.configJson), state.lastErrorAt, state.lastErrorCode, state.lastErrorMessage);
107
- }
108
- function upsertItems(db, sourceId, connectorId, items) {
109
- let newCount = 0;
110
- let updatedCount = 0;
111
- const checkStmt = db.prepare('SELECT id FROM captures WHERE platform = ? AND platform_id = ?');
112
- const updateStmt = db.prepare(`
113
- UPDATE captures SET
114
- title = ?, content_text = ?, author = ?, metadata = ?,
115
- captured_at = ?, raw_json = ?, thumbnail_url = ?
116
- WHERE id = ?
117
- `);
118
- const insertStmt = db.prepare(`
119
- INSERT INTO captures
120
- (source_id, capture_uuid, url, title, content_text,
121
- author, platform, platform_id, content_type, thumbnail_url,
122
- metadata, captured_at, raw_json)
123
- VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
124
- `);
125
- const linkStmt = db.prepare('INSERT OR IGNORE INTO capture_connectors (capture_id, connector_id) VALUES (?, ?)');
126
- for (const item of items) {
127
- let captureId = null;
128
- if (item.platformId) {
129
- const existing = checkStmt.get(item.platform, item.platformId);
130
- if (existing) {
131
- updateStmt.run(item.title, item.contentText, item.author, JSON.stringify(item.metadata), item.capturedAt, item.rawJson, item.thumbnailUrl, existing.id);
132
- captureId = existing.id;
133
- updatedCount++;
134
- }
135
- }
136
- if (captureId === null) {
137
- const info = insertStmt.run(sourceId, randomUUID(), item.url, item.title, item.contentText, item.author, item.platform, item.platformId, item.contentType, item.thumbnailUrl, JSON.stringify(item.metadata), item.capturedAt, item.rawJson);
138
- captureId = info.lastInsertRowid;
139
- newCount++;
140
- }
141
- linkStmt.run(captureId, connectorId);
142
- }
143
- return { newCount, updatedCount };
144
- }
145
- export function deleteConnectorItems(db, connectorId) {
146
- // 1. Drop this connector's M:N claims.
147
- db.prepare('DELETE FROM capture_connectors WHERE connector_id = ?').run(connectorId);
148
- // 2. Drop stars on captures that are about to disappear. Bulk-replace
149
- // connectors (ephemeral or full-wipe) re-insert captures with new UUIDs
150
- // on the next sync, so without this the star becomes a permanent orphan.
151
- // Scoped with the same predicate as the capture delete below.
152
- db.prepare(`
153
- DELETE FROM stars
154
- WHERE item_type = 'capture'
155
- AND item_uuid IN (
156
- SELECT capture_uuid FROM captures
157
- WHERE source_id = (SELECT id FROM sources WHERE name = 'connector')
158
- AND NOT EXISTS (
159
- SELECT 1 FROM capture_connectors WHERE capture_id = captures.id
160
- )
161
- )
162
- `).run();
163
- // 3. Delete captures that belonged to this connector and have no other
164
- // connector attribution left. Scoped to source='connector' so we never
165
- // touch session-world captures.
166
- db.prepare(`
167
- DELETE FROM captures
168
- WHERE source_id = (SELECT id FROM sources WHERE name = 'connector')
169
- AND NOT EXISTS (
170
- SELECT 1 FROM capture_connectors WHERE capture_id = captures.id
171
- )
172
- `).run();
173
- }
174
- // ── Sync Engine ─────────────────────────────────────────────────────────────
175
- function getSourceId(db) {
176
- // Connector captures all share a single generic 'connector' source row.
177
- // Per-connector attribution lives in the capture_connectors M:N table.
178
- const row = db.prepare("SELECT id FROM sources WHERE name = 'connector'").get();
179
- if (!row)
180
- throw new Error("Source 'connector' not found in DB");
181
- return row.id;
182
- }
183
- function hasKnownItem(db, platform, items) {
184
- if (items.length === 0)
185
- return false;
186
- const stmt = db.prepare('SELECT 1 FROM captures WHERE platform = ? AND platform_id = ? LIMIT 1');
187
- for (const item of items) {
188
- if (item.platformId && stmt.get(platform, item.platformId))
189
- return true;
190
- }
191
- return false;
192
- }
193
- export class SyncEngine {
194
- db;
195
- constructor(db) {
196
- this.db = db;
197
- }
198
- loadState(connectorId) {
199
- return loadSyncState(this.db, connectorId);
200
- }
201
- /**
202
- * Effect-native entry point. Returns an Effect that, when run, executes a
203
- * full sync cycle (ephemeral or dual-frontier persistent) and records the
204
- * outcome in connector_sync_state. The Effect is `Effect<ConnectorSyncResult, never>`
205
- * because all SyncErrors are caught internally and encoded in `result.error`.
206
- *
207
- * Preferred by callers that already live in the Effect world (the Scheduler
208
- * Effect migration, tests that want to inject Logger / Tracer layers via
209
- * `Effect.provide`). Promise-based callers should use `sync()` instead.
210
- */
211
- syncEffect(connector, opts = {}) {
212
- const db = this.db;
213
- const self = this;
214
- return Effect.gen(function* () {
215
- const state = yield* Effect.sync(() => loadSyncState(db, connector.id));
216
- const startedAt = yield* Clock.currentTimeMillis;
217
- const cancel = opts.cancel ?? (yield* Deferred.make());
218
- yield* bridgeAbortSignal(opts.signal, cancel);
219
- const body = connector.ephemeral
220
- ? self.syncEphemeralEffect(connector, state, opts, startedAt, cancel)
221
- : self.syncPersistentEffect(connector, state, opts, startedAt, cancel);
222
- const result = yield* body.pipe(Effect.withSpan('sync.cycle', {
223
- attributes: {
224
- 'connector.id': connector.id,
225
- 'sync.direction': opts.direction ?? 'both',
226
- },
227
- }));
228
- if (result.error) {
229
- state.consecutiveErrors += 1;
230
- state.lastErrorAt = yield* nowIso;
231
- state.lastErrorCode = result.error.code;
232
- state.lastErrorMessage = result.error.message;
233
- }
234
- else {
235
- state.consecutiveErrors = 0;
236
- state.lastErrorAt = null;
237
- state.lastErrorCode = null;
238
- state.lastErrorMessage = null;
239
- }
240
- yield* Effect.sync(() => saveSyncState(db, state));
241
- return result;
242
- // Effect.scoped discharges the Scope required by bridgeAbortSignal's
243
- // acquireRelease, guaranteeing removeEventListener runs on every exit
244
- // path (success, failure, interruption).
245
- }).pipe(Effect.scoped);
246
- }
247
- async sync(connector, opts = {}) {
248
- // opts.signal is bridged into an internal Deferred by syncEffect —
249
- // NOT passed to runPromise, because runtime interruption would
250
- // skip state persistence and surface as an error. Cancellation must
251
- // be observable inside the loop (via Deferred.isDone) so the loop
252
- // can return gracefully with stopReason='cancelled' + partial progress.
253
- try {
254
- return await Effect.runPromise(this.syncEffect(connector, opts));
255
- }
256
- catch (err) {
257
- // Defect surfaced past the typed error channel — defensive fallback.
258
- const state = loadSyncState(this.db, connector.id);
259
- const syncErr = SyncError.from(err);
260
- state.consecutiveErrors += 1;
261
- state.lastErrorAt = new Date().toISOString();
262
- state.lastErrorCode = syncErr.code;
263
- state.lastErrorMessage = syncErr.message;
264
- saveSyncState(this.db, state);
265
- return {
266
- connectorId: connector.id,
267
- added: 0,
268
- total: state.totalSynced,
269
- pages: 0,
270
- direction: opts.direction ?? 'both',
271
- stopReason: `error: ${syncErr.code}`,
272
- error: { code: syncErr.code, message: syncErr.message },
273
- };
274
- }
275
- }
276
- /**
277
- * Fetch pages in an Effect-based loop until a stop condition is met.
278
- * Errors are caught internally and returned in the result (never fails).
279
- */
280
- fetchLoopEffect(connector, state, opts, sourceId, startCursor, startedAt, cancel, signal) {
281
- const db = this.db;
282
- const delayMs = opts.delayMs ?? DEFAULT_SCHEDULE.pageDelayMs;
283
- const maxMinutes = opts.maxMinutes ?? 0;
284
- const maxPages = opts.maxPages ?? 100;
285
- const stalePageLimit = opts.stalePageLimit ?? 3;
286
- const checkpointEvery = 25;
287
- const deadline = maxMinutes > 0 ? startedAt + maxMinutes * 60_000 : Number.POSITIVE_INFINITY;
288
- // Initial sync handoff: forward writes tailCursor ONLY on the very first sync
289
- // (tailCursor still null, no prior forward interrupted = headCursor null).
290
- // This lets backfill pick up where forward left off. On subsequent cycles,
291
- // forward must NOT touch tailCursor — otherwise it overwrites backfill's
292
- // deep progress with a shallow position near the newest end.
293
- const isInitialSync = opts.phase === 'forward'
294
- && state.tailCursor === null
295
- && state.headCursor === null;
296
- // Capture the since-anchor at loop entry, before page-0 may update
297
- // headItemId. This is the stop signal for forward early-exit:
298
- // "stop when you reach this item — everything at or beyond it is already indexed."
299
- const sinceItemId = opts.phase === 'forward' ? state.headItemId : null;
300
- return Effect.gen(function* () {
301
- let cursor = startCursor;
302
- let added = 0;
303
- let pages = 0;
304
- let stalePages = 0;
305
- while (true) {
306
- const now = yield* Clock.currentTimeMillis;
307
- if (now >= deadline) {
308
- return { added, pages, stopReason: 'timeout' };
309
- }
310
- if (pages >= maxPages) {
311
- return { added, pages, stopReason: 'max_pages' };
312
- }
313
- if (yield* Deferred.isDone(cancel)) {
314
- return { added, pages, stopReason: 'cancelled' };
315
- }
316
- const fetchCtx = { cursor, sinceItemId, phase: opts.phase, signal };
317
- const outcome = yield* Effect.either(Effect.tryPromise({
318
- try: () => connector.fetchPage(fetchCtx),
319
- catch: SyncError.from,
320
- }).pipe(Effect.withSpan('sync.fetchPage', {
321
- attributes: {
322
- 'connector.id': connector.id,
323
- 'sync.phase': opts.phase,
324
- 'sync.page': pages + 1,
325
- },
326
- })));
327
- if (outcome._tag === 'Left') {
328
- const err = outcome.left;
329
- yield* Effect.logError(`[sync-engine] ${connector.id} ${opts.phase} page ${pages + 1} error: ${err.message}`);
330
- yield* Effect.sync(() => saveSyncState(db, state));
331
- return {
332
- added,
333
- pages,
334
- stopReason: `error: ${err.code}`,
335
- error: { code: err.code, message: err.message },
336
- };
337
- }
338
- const result = outcome.right;
339
- pages++;
340
- if (result.items.length === 0 && !result.nextCursor) {
341
- if (opts.phase === 'forward')
342
- state.headCursor = null;
343
- if (opts.phase === 'backfill')
344
- state.tailComplete = true;
345
- return {
346
- added,
347
- pages,
348
- stopReason: opts.phase === 'backfill' ? 'backfill_complete' : 'end_of_data',
349
- };
350
- }
351
- const { newCount } = yield* Effect.sync(() => db.transaction(() => upsertItems(db, sourceId, connector.id, result.items))()).pipe(Effect.withSpan('sync.upsert', {
352
- attributes: { 'items.count': result.items.length },
353
- }));
354
- added += newCount;
355
- // Update headItemId: the platform ID of the newest item we've ever seen.
356
- // Only on forward, only on the first page (pages === 1 after increment),
357
- // and only when NOT resuming from headCursor — a resumed forward is
358
- // catching up to the existing anchor, not establishing a new one.
359
- // On platforms with cursor-walking (no server-side since), the first page
360
- // of a fresh forward always starts at the newest end, so page-0's first
361
- // item is guaranteed to be >= the current headItemId.
362
- if (opts.phase === 'forward' && pages === 1 && startCursor === null) {
363
- const firstItem = result.items[0];
364
- if (firstItem?.platformId && firstItem.platformId !== state.headItemId) {
365
- state.headItemId = firstItem.platformId;
366
- }
367
- }
368
- if (opts.onProgress) {
369
- const progress = {
370
- connectorId: connector.id,
371
- phase: opts.phase,
372
- page: pages,
373
- fetched: result.items.length,
374
- added,
375
- running: true,
376
- };
377
- yield* Effect.sync(() => opts.onProgress(progress));
378
- }
379
- // Early-exit: forward stops when it reaches the since-anchor (headItemId).
380
- // This means we've caught up to the point where the last forward left off.
381
- // Much more efficient than stale-page detection for small incremental syncs
382
- // (e.g. 2 new bookmarks → 1 page instead of 3+ stale pages).
383
- // Note: sinceItemId was already captured into headItemId before page 0's
384
- // update (headItemId is only updated on page 0 of a fresh forward),
385
- // so we compare against the original anchor stored at fetchLoop entry.
386
- if (opts.phase === 'forward' && sinceItemId) {
387
- const hitAnchor = result.items.some(item => item.platformId === sinceItemId);
388
- if (hitAnchor) {
389
- state.headCursor = null;
390
- return { added, pages, stopReason: 'reached_since' };
391
- }
392
- }
393
- // Stale page detection: stop when we keep seeing only known data
394
- if (newCount === 0)
395
- stalePages++;
396
- else
397
- stalePages = 0;
398
- if (stalePages >= stalePageLimit) {
399
- if (opts.phase === 'forward')
400
- state.headCursor = null;
401
- if (opts.phase === 'backfill')
402
- state.tailComplete = true;
403
- return {
404
- added,
405
- pages,
406
- stopReason: opts.phase === 'forward' ? 'caught_up' : 'backfill_complete',
407
- };
408
- }
409
- if (!result.nextCursor) {
410
- if (opts.phase === 'forward')
411
- state.headCursor = null;
412
- if (opts.phase === 'backfill')
413
- state.tailComplete = true;
414
- return {
415
- added,
416
- pages,
417
- stopReason: opts.phase === 'backfill' ? 'backfill_complete' : 'end_of_data',
418
- };
419
- }
420
- cursor = result.nextCursor;
421
- if (opts.phase === 'forward') {
422
- // Save forward progress so an interrupted cycle can resume here
423
- // instead of re-fetching from the newest end.
424
- state.headCursor = cursor;
425
- // Only write tailCursor during initial sync (handoff to backfill).
426
- if (isInitialSync)
427
- state.tailCursor = cursor;
428
- }
429
- else {
430
- state.tailCursor = cursor;
431
- }
432
- if (pages % checkpointEvery === 0) {
433
- yield* Effect.sync(() => saveSyncState(db, state));
434
- }
435
- // Cap the inter-page delay at the remaining deadline so maxMinutes
436
- // has ms-level precision instead of being gated on polling frequency.
437
- const nowAfter = yield* Clock.currentTimeMillis;
438
- const remaining = deadline - nowAfter;
439
- const actualDelay = Math.max(0, Math.min(delayMs, remaining));
440
- if (actualDelay > 0) {
441
- yield* interruptibleSleep(actualDelay, cancel);
442
- }
443
- }
444
- });
445
- }
446
- syncPersistentEffect(connector, state, opts, startedAt, cancel) {
447
- const db = this.db;
448
- const direction = opts.direction ?? 'both';
449
- const sourceId = getSourceId(db);
450
- const self = this;
451
- return Effect.gen(function* () {
452
- const signal = yield* cancelDeferredToSignal(cancel);
453
- let totalAdded = 0;
454
- let totalPages = 0;
455
- let stopReason = 'complete';
456
- let lastError;
457
- if (direction === 'forward' || direction === 'both') {
458
- const hadAnchor = state.headItemId !== null;
459
- const fwd = yield* self
460
- .fetchLoopEffect(connector, state, { ...opts, phase: 'forward' }, sourceId, state.headCursor ?? null, startedAt, cancel, signal)
461
- .pipe(Effect.withSpan('sync.forward'));
462
- totalAdded += fwd.added;
463
- totalPages += fwd.pages;
464
- stopReason = fwd.stopReason;
465
- if (fwd.error)
466
- lastError = fwd.error;
467
- state.lastForwardSyncAt = yield* nowIso;
468
- // Anchor invalidation recovery (Q3): if forward ran to completion
469
- // (not interrupted) but never hit the since-anchor, the anchor is stale
470
- // (e.g. user un-bookmarked that item). Clear it so next forward starts
471
- // fresh and re-establishes the anchor from page 0.
472
- const completedWithoutHit = hadAnchor
473
- && fwd.stopReason !== 'reached_since'
474
- && fwd.stopReason !== 'timeout'
475
- && fwd.stopReason !== 'cancelled'
476
- && !fwd.stopReason.startsWith('error');
477
- if (completedWithoutHit) {
478
- state.headItemId = null;
479
- }
480
- }
481
- if (!lastError && !state.tailComplete && (direction === 'backfill' || direction === 'both')) {
482
- const bf = yield* self
483
- .fetchLoopEffect(connector, state, { ...opts, phase: 'backfill' }, sourceId, state.tailCursor, startedAt, cancel, signal)
484
- .pipe(Effect.withSpan('sync.backfill'));
485
- totalAdded += bf.added;
486
- totalPages += bf.pages;
487
- stopReason = bf.stopReason;
488
- if (bf.error)
489
- lastError = bf.error;
490
- state.lastBackfillSyncAt = yield* nowIso;
491
- }
492
- state.totalSynced += totalAdded;
493
- yield* Effect.sync(() => saveSyncState(db, state));
494
- yield* Effect.logInfo(`[sync-engine] ${connector.id} done: added=${totalAdded} pages=${totalPages} reason=${stopReason}`);
495
- if (opts.onProgress) {
496
- const progress = {
497
- connectorId: connector.id,
498
- phase: 'forward',
499
- page: totalPages,
500
- fetched: 0,
501
- added: totalAdded,
502
- running: false,
503
- };
504
- yield* Effect.sync(() => opts.onProgress(progress));
505
- }
506
- const ret = {
507
- connectorId: connector.id,
508
- added: totalAdded,
509
- total: state.totalSynced,
510
- pages: totalPages,
511
- direction,
512
- stopReason,
513
- };
514
- if (lastError) {
515
- ret.error = { code: lastError.code, message: lastError.message };
516
- }
517
- return ret;
518
- });
519
- }
520
- syncEphemeralEffect(connector, state, opts, startedAt, cancel) {
521
- const db = this.db;
522
- const delayMs = opts.delayMs ?? DEFAULT_SCHEDULE.pageDelayMs;
523
- const maxMinutes = opts.maxMinutes ?? 0;
524
- const maxPages = opts.maxPages ?? 100;
525
- const sourceId = getSourceId(db);
526
- const deadline = maxMinutes > 0 ? startedAt + maxMinutes * 60_000 : Number.POSITIVE_INFINITY;
527
- return Effect.gen(function* () {
528
- const signal = yield* cancelDeferredToSignal(cancel);
529
- yield* Effect.sync(() => db.transaction(() => deleteConnectorItems(db, connector.id))());
530
- let cursor = null;
531
- let totalAdded = 0;
532
- let totalPages = 0;
533
- let stopReason = 'complete';
534
- while (true) {
535
- const now = yield* Clock.currentTimeMillis;
536
- if (now >= deadline) {
537
- stopReason = 'timeout';
538
- break;
539
- }
540
- if (totalPages >= maxPages) {
541
- stopReason = 'max_pages';
542
- break;
543
- }
544
- if (yield* Deferred.isDone(cancel)) {
545
- stopReason = 'cancelled';
546
- break;
547
- }
548
- const outcome = yield* Effect.either(Effect.tryPromise({
549
- try: () => connector.fetchPage({ cursor, sinceItemId: null, phase: 'forward', signal }),
550
- catch: SyncError.from,
551
- }).pipe(Effect.withSpan('sync.fetchPage', {
552
- attributes: {
553
- 'connector.id': connector.id,
554
- 'sync.phase': 'forward',
555
- 'sync.page': totalPages + 1,
556
- },
557
- })));
558
- if (outcome._tag === 'Left') {
559
- const err = outcome.left;
560
- yield* Effect.logError(`[sync-engine] ${connector.id} forward page ${totalPages + 1} error: ${err.message}`);
561
- state.totalSynced = totalAdded;
562
- state.lastForwardSyncAt = yield* nowIso;
563
- yield* Effect.sync(() => saveSyncState(db, state));
564
- return {
565
- connectorId: connector.id,
566
- added: totalAdded,
567
- total: totalAdded,
568
- pages: totalPages,
569
- direction: 'forward',
570
- stopReason: `error: ${err.code}`,
571
- error: { code: err.code, message: err.message },
572
- };
573
- }
574
- const result = outcome.right;
575
- totalPages++;
576
- const { newCount } = yield* Effect.sync(() => db.transaction(() => upsertItems(db, sourceId, connector.id, result.items))()).pipe(Effect.withSpan('sync.upsert', {
577
- attributes: { 'items.count': result.items.length },
578
- }));
579
- totalAdded += newCount;
580
- if (!result.nextCursor)
581
- break;
582
- cursor = result.nextCursor;
583
- const nowAfter = yield* Clock.currentTimeMillis;
584
- const remaining = deadline - nowAfter;
585
- const actualDelay = Math.max(0, Math.min(delayMs, remaining));
586
- if (actualDelay > 0) {
587
- yield* interruptibleSleep(actualDelay, cancel);
588
- }
589
- }
590
- state.totalSynced = totalAdded;
591
- state.lastForwardSyncAt = yield* nowIso;
592
- yield* Effect.sync(() => saveSyncState(db, state));
593
- return {
594
- connectorId: connector.id,
595
- added: totalAdded,
596
- total: totalAdded,
597
- pages: totalPages,
598
- direction: 'forward',
599
- stopReason,
600
- };
601
- });
602
- }
603
- }
604
- //# sourceMappingURL=sync-engine.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"sync-engine.js","sourceRoot":"","sources":["../../src/connectors/sync-engine.ts"],"names":[],"mappings":"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"}