@devrev/airsync-sdk 2.0.0-beta.6 → 2.0.0-beta.7

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/README.md +8 -12
  2. package/dist/attachments-streaming/attachments-streaming-pool.d.ts.map +1 -1
  3. package/dist/attachments-streaming/attachments-streaming-pool.js +8 -9
  4. package/dist/common/constants.d.ts +0 -7
  5. package/dist/common/constants.d.ts.map +1 -1
  6. package/dist/common/constants.js +1 -28
  7. package/dist/common/helpers.d.ts.map +1 -1
  8. package/dist/common/helpers.js +1 -1
  9. package/dist/http/errors.d.ts +8 -0
  10. package/dist/http/errors.d.ts.map +1 -0
  11. package/dist/http/errors.js +31 -0
  12. package/dist/index.d.ts +18 -13
  13. package/dist/index.d.ts.map +1 -1
  14. package/dist/index.js +14 -11
  15. package/dist/logger/logger.d.ts.map +1 -1
  16. package/dist/logger/logger.interfaces.d.ts +2 -2
  17. package/dist/logger/logger.interfaces.d.ts.map +1 -1
  18. package/dist/mappers/mappers.d.ts +9 -3
  19. package/dist/mappers/mappers.d.ts.map +1 -1
  20. package/dist/mappers/mappers.interfaces.d.ts +0 -2
  21. package/dist/mappers/mappers.interfaces.d.ts.map +1 -1
  22. package/dist/mappers/mappers.js +33 -13
  23. package/dist/multithreading/adapters/base-adapter.d.ts +16 -35
  24. package/dist/multithreading/adapters/base-adapter.d.ts.map +1 -1
  25. package/dist/multithreading/adapters/base-adapter.js +89 -23
  26. package/dist/multithreading/adapters/extraction-adapter.d.ts +24 -20
  27. package/dist/multithreading/adapters/extraction-adapter.d.ts.map +1 -1
  28. package/dist/multithreading/adapters/extraction-adapter.js +175 -122
  29. package/dist/multithreading/adapters/loading-adapter.d.ts +13 -23
  30. package/dist/multithreading/adapters/loading-adapter.d.ts.map +1 -1
  31. package/dist/multithreading/adapters/loading-adapter.js +176 -301
  32. package/dist/multithreading/emit.d.ts.map +1 -1
  33. package/dist/multithreading/process-task.d.ts.map +1 -1
  34. package/dist/multithreading/process-task.js +24 -6
  35. package/dist/multithreading/spawn/spawn.d.ts +6 -1
  36. package/dist/multithreading/spawn/spawn.d.ts.map +1 -1
  37. package/dist/multithreading/spawn/spawn.helpers.d.ts.map +1 -1
  38. package/dist/multithreading/spawn/spawn.helpers.js +17 -52
  39. package/dist/multithreading/spawn/spawn.js +30 -26
  40. package/dist/multithreading/worker.js +15 -1
  41. package/dist/repo/repo.d.ts +4 -5
  42. package/dist/repo/repo.d.ts.map +1 -1
  43. package/dist/repo/repo.interfaces.d.ts +5 -4
  44. package/dist/repo/repo.interfaces.d.ts.map +1 -1
  45. package/dist/repo/repo.js +13 -15
  46. package/dist/state/base-state.d.ts +10 -5
  47. package/dist/state/base-state.d.ts.map +1 -1
  48. package/dist/state/base-state.js +39 -36
  49. package/dist/state/extraction-state.d.ts.map +1 -1
  50. package/dist/state/extraction-state.js +39 -4
  51. package/dist/state/state.interfaces.d.ts +13 -7
  52. package/dist/state/state.interfaces.d.ts.map +1 -1
  53. package/dist/state/state.interfaces.js +6 -8
  54. package/dist/state/time-value-resolver.d.ts.map +1 -1
  55. package/dist/state/time-value-resolver.js +3 -2
  56. package/dist/testing/mock-event.d.ts.map +1 -1
  57. package/dist/testing/mock-event.js +0 -8
  58. package/dist/testing/mock-server.d.ts +2 -0
  59. package/dist/testing/mock-server.d.ts.map +1 -1
  60. package/dist/testing/mock-server.interfaces.d.ts +6 -0
  61. package/dist/testing/mock-server.interfaces.d.ts.map +1 -1
  62. package/dist/testing/mock-server.js +37 -6
  63. package/dist/testing/test-adapters.d.ts +22 -0
  64. package/dist/testing/test-adapters.d.ts.map +1 -0
  65. package/dist/testing/test-adapters.js +32 -0
  66. package/dist/types/common.d.ts +4 -1
  67. package/dist/types/common.d.ts.map +1 -1
  68. package/dist/types/common.js +1 -1
  69. package/dist/types/errors.d.ts +13 -7
  70. package/dist/types/errors.d.ts.map +1 -1
  71. package/dist/types/errors.js +24 -0
  72. package/dist/types/extraction.d.ts +60 -44
  73. package/dist/types/extraction.d.ts.map +1 -1
  74. package/dist/types/extraction.js +10 -1
  75. package/dist/types/loading.d.ts +11 -30
  76. package/dist/types/loading.d.ts.map +1 -1
  77. package/dist/types/workers.d.ts +27 -23
  78. package/dist/types/workers.d.ts.map +1 -1
  79. package/dist/uploader/uploader.d.ts +1 -2
  80. package/dist/uploader/uploader.d.ts.map +1 -1
  81. package/dist/uploader/uploader.helpers.d.ts +3 -0
  82. package/dist/uploader/uploader.helpers.d.ts.map +1 -1
  83. package/dist/uploader/uploader.helpers.js +16 -0
  84. package/dist/uploader/uploader.interfaces.d.ts +4 -29
  85. package/dist/uploader/uploader.interfaces.d.ts.map +1 -1
  86. package/dist/uploader/uploader.js +4 -23
  87. package/docs/MIGRATION.md +651 -0
  88. package/package.json +24 -10
  89. package/MIGRATION.md +0 -1028
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.ts"],"names":[],"mappings":"AAYA,OAAO,EAEL,qBAAqB,EACrB,cAAc,EAGf,MAAM,qBAAqB,CAAC;AA0C7B;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,OAAO,EACP,cAAc,GACf,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,mBAAmB,CAAqB;gBACpC,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IA0GjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAoCjC"}
1
+ {"version":3,"file":"spawn.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.ts"],"names":[],"mappings":"AASA,OAAO,EAGL,qBAAqB,EACrB,cAAc,EAGf,MAAM,qBAAqB,CAAC;AAe7B;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,oBAAc,GAAG,OAAO,CAY7D;AAoCD;;;;GAIG;AACH,wBAAsB,KAAK,CAAC,cAAc,EAAE,EAC1C,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,OAAO,EAAE,YAAY,EACrB,cAAc,EACd,mBAAmB,GACpB,EAAE,qBAAqB,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CA0DvD;AAED,qBAAa,KAAK;IAChB,OAAO,CAAC,KAAK,CAAe;IAC5B,OAAO,CAAC,cAAc,CAAU;IAChC,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,oBAAoB,CAAkC;IAC9D,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,gBAAgB,CAA4C;IACpE,OAAO,CAAC,wBAAwB,CAA6C;IAC7E,OAAO,CAAC,OAAO,CAA4C;IAC3D,OAAO,CAAC,eAAe,CAAU;IACjC,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,mBAAmB,CAAqB;gBACpC,EACV,KAAK,EACL,MAAM,EACN,OAAO,EACP,OAAO,EACP,eAAe,GAChB,EAAE,cAAc;IA0GjB,OAAO,CAAC,aAAa;YAYP,kBAAkB;CAoCjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"spawn.helpers.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,UAAU,GACjB;IACD,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;IAChD,OAAO,EAAE,OAAO,CAAC;CAClB,CAiCA;AAuGD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG;IAC9D,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;CACjD,CAiEA;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS;eAwBhB,kBAAkB,GAAG,eAAe;EAG5E"}
1
+ {"version":3,"file":"spawn.helpers.d.ts","sourceRoot":"","sources":["../../../src/multithreading/spawn/spawn.helpers.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AACvE,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEjD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,EAAE,SAAS,EACpB,MAAM,EAAE,UAAU,GACjB;IACD,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;IAChD,OAAO,EAAE,OAAO,CAAC;CAClB,CAiCA;AAgHD,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,SAAS,GAAG;IAC9D,SAAS,EAAE,kBAAkB,GAAG,eAAe,CAAC;CACjD,CAEA;AAED,8EAA8E;AAC9E,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,SAAS;eA+BhB,kBAAkB,GAAG,eAAe;EAG5E"}
@@ -50,9 +50,18 @@ const EVENT_PHASE_MAP = {
50
50
  error: extraction_1.ExtractorEventType.ExternalSyncUnitExtractionError,
51
51
  },
52
52
  [extraction_1.EventType.StartExtractingMetadata]: {
53
- resumable: false,
53
+ resumable: true,
54
+ done: extraction_1.ExtractorEventType.MetadataExtractionDone,
55
+ error: extraction_1.ExtractorEventType.MetadataExtractionError,
56
+ progress: extraction_1.ExtractorEventType.MetadataExtractionProgress,
57
+ delayed: extraction_1.ExtractorEventType.MetadataExtractionDelayed,
58
+ },
59
+ [extraction_1.EventType.ContinueExtractingMetadata]: {
60
+ resumable: true,
54
61
  done: extraction_1.ExtractorEventType.MetadataExtractionDone,
55
62
  error: extraction_1.ExtractorEventType.MetadataExtractionError,
63
+ progress: extraction_1.ExtractorEventType.MetadataExtractionProgress,
64
+ delayed: extraction_1.ExtractorEventType.MetadataExtractionDelayed,
56
65
  },
57
66
  [extraction_1.EventType.StartExtractingData]: {
58
67
  resumable: true,
@@ -132,62 +141,18 @@ const EVENT_PHASE_MAP = {
132
141
  },
133
142
  };
134
143
  function getTimeoutErrorEventType(eventType) {
144
+ return { eventType: getEventTypeForResult(eventType, 'error').eventType };
145
+ }
146
+ /** Event type to emit when no worker script exists for the incoming event. */
147
+ function getNoScriptEventType(eventType) {
135
148
  switch (eventType) {
149
+ // A missing metadata worker is a misconfigured connector, so report it as a
150
+ // phase error rather than an unknown event type.
136
151
  case extraction_1.EventType.StartExtractingMetadata:
152
+ case extraction_1.EventType.ContinueExtractingMetadata:
137
153
  return {
138
154
  eventType: extraction_1.ExtractorEventType.MetadataExtractionError,
139
155
  };
140
- case extraction_1.EventType.StartExtractingData:
141
- case extraction_1.EventType.ContinueExtractingData:
142
- return {
143
- eventType: extraction_1.ExtractorEventType.DataExtractionError,
144
- };
145
- case extraction_1.EventType.StartDeletingExtractorState:
146
- return {
147
- eventType: extraction_1.ExtractorEventType.ExtractorStateDeletionError,
148
- };
149
- case extraction_1.EventType.StartExtractingAttachments:
150
- case extraction_1.EventType.ContinueExtractingAttachments:
151
- return {
152
- eventType: extraction_1.ExtractorEventType.AttachmentExtractionError,
153
- };
154
- case extraction_1.EventType.StartDeletingExtractorAttachmentsState:
155
- return {
156
- eventType: extraction_1.ExtractorEventType.ExtractorAttachmentsStateDeletionError,
157
- };
158
- case extraction_1.EventType.StartExtractingExternalSyncUnits:
159
- return {
160
- eventType: extraction_1.ExtractorEventType.ExternalSyncUnitExtractionError,
161
- };
162
- case extraction_1.EventType.StartLoadingData:
163
- case extraction_1.EventType.ContinueLoadingData:
164
- return {
165
- eventType: loading_1.LoaderEventType.DataLoadingError,
166
- };
167
- case extraction_1.EventType.StartDeletingLoaderState:
168
- return {
169
- eventType: loading_1.LoaderEventType.LoaderStateDeletionError,
170
- };
171
- case extraction_1.EventType.StartLoadingAttachments:
172
- case extraction_1.EventType.ContinueLoadingAttachments:
173
- return {
174
- eventType: loading_1.LoaderEventType.AttachmentLoadingError,
175
- };
176
- case extraction_1.EventType.StartDeletingLoaderAttachmentState:
177
- return {
178
- eventType: loading_1.LoaderEventType.LoaderAttachmentStateDeletionError,
179
- };
180
- default:
181
- console.error('Event type not recognized in getTimeoutErrorEventType function: ' +
182
- eventType);
183
- return {
184
- eventType: constants_1.UNKNOWN_EVENT_TYPE,
185
- };
186
- }
187
- }
188
- /** Event type to emit when no worker script exists for the incoming event. */
189
- function getNoScriptEventType(eventType) {
190
- switch (eventType) {
191
156
  case extraction_1.EventType.StartDeletingExtractorState:
192
157
  return {
193
158
  eventType: extraction_1.ExtractorEventType.ExtractorStateDeletionDone,
@@ -1,20 +1,36 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.Spawn = void 0;
4
+ exports.isLocalDevelopment = isLocalDevelopment;
7
5
  exports.spawn = spawn;
8
- const yargs_1 = __importDefault(require("yargs"));
9
- const helpers_1 = require("yargs/helpers");
10
6
  const constants_1 = require("../../common/constants");
11
- const helpers_2 = require("../../common/helpers");
7
+ const helpers_1 = require("../../common/helpers");
12
8
  const logger_1 = require("../../logger/logger");
13
9
  const extraction_1 = require("../../types/extraction");
14
10
  const workers_1 = require("../../types/workers");
15
11
  const create_worker_1 = require("../create-worker");
16
12
  const emit_1 = require("../emit");
17
13
  const spawn_helpers_1 = require("./spawn.helpers");
14
+ const LAMBDA_ENV_MARKERS = [
15
+ 'AWS_LAMBDA_FUNCTION_NAME',
16
+ 'AWS_EXECUTION_ENV',
17
+ 'LAMBDA_TASK_ROOT',
18
+ ];
19
+ /**
20
+ * Local mode is opt-in through AIRSYNC_LOCAL_DEVELOPMENT only, and refused on
21
+ * Lambda so a stray flag can never change production behavior.
22
+ */
23
+ function isLocalDevelopment(env = process.env) {
24
+ if (env.AIRSYNC_LOCAL_DEVELOPMENT !== '1') {
25
+ return false;
26
+ }
27
+ const marker = LAMBDA_ENV_MARKERS.find((name) => env[name]);
28
+ if (marker) {
29
+ console.warn(`Ignoring AIRSYNC_LOCAL_DEVELOPMENT because ${marker} is set (running on Lambda).`);
30
+ return false;
31
+ }
32
+ return true;
33
+ }
18
34
  function getWorkerPath({ event, workerBasePath, }) {
19
35
  let path = null;
20
36
  switch (event.payload.event_type) {
@@ -22,6 +38,7 @@ function getWorkerPath({ event, workerBasePath, }) {
22
38
  path = '/workers/external-sync-units-extraction';
23
39
  break;
24
40
  case extraction_1.EventType.StartExtractingMetadata:
41
+ case extraction_1.EventType.ContinueExtractingMetadata:
25
42
  path = '/workers/metadata-extraction';
26
43
  break;
27
44
  case extraction_1.EventType.StartExtractingData:
@@ -48,31 +65,18 @@ function getWorkerPath({ event, workerBasePath, }) {
48
65
  * events, graceful exit, lambda timeout handling). Resolves when the worker
49
66
  * run is fully finished.
50
67
  */
51
- async function spawn({ event, initialState, initialDomainMapping, options, baseWorkerPath, }) {
52
- const argv = await (0, yargs_1.default)((0, helpers_1.hideBin)(process.argv)).argv;
53
- if (argv._.includes('local') || argv.local) {
54
- options = Object.assign(Object.assign({}, (options || {})), { isLocalDevelopment: true });
55
- }
68
+ async function spawn({ event, initialState, initialDomainMapping, options: spawnOptions, baseWorkerPath, workerPathOverrides, }) {
69
+ const options = Object.assign(Object.assign({}, spawnOptions), { isLocalDevelopment: isLocalDevelopment() });
56
70
  const originalConsole = console;
57
71
  // eslint-disable-next-line no-global-assign
58
72
  console = new logger_1.Logger({ event, options });
59
73
  if (options === null || options === void 0 ? void 0 : options.isLocalDevelopment) {
60
74
  console.log('Snap-in is running in local development mode.');
61
75
  }
62
- let script = null;
63
- if (baseWorkerPath != null &&
64
- (options === null || options === void 0 ? void 0 : options.workerPathOverrides) != null &&
65
- options.workerPathOverrides[event.payload.event_type] != null) {
66
- script =
67
- baseWorkerPath +
68
- options.workerPathOverrides[event.payload.event_type];
69
- }
70
- else {
71
- script = getWorkerPath({
72
- event,
73
- workerBasePath: baseWorkerPath !== null && baseWorkerPath !== void 0 ? baseWorkerPath : __dirname,
74
- });
75
- }
76
+ const override = workerPathOverrides === null || workerPathOverrides === void 0 ? void 0 : workerPathOverrides[event.payload.event_type];
77
+ const script = override != null
78
+ ? baseWorkerPath + override
79
+ : getWorkerPath({ event, workerBasePath: baseWorkerPath });
76
80
  if (script) {
77
81
  try {
78
82
  const worker = await (0, create_worker_1.createWorker)({
@@ -184,7 +188,7 @@ class Spawn {
184
188
  });
185
189
  this.memoryMonitoringInterval = setInterval(() => {
186
190
  try {
187
- const memoryInfo = (0, helpers_2.getMemoryUsage)();
191
+ const memoryInfo = (0, helpers_1.getMemoryUsage)();
188
192
  if (memoryInfo) {
189
193
  console.info(memoryInfo.formattedMessage);
190
194
  }
@@ -1,6 +1,20 @@
1
1
  "use strict";
2
2
  const { workerData } = require('node:worker_threads');
3
- require('ts-node').register();
3
+ let resolvedWorkerPath;
4
+ try {
5
+ resolvedWorkerPath = require.resolve(workerData.workerPath);
6
+ }
7
+ catch (_a) {
8
+ // Unresolvable without a TypeScript loader, so the worker is a .ts file.
9
+ }
10
+ if (!resolvedWorkerPath || resolvedWorkerPath.endsWith('.ts')) {
11
+ try {
12
+ require('ts-node').register();
13
+ }
14
+ catch (error) {
15
+ throw new Error(`Worker ${workerData.workerPath} needs ts-node to run TypeScript. Install ts-node or point the worker at compiled JavaScript. ${error.message}`);
16
+ }
17
+ }
4
18
  const { Logger } = require('../logger/logger');
5
19
  console = new Logger({ event: workerData.event, options: workerData.options });
6
20
  require(workerData.workerPath);
@@ -1,7 +1,6 @@
1
1
  import { Item } from '../repo/repo.interfaces';
2
- import { ErrorRecord } from '../types/common';
3
2
  import { Artifact } from '../uploader/uploader.interfaces';
4
- import { NormalizedAttachment, NormalizedItem, RepoFactoryInterface } from './repo.interfaces';
3
+ import { NormalizedAttachment, NormalizedItem } from './repo.interfaces';
5
4
  export declare class Repo {
6
5
  readonly itemType: string;
7
6
  private items;
@@ -20,9 +19,9 @@ export declare class Repo {
20
19
  newest?: number;
21
20
  };
22
21
  };
23
- constructor({ event, itemType, normalize, onUpload, options, }: RepoFactoryInterface);
24
22
  getItems(): (NormalizedItem | NormalizedAttachment | Item)[];
25
- upload(batch?: (NormalizedItem | NormalizedAttachment | Item)[]): Promise<void | ErrorRecord>;
26
- push(items: Item[]): Promise<boolean>;
23
+ upload(batch?: (NormalizedItem | NormalizedAttachment | Item)[]): Promise<void>;
24
+ /** Buffers items and uploads every full batch. Throws if an upload fails. */
25
+ push(items: Item[]): Promise<void>;
27
26
  }
28
27
  //# sourceMappingURL=repo.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/repo/repo.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAG3D,OAAO,EACL,oBAAoB,EACpB,cAAc,EACd,oBAAoB,EACrB,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,IAAI;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAC,CAAwD;IAC1E,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAuB;IAChC,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,UAAU,EAAE;QACjB,YAAY,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnD,YAAY,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACpD,CAGC;gBAEU,EACV,KAAK,EACL,QAAQ,EACR,SAAS,EACT,QAAQ,EACR,OAAO,GACR,EAAE,oBAAoB;IAUvB,QAAQ,IAAI,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE;IAItD,MAAM,CACV,KAAK,CAAC,EAAE,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,GAAG,WAAW,CAAC;IAsDxB,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,OAAO,CAAC;CAkC5C"}
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../../src/repo/repo.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AAG/C,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAG3D,OAAO,EACL,oBAAoB,EACpB,cAAc,EAEf,MAAM,mBAAmB,CAAC;AAE3B,qBAAa,IAAI;IACf,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,SAAS,CAAC,CAAwD;IAC1E,OAAO,CAAC,QAAQ,CAAW;IAC3B,OAAO,CAAC,QAAQ,CAA+B;IAC/C,OAAO,CAAC,OAAO,CAAC,CAAiB;IAC1B,iBAAiB,EAAE,QAAQ,EAAE,CAAC;IAC9B,UAAU,EAAE;QACjB,YAAY,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;QACnD,YAAY,EAAE;YAAE,MAAM,CAAC,EAAE,MAAM,CAAC;YAAC,MAAM,CAAC,EAAE,MAAM,CAAA;SAAE,CAAC;KACpD,CAGC;IAoBF,QAAQ,IAAI,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE;IAItD,MAAM,CACV,KAAK,CAAC,EAAE,CAAC,cAAc,GAAG,oBAAoB,GAAG,IAAI,CAAC,EAAE,GACvD,OAAO,CAAC,IAAI,CAAC;IA2DhB,6EAA6E;IACvE,IAAI,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CA6BzC"}
@@ -1,18 +1,19 @@
1
1
  import { AirSyncEvent } from '../types/extraction';
2
- import { WorkerAdapterOptions } from '../types/workers';
2
+ import { RepoOptions, RuntimeOptions } from '../types/workers';
3
3
  import { Artifact } from '../uploader/uploader.interfaces';
4
4
  /** Stores and uploads extracted data. */
5
5
  export interface RepoInterface {
6
6
  itemType: string;
7
7
  normalize?: (record: object) => NormalizedItem | NormalizedAttachment;
8
- overridenOptions?: WorkerAdapterOptions;
8
+ overriddenOptions?: RepoOptions;
9
9
  }
10
10
  export interface RepoFactoryInterface {
11
11
  event: AirSyncEvent;
12
12
  itemType: string;
13
13
  normalize?: (record: object) => NormalizedItem | NormalizedAttachment;
14
14
  onUpload: (artifact: Artifact) => void;
15
- options?: WorkerAdapterOptions;
15
+ options?: RuntimeOptions;
16
+ skipConfirmation?: boolean;
16
17
  }
17
18
  export interface NormalizedItem {
18
19
  id: string;
@@ -30,7 +31,7 @@ export interface NormalizedAttachment {
30
31
  content_type?: string;
31
32
  created_date?: string;
32
33
  modified_date?: string;
33
- grand_parent_id?: number | string;
34
+ grand_parent_id?: string;
34
35
  }
35
36
  export type Item = Record<string, any>;
36
37
  //# sourceMappingURL=repo.interfaces.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"repo.interfaces.d.ts","sourceRoot":"","sources":["../../src/repo/repo.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,oBAAoB,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3D,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,gBAAgB,CAAC,EAAE,oBAAoB,CAAC;CACzC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,oBAAoB,CAAC;CAChC;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IAGvB,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACnC;AAGD,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC"}
1
+ {"version":3,"file":"repo.interfaces.d.ts","sourceRoot":"","sources":["../../src/repo/repo.interfaces.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAC/D,OAAO,EAAE,QAAQ,EAAE,MAAM,iCAAiC,CAAC;AAE3D,yCAAyC;AACzC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,iBAAiB,CAAC,EAAE,WAAW,CAAC;CACjC;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,YAAY,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,cAAc,GAAG,oBAAoB,CAAC;IACtE,QAAQ,EAAE,CAAC,QAAQ,EAAE,QAAQ,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,cAAc,CAAC;IACzB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAGD,MAAM,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC"}
package/dist/repo/repo.js CHANGED
@@ -5,7 +5,8 @@ const constants_1 = require("../common/constants");
5
5
  const uploader_1 = require("../uploader/uploader");
6
6
  const repo_helpers_1 = require("./repo.helpers");
7
7
  class Repo {
8
- constructor({ event, itemType, normalize, onUpload, options, }) {
8
+ /** @internal */
9
+ constructor({ event, itemType, normalize, onUpload, options, skipConfirmation, }) {
9
10
  this.dateRanges = {
10
11
  creationDate: {},
11
12
  modifiedDate: {},
@@ -14,7 +15,7 @@ class Repo {
14
15
  this.itemType = itemType;
15
16
  this.normalize = normalize;
16
17
  this.onUpload = onUpload;
17
- this.uploader = new uploader_1.Uploader({ event, options });
18
+ this.uploader = new uploader_1.Uploader({ event, options, skipConfirmation });
18
19
  this.options = options;
19
20
  this.uploadedArtifacts = [];
20
21
  }
@@ -22,6 +23,7 @@ class Repo {
22
23
  return this.items;
23
24
  }
24
25
  async upload(batch) {
26
+ var _a;
25
27
  const itemsToUpload = batch || this.items;
26
28
  if (itemsToUpload.length > 0) {
27
29
  for (const item of itemsToUpload) {
@@ -43,12 +45,11 @@ class Repo {
43
45
  console.log(`Uploading ${itemsToUpload.length} items of type ${this.itemType}. `);
44
46
  const { artifact, error } = await this.uploader.upload(this.itemType, itemsToUpload);
45
47
  if (error || !artifact) {
46
- console.error('Error while uploading batch', error);
47
- return error;
48
+ console.error(`Error while uploading batch of ${itemsToUpload.length} items of type ${this.itemType}.`, error);
49
+ throw new Error((_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : `Upload failed for item type "${this.itemType}" without artifact.`);
48
50
  }
49
51
  this.onUpload(artifact);
50
52
  this.uploadedArtifacts.push(artifact);
51
- // An explicit batch was already spliced out of this.items by the caller
52
53
  if (!batch) {
53
54
  this.items = [];
54
55
  }
@@ -58,12 +59,13 @@ class Repo {
58
59
  console.log(`No items to upload for type ${this.itemType}. Skipping upload.`);
59
60
  }
60
61
  }
62
+ /** Buffers items and uploads every full batch. Throws if an upload fails. */
61
63
  async push(items) {
62
64
  var _a;
63
65
  let recordsToPush;
64
66
  if (!items || items.length === 0) {
65
67
  console.log(`No items to push for type ${this.itemType}. Skipping push.`);
66
- return true;
68
+ return;
67
69
  }
68
70
  if (this.normalize &&
69
71
  this.itemType != constants_1.AirSyncDefaultItemTypes.EXTERNAL_DOMAIN_METADATA &&
@@ -76,16 +78,12 @@ class Repo {
76
78
  this.items.push(...recordsToPush);
77
79
  const batchSize = ((_a = this.options) === null || _a === void 0 ? void 0 : _a.batchSize) || constants_1.ARTIFACT_BATCH_SIZE;
78
80
  while (this.items.length >= batchSize) {
79
- const batch = this.items.splice(0, batchSize);
80
- try {
81
- await this.upload(batch);
82
- }
83
- catch (error) {
84
- console.error('Error while uploading batch', error);
85
- return false;
86
- }
81
+ // Items leave the repo only after their batch uploaded, so a failed
82
+ // batch is still there for the next flush.
83
+ const batch = this.items.slice(0, batchSize);
84
+ await this.upload(batch);
85
+ this.items.splice(0, batchSize);
87
86
  }
88
- return true;
89
87
  }
90
88
  }
91
89
  exports.Repo = Repo;
@@ -4,7 +4,7 @@ import { ExtractionScope } from '../types/workers';
4
4
  import { SdkState, StateInterface } from './state.interfaces';
5
5
  /**
6
6
  * State lifecycle shared by all sync modes: connector/SDK state separation,
7
- * fetch/init/post, the v1->v2 migration shim, and the snap-in-version-gated
7
+ * fetch/init/post, the v1 to v2 migration shim, and the snap-in-version-gated
8
8
  * initial domain mapping install. Subclasses seed the SDK-owned state.
9
9
  */
10
10
  export declare abstract class BaseState<ConnectorState> {
@@ -39,12 +39,17 @@ export declare abstract class BaseState<ConnectorState> {
39
39
  init(initialState: ConnectorState): Promise<void>;
40
40
  /**
41
41
  * Normalizes fetched state into the `{ connectorState, sdkState }` envelope.
42
- * A flat v1 blob is split by `V1_SDK_STATE_KEYS`; an envelope with only one
43
- * side present fails loud.
42
+ * Versioned envelopes are read by `stateVersion`; unversioned ones (2.0.0
43
+ * betas) by their keys; anything else is a flat v1 blob split by
44
+ * `V1_SDK_STATE_KEYS`.
44
45
  */
45
46
  private normalizeFetchedState;
46
- /** Posts the v2 `{ connectorState, sdkState }` envelope to the API. */
47
- postState(state?: ConnectorState): Promise<void>;
47
+ private readEnvelope;
48
+ /**
49
+ * Posts the v2 envelope (connector and SDK state as they are now) to the
50
+ * API. Throws on failure so a caller can stop before a risky external write.
51
+ */
52
+ postState(): Promise<void>;
48
53
  fetchState(): Promise<{
49
54
  state: string;
50
55
  objects?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"base-state.d.ts","sourceRoot":"","sources":["../../src/state/base-state.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAEL,QAAQ,EACR,cAAc,EAEf,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,8BAAsB,SAAS,CAAC,cAAc;IAC5C,SAAS,CAAC,eAAe,EAAE,cAAc,CAAC;IAC1C,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC9B,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAM;IACjD,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;gBAGxB,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,EACvD,eAAe,EAAE,QAAQ;IAY3B,2EAA2E;IAC3E,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,cAAc,EAE9B;IAED,uEAAuE;IACvE,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAE3B;IAED,IAAI,eAAe,IAAI,eAAe,CAErC;IAED;;;;OAIG;IACG,mCAAmC,CACvC,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,OAAO,CAAC,IAAI,CAAC;IAwChB;;;;OAIG;IACG,IAAI,CAAC,YAAY,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAkDvD;;;;OAIG;IACH,OAAO,CAAC,qBAAqB;IAyC7B,uEAAuE;IACjE,SAAS,CAAC,KAAK,CAAC,EAAE,cAAc;IA4DhC,UAAU,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAqBjE"}
1
+ {"version":3,"file":"base-state.d.ts","sourceRoot":"","sources":["../../src/state/base-state.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAEnD,OAAO,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAEL,QAAQ,EAER,cAAc,EAEf,MAAM,oBAAoB,CAAC;AAE5B;;;;GAIG;AACH,8BAAsB,SAAS,CAAC,cAAc;IAC5C,SAAS,CAAC,eAAe,EAAE,cAAc,CAAC;IAC1C,SAAS,CAAC,SAAS,EAAE,QAAQ,CAAC;IAC9B,SAAS,CAAC,gBAAgB,EAAE,eAAe,CAAM;IACjD,SAAS,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC;IAC7C,SAAS,CAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IACvC,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,UAAU,CAAS;IAC3B,OAAO,CAAC,SAAS,CAAS;gBAGxB,EAAE,KAAK,EAAE,YAAY,EAAE,EAAE,cAAc,CAAC,cAAc,CAAC,EACvD,eAAe,EAAE,QAAQ;IAY3B,2EAA2E;IAC3E,IAAI,KAAK,IAAI,cAAc,CAE1B;IAED,IAAI,KAAK,CAAC,KAAK,EAAE,cAAc,EAE9B;IAED,uEAAuE;IACvE,IAAI,QAAQ,IAAI,QAAQ,CAEvB;IAED,IAAI,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAE3B;IAED,IAAI,eAAe,IAAI,eAAe,CAErC;IAED;;;;OAIG;IACG,mCAAmC,CACvC,oBAAoB,CAAC,EAAE,oBAAoB,GAC1C,OAAO,CAAC,IAAI,CAAC;IAwChB;;;;OAIG;IACG,IAAI,CAAC,YAAY,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAuDvD;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IA2C7B,OAAO,CAAC,YAAY;IAepB;;;OAGG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IA0C1B,UAAU,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAqBjE"}
@@ -13,7 +13,7 @@ const install_initial_domain_mapping_1 = require("./install-initial-domain-mappi
13
13
  const state_interfaces_1 = require("./state.interfaces");
14
14
  /**
15
15
  * State lifecycle shared by all sync modes: connector/SDK state separation,
16
- * fetch/init/post, the v1->v2 migration shim, and the snap-in-version-gated
16
+ * fetch/init/post, the v1 to v2 migration shim, and the snap-in-version-gated
17
17
  * initial domain mapping install. Subclasses seed the SDK-owned state.
18
18
  */
19
19
  class BaseState {
@@ -115,14 +115,17 @@ class BaseState {
115
115
  }
116
116
  }
117
117
  catch (error) {
118
- if (axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404) {
118
+ try {
119
+ if (!(axios_1.default.isAxiosError(error) && ((_a = error.response) === null || _a === void 0 ? void 0 : _a.status) === 404)) {
120
+ throw error;
121
+ }
119
122
  console.log('State not found. Initializing state with initial state.');
120
123
  this.state = initialState;
121
124
  this.sdkState = Object.assign({}, this.initialSdkState);
122
125
  await this.postState();
123
126
  }
124
- else {
125
- const errorMessage = `Failed to init state. ${(0, logger_1.serializeError)(error)}`;
127
+ catch (initError) {
128
+ const errorMessage = `Failed to init state. ${(0, logger_1.serializeError)(initError)}`;
126
129
  console.error(errorMessage);
127
130
  node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.postMessage({
128
131
  subject: workers_1.WorkerMessageSubject.WorkerMessageFailed,
@@ -134,24 +137,24 @@ class BaseState {
134
137
  }
135
138
  /**
136
139
  * Normalizes fetched state into the `{ connectorState, sdkState }` envelope.
137
- * A flat v1 blob is split by `V1_SDK_STATE_KEYS`; an envelope with only one
138
- * side present fails loud.
140
+ * Versioned envelopes are read by `stateVersion`; unversioned ones (2.0.0
141
+ * betas) by their keys; anything else is a flat v1 blob split by
142
+ * `V1_SDK_STATE_KEYS`.
139
143
  */
140
144
  normalizeFetchedState(parsed) {
141
145
  if (parsed === null || typeof parsed !== 'object') {
142
146
  throw new Error('Fetched state is not a JSON object.');
143
147
  }
144
148
  const record = parsed;
145
- const hasConnector = 'connectorState' in record;
146
- const hasSdk = 'sdkState' in record;
147
- if (hasConnector || hasSdk) {
148
- if (!hasConnector || !hasSdk) {
149
- throw new Error('Malformed state envelope: expected both "connectorState" and "sdkState".');
149
+ if (record.stateVersion !== undefined) {
150
+ if (record.stateVersion !== state_interfaces_1.STATE_VERSION) {
151
+ throw new Error(`Unsupported state version ${String(record.stateVersion)}; this SDK reads version ${state_interfaces_1.STATE_VERSION}.`);
150
152
  }
151
- return {
152
- connectorState: record.connectorState,
153
- sdkState: Object.assign(Object.assign({}, this.initialSdkState), record.sdkState),
154
- };
153
+ return this.readEnvelope(record);
154
+ }
155
+ // Envelopes written by 2.0.0 betas carry no version marker.
156
+ if ('connectorState' in record || 'sdkState' in record) {
157
+ return this.readEnvelope(record);
155
158
  }
156
159
  // Legacy flat v1 blob: split known SDK keys out of the connector state.
157
160
  const connectorState = {};
@@ -169,11 +172,23 @@ class BaseState {
169
172
  sdkState: Object.assign(Object.assign({}, this.initialSdkState), sdkState),
170
173
  };
171
174
  }
172
- /** Posts the v2 `{ connectorState, sdkState }` envelope to the API. */
173
- async postState(state) {
175
+ readEnvelope(record) {
176
+ if (!('connectorState' in record) || !('sdkState' in record)) {
177
+ throw new Error('Malformed state envelope: expected both "connectorState" and "sdkState".');
178
+ }
179
+ return {
180
+ connectorState: record.connectorState,
181
+ sdkState: Object.assign(Object.assign({}, this.initialSdkState), record.sdkState),
182
+ };
183
+ }
184
+ /**
185
+ * Posts the v2 envelope (connector and SDK state as they are now) to the
186
+ * API. Throws on failure so a caller can stop before a risky external write.
187
+ */
188
+ async postState() {
174
189
  const url = this.workerUrl + '.update';
175
- this.state = state || this.state;
176
190
  const envelope = {
191
+ stateVersion: state_interfaces_1.STATE_VERSION,
177
192
  connectorState: this.state,
178
193
  sdkState: this.sdkState,
179
194
  };
@@ -182,13 +197,7 @@ class BaseState {
182
197
  stringifiedState = JSON.stringify(envelope);
183
198
  }
184
199
  catch (error) {
185
- const errorMessage = `Failed to stringify state. ${(0, logger_1.serializeError)(error)}`;
186
- console.error(errorMessage);
187
- node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.postMessage({
188
- subject: workers_1.WorkerMessageSubject.WorkerMessageFailed,
189
- payload: { message: errorMessage },
190
- });
191
- process.exit(1);
200
+ throw new Error(`Failed to stringify state. ${(0, logger_1.serializeError)(error)}`);
192
201
  }
193
202
  try {
194
203
  await client_1.axiosClient.post(url, {
@@ -202,20 +211,14 @@ class BaseState {
202
211
  request_id: this.requestId,
203
212
  },
204
213
  });
205
- console.log('State updated successfully to', {
206
- connectorState: (0, logger_1.getPrintableState)(this.state),
207
- sdkState: (0, logger_1.getPrintableState)(this.sdkState),
208
- });
209
214
  }
210
215
  catch (error) {
211
- const errorMessage = `Failed to update the state. ${(0, logger_1.serializeError)(error)}`;
212
- console.error(errorMessage);
213
- node_worker_threads_1.parentPort === null || node_worker_threads_1.parentPort === void 0 ? void 0 : node_worker_threads_1.parentPort.postMessage({
214
- subject: workers_1.WorkerMessageSubject.WorkerMessageFailed,
215
- payload: { message: errorMessage },
216
- });
217
- process.exit(1);
216
+ throw new Error(`Failed to update the state. ${(0, logger_1.serializeError)(error)}`);
218
217
  }
218
+ console.log('State updated successfully to', {
219
+ connectorState: (0, logger_1.getPrintableState)(this.state),
220
+ sdkState: (0, logger_1.getPrintableState)(this.sdkState),
221
+ });
219
222
  }
220
223
  async fetchState() {
221
224
  var _a, _b;
@@ -1 +1 @@
1
- {"version":3,"file":"extraction-state.d.ts","sourceRoot":"","sources":["../../src/state/extraction-state.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAsB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGxE,sGAAsG;AACtG,qBAAa,eAAe,CAAC,cAAc,CAAE,SAAQ,SAAS,CAAC,cAAc,CAAC;gBAChE,MAAM,EAAE,cAAc,CAAC,cAAc,CAAC;IAIlD;;;;OAIG;IACH,uBAAuB,IAAI,IAAI;CA6EhC;AAED,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,EAC1D,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,OAAO,GACR,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAkB3E"}
1
+ {"version":3,"file":"extraction-state.d.ts","sourceRoot":"","sources":["../../src/state/extraction-state.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAsB,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAGxE,sGAAsG;AACtG,qBAAa,eAAe,CAAC,cAAc,CAAE,SAAQ,SAAS,CAAC,cAAc,CAAC;gBAChE,MAAM,EAAE,cAAc,CAAC,cAAc,CAAC;IAIlD;;;;OAIG;IACH,uBAAuB,IAAI,IAAI;CAyHhC;AAED,wBAAsB,qBAAqB,CAAC,cAAc,EAAE,EAC1D,KAAK,EACL,YAAY,EACZ,oBAAoB,EACpB,OAAO,GACR,EAAE,cAAc,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAkB3E"}
@@ -23,6 +23,17 @@ class ExtractionState extends base_state_1.BaseState {
23
23
  resolveExtractionWindow() {
24
24
  const sdkState = this.sdkState;
25
25
  const eventContext = this.event.payload.event_context;
26
+ const overrideExtractFrom = (value) => {
27
+ if (eventContext.extract_from !== undefined) {
28
+ eventContext.original_extract_from = eventContext.extract_from;
29
+ }
30
+ eventContext.extract_from = value;
31
+ };
32
+ if (this.event.payload.event_type === extraction_1.EventType.StartExtractingData &&
33
+ !sdkState.lastSyncStarted) {
34
+ sdkState.lastSyncStarted = new Date().toISOString();
35
+ console.log(`Setting lastSyncStarted to ${sdkState.lastSyncStarted}.`);
36
+ }
26
37
  if (this.event.payload.event_type === extraction_1.EventType.StartExtractingMetadata) {
27
38
  const timeFields = [
28
39
  {
@@ -41,7 +52,12 @@ class ExtractionState extends base_state_1.BaseState {
41
52
  if (timeValue && timeValue.type) {
42
53
  try {
43
54
  const resolved = (0, time_value_resolver_1.resolveTimeValue)(timeValue, sdkState);
44
- eventContext[target] = resolved;
55
+ if (target === 'extract_from') {
56
+ overrideExtractFrom(resolved);
57
+ }
58
+ else {
59
+ eventContext[target] = resolved;
60
+ }
45
61
  sdkState[pending] = resolved;
46
62
  console.log(`Resolved ${target} to ${resolved}. Stored in ${pending}.`);
47
63
  }
@@ -55,12 +71,31 @@ class ExtractionState extends base_state_1.BaseState {
55
71
  process.exit(1);
56
72
  }
57
73
  }
74
+ else if (target === 'extract_from') {
75
+ // Non-CPv2 platforms send no TimeValue: prefer the last successful
76
+ // sync start, else the extract_from the platform supplied directly.
77
+ const fallback = sdkState.lastSuccessfulSyncStarted || eventContext.extract_from;
78
+ if (fallback) {
79
+ if (sdkState.lastSuccessfulSyncStarted) {
80
+ overrideExtractFrom(fallback);
81
+ }
82
+ sdkState.pendingWorkersOldest = fallback;
83
+ console.log(`Using ${sdkState.lastSuccessfulSyncStarted
84
+ ? 'lastSuccessfulSyncStarted'
85
+ : 'platform-provided extract_from'} as extract_from: ${fallback}. Stored in pendingWorkersOldest.`);
86
+ }
87
+ }
58
88
  }
59
89
  }
60
90
  else {
61
- if (sdkState.pendingWorkersOldest) {
62
- eventContext.extract_from = sdkState.pendingWorkersOldest;
63
- console.log(`Reusing pendingWorkersOldest as extract_from: ${sdkState.pendingWorkersOldest}.`);
91
+ const pendingExtractFrom = sdkState.pendingWorkersOldest || sdkState.lastSuccessfulSyncStarted;
92
+ if (pendingExtractFrom) {
93
+ if (eventContext.extract_from !== pendingExtractFrom) {
94
+ overrideExtractFrom(pendingExtractFrom);
95
+ }
96
+ console.log(`Using ${sdkState.pendingWorkersOldest
97
+ ? 'pendingWorkersOldest'
98
+ : 'lastSuccessfulSyncStarted'} as extract_from: ${pendingExtractFrom}.`);
64
99
  }
65
100
  else {
66
101
  console.log('pendingWorkersOldest is not set in state. extract_from will not be populated for this invocation.');