@adcp/sdk 15.9.0 → 16.0.0-beta.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 (295) hide show
  1. package/bin/adcp-identity.js +74 -0
  2. package/bin/adcp.js +2 -0
  3. package/dist/lib/adapters/keyed-account-backend.d.mts +37 -0
  4. package/dist/lib/adapters/keyed-account-backend.d.ts +37 -0
  5. package/dist/lib/adapters/keyed-account-backend.js +121 -0
  6. package/dist/lib/adapters/keyed-account-backend.mjs +94 -0
  7. package/dist/lib/adapters/keyed-account-store.d.mts +28 -0
  8. package/dist/lib/adapters/keyed-account-store.d.ts +28 -0
  9. package/dist/lib/adapters/keyed-account-store.js +227 -0
  10. package/dist/lib/adapters/keyed-account-store.mjs +203 -0
  11. package/dist/lib/core/SingleAgentClient.d.mts +16 -2
  12. package/dist/lib/core/SingleAgentClient.d.ts +16 -2
  13. package/dist/lib/core/SingleAgentClient.js +259 -62
  14. package/dist/lib/core/SingleAgentClient.mjs +261 -57
  15. package/dist/lib/core/TaskExecutor.d.mts +6 -0
  16. package/dist/lib/core/TaskExecutor.d.ts +6 -0
  17. package/dist/lib/core/TaskExecutor.js +66 -5
  18. package/dist/lib/core/TaskExecutor.mjs +71 -5
  19. package/dist/lib/core/postgres-webhook-registration-store.js +32 -5
  20. package/dist/lib/core/postgres-webhook-registration-store.mjs +32 -5
  21. package/dist/lib/core/redis-webhook-registration-store.js +23 -1
  22. package/dist/lib/core/redis-webhook-registration-store.mjs +23 -1
  23. package/dist/lib/core/webhook-registration.d.mts +7 -1
  24. package/dist/lib/core/webhook-registration.d.ts +7 -1
  25. package/dist/lib/core/webhook-registration.js +24 -2
  26. package/dist/lib/core/webhook-registration.mjs +23 -2
  27. package/dist/lib/identity-3.3/index.d.mts +10 -0
  28. package/dist/lib/identity-3.3/index.d.ts +10 -0
  29. package/dist/lib/identity-3.3/index.js +75 -0
  30. package/dist/lib/identity-3.3/index.mjs +46 -0
  31. package/dist/lib/identity-3.3/lifecycle.d.mts +113 -0
  32. package/dist/lib/identity-3.3/lifecycle.d.ts +113 -0
  33. package/dist/lib/identity-3.3/lifecycle.js +267 -0
  34. package/dist/lib/identity-3.3/lifecycle.mjs +240 -0
  35. package/dist/lib/identity-3.3/revocation.d.mts +50 -0
  36. package/dist/lib/identity-3.3/revocation.d.ts +50 -0
  37. package/dist/lib/identity-3.3/revocation.js +238 -0
  38. package/dist/lib/identity-3.3/revocation.mjs +216 -0
  39. package/dist/lib/identity-3.3/schemas.draft.d.mts +2472 -0
  40. package/dist/lib/identity-3.3/schemas.draft.d.ts +2472 -0
  41. package/dist/lib/identity-3.3/schemas.draft.js +1448 -0
  42. package/dist/lib/identity-3.3/schemas.draft.mjs +1428 -0
  43. package/dist/lib/identity-3.3/server.d.mts +34 -0
  44. package/dist/lib/identity-3.3/server.d.ts +34 -0
  45. package/dist/lib/identity-3.3/server.js +219 -0
  46. package/dist/lib/identity-3.3/server.mjs +194 -0
  47. package/dist/lib/identity-3.3/store.d.mts +24 -0
  48. package/dist/lib/identity-3.3/store.d.ts +24 -0
  49. package/dist/lib/identity-3.3/store.js +191 -0
  50. package/dist/lib/identity-3.3/store.mjs +169 -0
  51. package/dist/lib/identity-3.3/trust.d.mts +94 -0
  52. package/dist/lib/identity-3.3/trust.d.ts +94 -0
  53. package/dist/lib/identity-3.3/trust.js +278 -0
  54. package/dist/lib/identity-3.3/trust.mjs +239 -0
  55. package/dist/lib/identity-3.3/types.d.mts +127 -0
  56. package/dist/lib/identity-3.3/types.d.ts +127 -0
  57. package/dist/lib/identity-3.3/types.js +16 -0
  58. package/dist/lib/identity-3.3/types.mjs +0 -0
  59. package/dist/lib/identity-3.3/validation.d.mts +2 -0
  60. package/dist/lib/identity-3.3/validation.d.ts +2 -0
  61. package/dist/lib/identity-3.3/validation.js +125 -0
  62. package/dist/lib/identity-3.3/validation.mjs +91 -0
  63. package/dist/lib/index.d.mts +1 -1
  64. package/dist/lib/index.d.ts +1 -1
  65. package/dist/lib/reporting/azure/index.d.mts +5 -0
  66. package/dist/lib/reporting/azure/index.d.ts +5 -0
  67. package/dist/lib/reporting/azure/index.js +26 -7
  68. package/dist/lib/reporting/azure/index.mjs +26 -7
  69. package/dist/lib/reporting/bigquery/index.d.mts +80 -25
  70. package/dist/lib/reporting/bigquery/index.d.ts +80 -25
  71. package/dist/lib/reporting/bigquery/index.js +184 -81
  72. package/dist/lib/reporting/bigquery/index.mjs +182 -80
  73. package/dist/lib/reporting/gcs/adapter.d.mts +8 -1
  74. package/dist/lib/reporting/gcs/adapter.d.ts +8 -1
  75. package/dist/lib/reporting/gcs/errors.d.mts +6 -0
  76. package/dist/lib/reporting/gcs/errors.d.ts +6 -0
  77. package/dist/lib/reporting/gcs/fence.d.mts +5 -0
  78. package/dist/lib/reporting/gcs/fence.d.ts +5 -0
  79. package/dist/lib/reporting/gcs/index.d.mts +9 -0
  80. package/dist/lib/reporting/gcs/index.d.ts +9 -0
  81. package/dist/lib/reporting/gcs/reader.d.mts +27 -3
  82. package/dist/lib/reporting/gcs/reader.d.ts +27 -3
  83. package/dist/lib/reporting/gcs/row-provider.d.mts +7 -0
  84. package/dist/lib/reporting/gcs/row-provider.d.ts +7 -0
  85. package/dist/lib/reporting/gcs/row-provider.js +34 -14
  86. package/dist/lib/reporting/gcs/row-provider.mjs +34 -14
  87. package/dist/lib/reporting/ledger/change-feed.d.mts +22 -1
  88. package/dist/lib/reporting/ledger/change-feed.d.ts +22 -1
  89. package/dist/lib/reporting/ledger/index.d.mts +11 -0
  90. package/dist/lib/reporting/ledger/index.d.ts +11 -0
  91. package/dist/lib/reporting/ledger/managed-postgres.d.mts +8 -0
  92. package/dist/lib/reporting/ledger/managed-postgres.d.ts +8 -0
  93. package/dist/lib/reporting/ledger/managed-router.d.mts +27 -2
  94. package/dist/lib/reporting/ledger/managed-router.d.ts +27 -2
  95. package/dist/lib/reporting/ledger/managed.d.mts +86 -6
  96. package/dist/lib/reporting/ledger/managed.d.ts +86 -6
  97. package/dist/lib/reporting/ledger/notification-activity.d.mts +65 -3
  98. package/dist/lib/reporting/ledger/notification-activity.d.ts +65 -3
  99. package/dist/lib/reporting/ledger/object-writes.d.mts +64 -5
  100. package/dist/lib/reporting/ledger/object-writes.d.ts +64 -5
  101. package/dist/lib/reporting/ledger/postgres.d.mts +43 -9
  102. package/dist/lib/reporting/ledger/postgres.d.ts +43 -9
  103. package/dist/lib/reporting/ledger/postgres.js +43 -27
  104. package/dist/lib/reporting/ledger/postgres.mjs +43 -27
  105. package/dist/lib/reporting/ledger/row-encoding.d.mts +92 -6
  106. package/dist/lib/reporting/ledger/row-encoding.d.ts +92 -6
  107. package/dist/lib/reporting/ledger/row-encoding.js +8 -4
  108. package/dist/lib/reporting/ledger/row-encoding.mjs +6 -3
  109. package/dist/lib/reporting/ledger/row-storage-errors.d.mts +11 -1
  110. package/dist/lib/reporting/ledger/row-storage-errors.d.ts +11 -1
  111. package/dist/lib/reporting/ledger/row-storage-migration.d.mts +19 -1
  112. package/dist/lib/reporting/ledger/row-storage-migration.d.ts +19 -1
  113. package/dist/lib/reporting/ledger/row-storage-migration.js +133 -18
  114. package/dist/lib/reporting/ledger/row-storage-migration.mjs +133 -18
  115. package/dist/lib/reporting/ledger/row-storage-object.d.mts +103 -12
  116. package/dist/lib/reporting/ledger/row-storage-object.d.ts +103 -12
  117. package/dist/lib/reporting/ledger/row-storage-object.js +106 -31
  118. package/dist/lib/reporting/ledger/row-storage-object.mjs +104 -31
  119. package/dist/lib/reporting/ledger/row-storage.d.mts +87 -20
  120. package/dist/lib/reporting/ledger/row-storage.d.ts +87 -20
  121. package/dist/lib/reporting/ledger/row-storage.js +126 -66
  122. package/dist/lib/reporting/ledger/row-storage.mjs +129 -67
  123. package/dist/lib/reporting/ledger/schedule.d.mts +13 -0
  124. package/dist/lib/reporting/ledger/schedule.d.ts +13 -0
  125. package/dist/lib/reporting/ledger/schedule.js +24 -0
  126. package/dist/lib/reporting/ledger/schedule.mjs +23 -0
  127. package/dist/lib/reporting/ledger/types.d.mts +23 -1
  128. package/dist/lib/reporting/ledger/types.d.ts +23 -1
  129. package/dist/lib/reporting/s3/index.d.mts +5 -0
  130. package/dist/lib/reporting/s3/index.d.ts +5 -0
  131. package/dist/lib/reporting/s3/index.js +37 -14
  132. package/dist/lib/reporting/s3/index.mjs +37 -14
  133. package/dist/lib/reporting/service/index.d.mts +10 -0
  134. package/dist/lib/reporting/service/index.d.ts +10 -0
  135. package/dist/lib/reporting/service/maintenance.d.mts +28 -2
  136. package/dist/lib/reporting/service/maintenance.d.ts +28 -2
  137. package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
  138. package/dist/lib/server/account-sync-contract.d.mts +14 -0
  139. package/dist/lib/server/account-sync-contract.d.ts +14 -0
  140. package/dist/lib/server/account-sync-contract.js +225 -0
  141. package/dist/lib/server/account-sync-contract.mjs +197 -0
  142. package/dist/lib/server/adcp-server.js +5 -0
  143. package/dist/lib/server/adcp-server.mjs +10 -0
  144. package/dist/lib/server/auth-signature.d.mts +10 -0
  145. package/dist/lib/server/auth-signature.d.ts +10 -0
  146. package/dist/lib/server/auth-signature.js +61 -2
  147. package/dist/lib/server/auth-signature.mjs +65 -2
  148. package/dist/lib/server/auth.d.mts +6 -0
  149. package/dist/lib/server/auth.d.ts +6 -0
  150. package/dist/lib/server/auth.js +6 -0
  151. package/dist/lib/server/auth.mjs +6 -0
  152. package/dist/lib/server/create-adcp-server.d.mts +19 -5
  153. package/dist/lib/server/create-adcp-server.d.ts +19 -5
  154. package/dist/lib/server/create-adcp-server.js +238 -19
  155. package/dist/lib/server/create-adcp-server.mjs +240 -10
  156. package/dist/lib/server/decisioning/account.d.mts +24 -1
  157. package/dist/lib/server/decisioning/account.d.ts +24 -1
  158. package/dist/lib/server/decisioning/index.d.mts +1 -1
  159. package/dist/lib/server/decisioning/index.d.ts +1 -1
  160. package/dist/lib/server/decisioning/runtime/from-platform.d.mts +0 -50
  161. package/dist/lib/server/decisioning/runtime/from-platform.d.ts +0 -50
  162. package/dist/lib/server/decisioning/runtime/from-platform.js +61 -11
  163. package/dist/lib/server/decisioning/runtime/from-platform.mjs +65 -12
  164. package/dist/lib/server/index.d.mts +2 -0
  165. package/dist/lib/server/index.d.ts +2 -0
  166. package/dist/lib/server/index.js +12 -0
  167. package/dist/lib/server/index.mjs +12 -0
  168. package/dist/lib/server/notification-subscriptions/runtime.js +9 -1
  169. package/dist/lib/server/notification-subscriptions/runtime.mjs +9 -1
  170. package/dist/lib/server/notification-subscriptions/types.d.mts +5 -0
  171. package/dist/lib/server/notification-subscriptions/types.d.ts +5 -0
  172. package/dist/lib/server/principal/types.d.mts +1 -1
  173. package/dist/lib/server/principal/types.d.ts +1 -1
  174. package/dist/lib/server/serve.js +5 -0
  175. package/dist/lib/server/serve.mjs +5 -0
  176. package/dist/lib/server/webhook-delivery/recovery.d.mts +1 -0
  177. package/dist/lib/server/webhook-delivery/recovery.d.ts +1 -0
  178. package/dist/lib/server/webhook-delivery/recovery.js +4 -0
  179. package/dist/lib/server/webhook-delivery/recovery.mjs +4 -0
  180. package/dist/lib/server/webhook-emitter.d.mts +10 -0
  181. package/dist/lib/server/webhook-emitter.d.ts +10 -0
  182. package/dist/lib/server/webhook-emitter.js +22 -0
  183. package/dist/lib/server/webhook-emitter.mjs +22 -0
  184. package/dist/lib/signing/agent-context.d.mts +0 -5
  185. package/dist/lib/signing/agent-context.d.ts +0 -5
  186. package/dist/lib/signing/agent-context.js +9 -1
  187. package/dist/lib/signing/agent-context.mjs +9 -1
  188. package/dist/lib/signing/agent-fetch.js +27 -2
  189. package/dist/lib/signing/agent-fetch.mjs +32 -2
  190. package/dist/lib/signing/agent-resolver/canonicalize.d.mts +10 -15
  191. package/dist/lib/signing/agent-resolver/canonicalize.d.ts +10 -15
  192. package/dist/lib/signing/agent-resolver/canonicalize.js +17 -5
  193. package/dist/lib/signing/agent-resolver/canonicalize.mjs +16 -5
  194. package/dist/lib/signing/agent-resolver/index.d.mts +1 -0
  195. package/dist/lib/signing/agent-resolver/index.d.ts +1 -0
  196. package/dist/lib/signing/agent-resolver/index.js +5 -0
  197. package/dist/lib/signing/agent-resolver/index.mjs +3 -0
  198. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.mts +3 -2
  199. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.d.ts +3 -2
  200. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.js +30 -3
  201. package/dist/lib/signing/agent-resolver/resolved-agent-jwks.mjs +30 -3
  202. package/dist/lib/signing/agent-resolver/strict-json.d.mts +2 -2
  203. package/dist/lib/signing/agent-resolver/strict-json.d.ts +2 -2
  204. package/dist/lib/signing/agent-resolver/strict-json.js +5 -3
  205. package/dist/lib/signing/agent-resolver/strict-json.mjs +5 -3
  206. package/dist/lib/signing/brand-jwks.d.mts +2 -2
  207. package/dist/lib/signing/brand-jwks.d.ts +2 -2
  208. package/dist/lib/signing/brand-jwks.js +4 -4
  209. package/dist/lib/signing/brand-jwks.mjs +4 -4
  210. package/dist/lib/signing/client.d.mts +1 -0
  211. package/dist/lib/signing/client.d.ts +1 -0
  212. package/dist/lib/signing/client.js +5 -0
  213. package/dist/lib/signing/client.mjs +3 -0
  214. package/dist/lib/signing/jwks-https.d.mts +1 -1
  215. package/dist/lib/signing/jwks-https.d.ts +1 -1
  216. package/dist/lib/signing/jwks-https.js +1 -1
  217. package/dist/lib/signing/jwks-https.mjs +1 -1
  218. package/dist/lib/signing/jwks.d.mts +11 -3
  219. package/dist/lib/signing/jwks.d.ts +11 -3
  220. package/dist/lib/signing/jwks.js +1 -1
  221. package/dist/lib/signing/jwks.mjs +1 -1
  222. package/dist/lib/signing/parser.d.mts +1 -1
  223. package/dist/lib/signing/parser.d.ts +1 -1
  224. package/dist/lib/signing/parser.js +5 -3
  225. package/dist/lib/signing/parser.mjs +6 -4
  226. package/dist/lib/signing/revocation.d.mts +4 -1
  227. package/dist/lib/signing/revocation.d.ts +4 -1
  228. package/dist/lib/signing/revocation.js +33 -3
  229. package/dist/lib/signing/revocation.mjs +31 -2
  230. package/dist/lib/signing/server.d.mts +1 -1
  231. package/dist/lib/signing/server.d.ts +1 -1
  232. package/dist/lib/signing/server.js +4 -0
  233. package/dist/lib/signing/server.mjs +4 -0
  234. package/dist/lib/signing/types.d.mts +3 -0
  235. package/dist/lib/signing/types.d.ts +3 -0
  236. package/dist/lib/signing/web-bot-auth.d.mts +117 -0
  237. package/dist/lib/signing/web-bot-auth.d.ts +117 -0
  238. package/dist/lib/signing/web-bot-auth.js +660 -0
  239. package/dist/lib/signing/web-bot-auth.mjs +624 -0
  240. package/dist/lib/testing/client.d.mts +1 -4
  241. package/dist/lib/testing/client.d.ts +1 -4
  242. package/dist/lib/testing/client.js +141 -20
  243. package/dist/lib/testing/client.mjs +137 -19
  244. package/dist/lib/testing/compliance/comply.js +29 -10
  245. package/dist/lib/testing/compliance/comply.mjs +37 -11
  246. package/dist/lib/testing/storyboard/account-sync-contract.d.mts +3 -0
  247. package/dist/lib/testing/storyboard/account-sync-contract.d.ts +3 -0
  248. package/dist/lib/testing/storyboard/account-sync-contract.js +79 -0
  249. package/dist/lib/testing/storyboard/account-sync-contract.mjs +55 -0
  250. package/dist/lib/testing/storyboard/default-invariants.js +2 -0
  251. package/dist/lib/testing/storyboard/default-invariants.mjs +2 -0
  252. package/dist/lib/testing/storyboard/runner.js +23 -8
  253. package/dist/lib/testing/storyboard/runner.mjs +24 -8
  254. package/dist/lib/testing/storyboard/validations.d.mts +1 -1
  255. package/dist/lib/testing/storyboard/validations.d.ts +1 -1
  256. package/dist/lib/types/adcp.d.mts +4 -0
  257. package/dist/lib/types/adcp.d.ts +4 -0
  258. package/dist/lib/types/schemas.generated.d.ts +6 -6
  259. package/dist/lib/utils/capabilities.d.mts +1 -0
  260. package/dist/lib/utils/capabilities.d.ts +1 -0
  261. package/dist/lib/utils/capabilities.js +5 -0
  262. package/dist/lib/utils/capabilities.mjs +5 -0
  263. package/dist/lib/v2/projection/creative-delivery.d.mts +3 -1
  264. package/dist/lib/v2/projection/creative-delivery.d.ts +3 -1
  265. package/dist/lib/v2/projection/creative-delivery.js +26 -10
  266. package/dist/lib/v2/projection/creative-delivery.mjs +26 -10
  267. package/dist/lib/v2/projection/index.d.mts +1 -1
  268. package/dist/lib/v2/projection/index.d.ts +1 -1
  269. package/dist/lib/v2/projection/legacy-routes.d.mts +24 -2
  270. package/dist/lib/v2/projection/legacy-routes.d.ts +24 -2
  271. package/dist/lib/v2/projection/legacy-routes.js +28 -2
  272. package/dist/lib/v2/projection/legacy-routes.mjs +26 -2
  273. package/dist/lib/validation/schema-loader.d.mts +2 -0
  274. package/dist/lib/validation/schema-loader.d.ts +2 -0
  275. package/dist/lib/validation/schema-loader.js +43 -4
  276. package/dist/lib/validation/schema-loader.mjs +39 -3
  277. package/dist/lib/version.d.mts +3 -3
  278. package/dist/lib/version.d.ts +3 -3
  279. package/dist/lib/version.js +3 -3
  280. package/dist/lib/version.mjs +3 -3
  281. package/docs/TYPE-SUMMARY.md +2 -2
  282. package/docs/guides/DISCOVERY-CACHE-AND-SESSION-REUSE.md +4 -0
  283. package/docs/guides/REPORTING-LEDGER-CUTOVER.md +1 -1
  284. package/docs/guides/REPORTING-LEDGER.md +132 -46
  285. package/docs/guides/REPORTING-OPERATIONS.md +25 -4
  286. package/docs/guides/REPORTING-STABILITY.md +76 -0
  287. package/docs/guides/account-resolution.md +101 -0
  288. package/docs/llms.txt +3 -2
  289. package/docs/migration-12-to-13.md +7 -0
  290. package/docs/migration-14.x-rc-worksheet.md +4 -4
  291. package/docs/migration-agent-identity-3.3.md +355 -0
  292. package/docs/migration-agent-resolution-3.3.md +5 -0
  293. package/docs/migration-reporting-row-storage-alignment.md +137 -0
  294. package/examples/storyboards/account-sync-contract.yaml +57 -0
  295. package/package.json +15 -1
@@ -32,7 +32,8 @@ __export(bigquery_exports, {
32
32
  createBigQueryReportingWarehouseSinkV1: () => createBigQueryReportingWarehouseSinkV1,
33
33
  reportingWarehouseCurrentRowsViewSqlV1: () => reportingWarehouseCurrentRowsViewSqlV1,
34
34
  reportingWarehouseDefaultTablesSqlV1: () => reportingWarehouseDefaultTablesSqlV1,
35
- reportingWarehouseJobIdV1: () => reportingWarehouseJobIdV1
35
+ reportingWarehouseJobIdV1: () => reportingWarehouseJobIdV1,
36
+ reportingWarehouseLoadDeadlineV1: () => reportingWarehouseLoadDeadlineV1
36
37
  });
37
38
  module.exports = __toCommonJS(bigquery_exports);
38
39
  var import_crypto = require("crypto");
@@ -40,6 +41,7 @@ var import_fs = require("fs");
40
41
  var import_os = require("os");
41
42
  var path = __toESM(require("path"));
42
43
  var import_change_feed = require('../ledger/change-feed.js');
44
+ var import_schedule = require('../ledger/schedule.js');
43
45
  const REPORTING_WAREHOUSE_SINK_MIGRATION = `
44
46
  CREATE TABLE IF NOT EXISTS adcp_reporting_warehouse_sinks (
45
47
  sink_name TEXT PRIMARY KEY CHECK (sink_name ~ '^[A-Za-z0-9_.:-]{1,128}$'),
@@ -49,14 +51,21 @@ CREATE TABLE IF NOT EXISTS adcp_reporting_warehouse_sinks (
49
51
  planned_revisions JSONB,
50
52
  planned_rows_attempt INTEGER NOT NULL DEFAULT 0 CHECK (planned_rows_attempt >= 0),
51
53
  planned_revisions_attempt INTEGER NOT NULL DEFAULT 0 CHECK (planned_revisions_attempt >= 0),
54
+ planned_rows_timeouts INTEGER NOT NULL DEFAULT 0 CHECK (planned_rows_timeouts >= 0),
55
+ planned_revisions_timeouts INTEGER NOT NULL DEFAULT 0 CHECK (planned_revisions_timeouts >= 0),
52
56
  reset_generation INTEGER NOT NULL DEFAULT 0 CHECK (reset_generation >= 0),
53
57
  updated_at TIMESTAMPTZ NOT NULL DEFAULT clock_timestamp(),
54
58
  CHECK ((planned_to_cursor IS NULL) = (planned_revisions IS NULL))
55
59
  );
56
60
  ALTER TABLE adcp_reporting_warehouse_sinks
57
61
  ADD COLUMN IF NOT EXISTS reset_generation INTEGER NOT NULL DEFAULT 0 CHECK (reset_generation >= 0);
62
+ ALTER TABLE adcp_reporting_warehouse_sinks
63
+ ADD COLUMN IF NOT EXISTS planned_rows_timeouts INTEGER NOT NULL DEFAULT 0 CHECK (planned_rows_timeouts >= 0);
64
+ ALTER TABLE adcp_reporting_warehouse_sinks
65
+ ADD COLUMN IF NOT EXISTS planned_revisions_timeouts INTEGER NOT NULL DEFAULT 0 CHECK (planned_revisions_timeouts >= 0);
58
66
  `.trim();
59
67
  const MAX_LOAD_TIMEOUT = 6 * 36e5;
68
+ const MAX_TIMEOUT_DOUBLINGS = 16;
60
69
  let warnedLabelsIgnored = false;
61
70
  const PROJECT = /^[a-z][a-z0-9-]{4,61}[a-z0-9]$/;
62
71
  const DATASET_OR_TABLE = /^[A-Za-z_][A-Za-z0-9_]{0,1023}$/;
@@ -109,51 +118,104 @@ function createBigQueryReportingWarehouseSinkV1(options) {
109
118
  ...options.projectId ? { projectId: options.projectId } : {},
110
119
  ...options.location ? { location: options.location } : {}
111
120
  } : void 0;
112
- async function cancelLoad(jobId, signal) {
121
+ const uploads = /* @__PURE__ */ new Map();
122
+ function startUpload(tableId, jobId, lines) {
123
+ const entry = {
124
+ startedAt: Date.now(),
125
+ done: Promise.resolve()
126
+ };
127
+ const cleanup = async () => {
128
+ if (uploads.get(jobId) === entry) uploads.delete(jobId);
129
+ if (entry.directory) await import_fs.promises.rm(entry.directory, { recursive: true, force: true }).catch(() => {
130
+ });
131
+ };
132
+ entry.done = (async () => {
133
+ const directory = await import_fs.promises.mkdtemp(path.join((0, import_os.tmpdir)(), "adcp-warehouse-"));
134
+ entry.directory = directory;
135
+ const file = path.join(directory, `${jobId}.ndjson`);
136
+ await import_fs.promises.writeFile(file, lines.length ? lines.join("\n") + "\n" : "", { mode: 384 });
137
+ return dataset.table(tableId).load(file, {
138
+ jobId,
139
+ sourceFormat: "NEWLINE_DELIMITED_JSON",
140
+ writeDisposition: "WRITE_APPEND",
141
+ ...options.location ? { location: options.location } : {}
142
+ });
143
+ })();
144
+ const replaced = uploads.get(jobId);
145
+ uploads.set(jobId, entry);
146
+ void entry.done.then(cleanup, cleanup);
147
+ if (replaced?.directory) void import_fs.promises.rm(replaced.directory, { recursive: true, force: true }).catch(() => {
148
+ });
149
+ return entry.done;
150
+ }
151
+ async function jobStatus(jobId, signal, boundMilliseconds = loadTimeout, context) {
152
+ let metadata;
113
153
  try {
114
- const job = options.bigquery.job(jobId, jobOptions);
115
- if (typeof job.cancel !== "function") return;
116
- const cancel = job.cancel.bind(job);
117
- await withinDeadline(cancel, Math.min(loadTimeout, 3e4), signal);
118
- } catch (error) {
119
- const code = error?.code;
120
- if (code === 404 || signal?.aborted) return;
121
- process.emitWarning(
122
- `Cancelling BigQuery load job ${jobId} failed (${typeof code === "number" || typeof code === "string" ? code : "no status code"}); the job may still be running`,
123
- { code: "ADCP_BIGQUERY_SINK_CANCEL_FAILED" }
154
+ metadata = await withinDeadline(
155
+ () => options.bigquery.job(jobId, jobOptions).getMetadata(),
156
+ boundMilliseconds,
157
+ signal,
158
+ context
124
159
  );
160
+ } catch (error) {
161
+ if (error?.code === 404) return "missing";
162
+ throw error;
163
+ }
164
+ const record = Array.isArray(metadata) ? metadata[0] : metadata;
165
+ if (record?.status?.state !== "DONE") return "running";
166
+ if (record.status.errorResult) {
167
+ const failure = new Error("A BigQuery load job for this batch failed; it will be retried as a new attempt");
168
+ Object.defineProperty(failure, "adcpJobFailed", { value: true });
169
+ throw failure;
125
170
  }
171
+ return "done";
126
172
  }
127
- async function loadOnce(tableId, jobId, lines, attempt, signal) {
128
- const loadDeadline = Math.min(loadTimeout * 2 ** Math.min(attempt, 16), MAX_LOAD_TIMEOUT);
173
+ async function loadOnce(role, tableId, jobId, lines, timeouts, signal) {
129
174
  signal?.throwIfAborted();
130
- const directory = await import_fs.promises.mkdtemp(path.join((0, import_os.tmpdir)(), "adcp-warehouse-"));
131
- const file = path.join(directory, `${jobId}.ndjson`);
132
- try {
133
- await import_fs.promises.writeFile(file, lines.length ? lines.join("\n") + "\n" : "", { mode: 384 });
175
+ const table = `the ${role} table "${tableId}" (timeout count ${timeouts})`;
176
+ let status = await jobStatus(jobId, signal, loadTimeout, table);
177
+ if (status === "done") return;
178
+ const loadDeadline = reportingWarehouseLoadDeadlineV1(loadTimeout, timeouts);
179
+ const deadlineAt = Date.now() + loadDeadline;
180
+ const timedOut = (what) => {
181
+ const error = new Error(
182
+ `${what} exceeded this run's ${loadDeadline} ms deadline for ${table}; the next run checks the job again`
183
+ );
184
+ Object.defineProperty(error, "adcpDeadlineExceeded", { value: true });
185
+ Object.defineProperty(error, "adcpLoadTimedOut", { value: true });
186
+ return error;
187
+ };
188
+ if (status === "missing") {
134
189
  try {
135
- await withinDeadline(
136
- () => dataset.table(tableId).load(file, {
137
- jobId,
138
- sourceFormat: "NEWLINE_DELIMITED_JSON",
139
- writeDisposition: "WRITE_APPEND",
140
- ...options.location ? { location: options.location } : {}
141
- }),
142
- loadDeadline,
143
- signal
144
- );
190
+ const running = uploads.get(jobId);
191
+ const upload = running && Date.now() - running.startedAt < MAX_LOAD_TIMEOUT ? running.done : startUpload(tableId, jobId, lines);
192
+ await withinDeadline(() => upload, Math.max(deadlineAt - Date.now(), 1), signal);
193
+ return;
145
194
  } catch (error) {
146
- if (isDeadlineExceeded(error)) await cancelLoad(jobId, signal);
195
+ if (isDeadlineExceeded(error)) throw timedOut("Uploading the load");
147
196
  if (!isAlreadyExists(error)) throw error;
148
- const metadata = await withinDeadline(
149
- () => options.bigquery.job(jobId, jobOptions).getMetadata(),
150
- loadTimeout,
151
- signal
152
- );
153
- assertJobSucceeded(metadata);
197
+ status = await jobStatus(jobId, signal, loadTimeout, table);
198
+ if (status === "missing") {
199
+ throw new Error(
200
+ "BigQuery refused the load job ID as already existing, but the job cannot be found. Check that projectId and location match the dataset (location is required for datasets outside the US and EU multi-regions)",
201
+ { cause: error }
202
+ );
203
+ }
204
+ }
205
+ }
206
+ const pollMilliseconds = Math.min(5e3, Math.max(250, Math.floor(loadDeadline / 10)));
207
+ while (status !== "done") {
208
+ const remaining = deadlineAt - Date.now();
209
+ if (remaining <= 0) throw timedOut("Waiting for the running load job");
210
+ await sleep(Math.min(pollMilliseconds, remaining), signal);
211
+ const bound = Math.max(Math.min(loadTimeout, deadlineAt - Date.now()), 1);
212
+ try {
213
+ status = await jobStatus(jobId, signal, bound, table);
214
+ } catch (error) {
215
+ if (isDeadlineExceeded(error) && bound < loadTimeout) throw timedOut("Waiting for the running load job");
216
+ throw error;
154
217
  }
155
- } finally {
156
- await import_fs.promises.rm(directory, { recursive: true, force: true });
218
+ if (status === "missing") throw new Error("A BigQuery load job for this batch disappeared while it was awaited");
157
219
  }
158
220
  }
159
221
  return {
@@ -168,6 +230,7 @@ function createBigQueryReportingWarehouseSinkV1(options) {
168
230
  `UPDATE adcp_reporting_warehouse_sinks
169
231
  SET committed_cursor = NULL, planned_from_cursor = NULL, planned_to_cursor = NULL,
170
232
  planned_revisions = NULL, planned_rows_attempt = 0, planned_revisions_attempt = 0,
233
+ planned_rows_timeouts = 0, planned_revisions_timeouts = 0,
171
234
  reset_generation = reset_generation + 1, updated_at = clock_timestamp()
172
235
  WHERE sink_name = $1 AND ($2::boolean OR planned_to_cursor IS NULL)
173
236
  RETURNING sink_name`,
@@ -201,7 +264,8 @@ function createBigQueryReportingWarehouseSinkV1(options) {
201
264
  );
202
265
  const state = (await options.db.query(
203
266
  `SELECT committed_cursor, planned_from_cursor, planned_to_cursor, planned_revisions,
204
- planned_rows_attempt, planned_revisions_attempt, reset_generation
267
+ planned_rows_attempt, planned_revisions_attempt,
268
+ planned_rows_timeouts, planned_revisions_timeouts, reset_generation
205
269
  FROM adcp_reporting_warehouse_sinks WHERE sink_name = $1`,
206
270
  [options.name]
207
271
  ).catch(missingMigration)).rows[0];
@@ -220,7 +284,9 @@ function createBigQueryReportingWarehouseSinkV1(options) {
220
284
  to: state.planned_to_cursor,
221
285
  revisions: state.planned_revisions,
222
286
  rowsAttempt: state.planned_rows_attempt,
223
- revisionsAttempt: state.planned_revisions_attempt
287
+ revisionsAttempt: state.planned_revisions_attempt,
288
+ rowsTimeouts: state.planned_rows_timeouts,
289
+ revisionsTimeouts: state.planned_revisions_timeouts
224
290
  } : void 0;
225
291
  if (!plan) {
226
292
  const position = {
@@ -269,12 +335,15 @@ function createBigQueryReportingWarehouseSinkV1(options) {
269
335
  to: page.cursor,
270
336
  revisions: page.records.filter((record) => record.kind === "revision").map((record) => ({ id: record.record_id, account_id: record.account_id })),
271
337
  rowsAttempt: 0,
272
- revisionsAttempt: 0
338
+ revisionsAttempt: 0,
339
+ rowsTimeouts: 0,
340
+ revisionsTimeouts: 0
273
341
  };
274
342
  const claimed = await options.db.query(
275
343
  `UPDATE adcp_reporting_warehouse_sinks
276
344
  SET planned_from_cursor = $2, planned_to_cursor = $3, planned_revisions = $4::jsonb,
277
- planned_rows_attempt = 0, planned_revisions_attempt = 0, updated_at = clock_timestamp()
345
+ planned_rows_attempt = 0, planned_revisions_attempt = 0,
346
+ planned_rows_timeouts = 0, planned_revisions_timeouts = 0, updated_at = clock_timestamp()
278
347
  WHERE sink_name = $1 AND committed_cursor IS NOT DISTINCT FROM $2
279
348
  AND planned_to_cursor IS NULL AND planned_revisions IS NULL AND reset_generation = $5
280
349
  RETURNING sink_name`,
@@ -294,6 +363,7 @@ function createBigQueryReportingWarehouseSinkV1(options) {
294
363
  const rowLines = [];
295
364
  const revisionLines = [];
296
365
  const missing = [];
366
+ const resolved = [];
297
367
  for (const planned of plan.revisions) {
298
368
  signal?.throwIfAborted();
299
369
  const revision = await options.store.getRevisionMetadata(planned.id, planned.account_id);
@@ -301,10 +371,10 @@ function createBigQueryReportingWarehouseSinkV1(options) {
301
371
  missing.push(planned.id);
302
372
  continue;
303
373
  }
304
- const periodDate = sourceLocalDate(
305
- revision.wireRevision.period?.start,
306
- revision.wireRevision.period?.source_timezone
307
- );
374
+ resolved.push({ planned, revision, periodDate: periodDateOf(revision) });
375
+ }
376
+ for (const { planned, revision, periodDate } of resolved) {
377
+ signal?.throwIfAborted();
308
378
  const base = {
309
379
  reporting_revision_id: revision.reporting_revision_id,
310
380
  reporting_obligation_id: revision.reporting_obligation_id,
@@ -333,9 +403,9 @@ function createBigQueryReportingWarehouseSinkV1(options) {
333
403
  JSON.stringify({
334
404
  ...base,
335
405
  supersedes_reporting_revision_id: revision.supersedes_reporting_revision_id ?? null,
336
- period_start: revision.wireRevision.period?.start ?? null,
337
- period_end: revision.wireRevision.period?.end ?? null,
338
- source_timezone: revision.wireRevision.period?.source_timezone ?? null,
406
+ period_start: revision.wireRevision.period.start,
407
+ period_end: revision.wireRevision.period.end,
408
+ source_timezone: revision.wireRevision.period.source_timezone,
339
409
  observed_at: revision.observedAt,
340
410
  data_through: revision.dataThrough,
341
411
  revision_content_sha256: revision.binding.sha256,
@@ -347,27 +417,52 @@ function createBigQueryReportingWarehouseSinkV1(options) {
347
417
  const baseJobId = reportingWarehouseJobIdV1(options.name, plan.from, plan.to, state.reset_generation);
348
418
  const suffix = (attempt) => attempt ? `_a${attempt}` : "";
349
419
  const steps = [
350
- { table: options.rowsTableId, kind: "rows", lines: rowLines, attempt: plan.rowsAttempt },
351
- { table: options.revisionsTableId, kind: "revs", lines: revisionLines, attempt: plan.revisionsAttempt }
420
+ {
421
+ table: options.rowsTableId,
422
+ role: "rows",
423
+ kind: "rows",
424
+ lines: rowLines,
425
+ attempt: plan.rowsAttempt,
426
+ timeouts: plan.rowsTimeouts,
427
+ timeoutColumn: "planned_rows_timeouts",
428
+ attemptColumn: "planned_rows_attempt"
429
+ },
430
+ {
431
+ table: options.revisionsTableId,
432
+ role: "revisions",
433
+ kind: "revs",
434
+ lines: revisionLines,
435
+ attempt: plan.revisionsAttempt,
436
+ timeouts: plan.revisionsTimeouts,
437
+ timeoutColumn: "planned_revisions_timeouts",
438
+ attemptColumn: "planned_revisions_attempt"
439
+ }
352
440
  ];
353
441
  for (const step of steps) {
354
442
  if (!step.lines.length) continue;
355
443
  try {
356
444
  await loadOnce(
445
+ step.role,
357
446
  step.table,
358
447
  `${baseJobId}_${step.kind}${suffix(step.attempt)}`,
359
448
  [...step.lines],
360
- step.attempt,
449
+ step.timeouts,
361
450
  signal
362
451
  );
363
452
  } catch (error) {
364
453
  if (isFinishedWithError(error)) {
365
- const column = step.kind === "rows" ? "planned_rows_attempt" : "planned_revisions_attempt";
366
454
  await options.db.query(
367
- `UPDATE adcp_reporting_warehouse_sinks SET ${column} = ${column} + 1,
455
+ `UPDATE adcp_reporting_warehouse_sinks SET ${step.attemptColumn} = ${step.attemptColumn} + 1,
368
456
  updated_at = clock_timestamp() ${matchesPlan}`,
369
457
  planValues
370
458
  );
459
+ } else if (isLoadTimedOut(error)) {
460
+ await options.db.query(
461
+ `UPDATE adcp_reporting_warehouse_sinks
462
+ SET ${step.timeoutColumn} = $8::integer + 1, updated_at = clock_timestamp()
463
+ ${matchesPlan} AND ${step.timeoutColumn} = $8::integer`,
464
+ [...planValues, step.timeouts]
465
+ );
371
466
  }
372
467
  throw error;
373
468
  }
@@ -376,7 +471,7 @@ function createBigQueryReportingWarehouseSinkV1(options) {
376
471
  `UPDATE adcp_reporting_warehouse_sinks
377
472
  SET committed_cursor = $3, planned_from_cursor = NULL, planned_to_cursor = NULL,
378
473
  planned_revisions = NULL, planned_rows_attempt = 0, planned_revisions_attempt = 0,
379
- updated_at = clock_timestamp()
474
+ planned_rows_timeouts = 0, planned_revisions_timeouts = 0, updated_at = clock_timestamp()
380
475
  ${matchesPlan} RETURNING sink_name`,
381
476
  planValues
382
477
  );
@@ -395,6 +490,9 @@ function missingMigration(error) {
395
490
  }
396
491
  throw error;
397
492
  }
493
+ function reportingWarehouseLoadDeadlineV1(baseMilliseconds, timeouts) {
494
+ return Math.min(baseMilliseconds * 2 ** Math.min(Math.max(timeouts, 0), MAX_TIMEOUT_DOUBLINGS), MAX_LOAD_TIMEOUT);
495
+ }
398
496
  function reportingWarehouseJobIdV1(name, from, to, generation = 0) {
399
497
  return `adcp_rr_${(0, import_crypto.createHash)("sha256").update(JSON.stringify(generation > 0 ? [name, from, to, generation] : [name, from, to])).digest("hex").slice(0, 40)}`;
400
498
  }
@@ -451,23 +549,19 @@ SELECT row_data.*
451
549
  ) AS current_revision
452
550
  USING (reporting_obligation_id, reporting_revision_id);`.trim();
453
551
  }
454
- function sourceLocalDate(start, timeZone) {
455
- if (!start) return null;
456
- const instant = new Date(start);
457
- if (Number.isNaN(instant.getTime())) return null;
552
+ function periodDateOf(revision) {
553
+ const period = revision.wireRevision.period;
458
554
  try {
459
- const parts = new Intl.DateTimeFormat("en-CA", {
460
- timeZone: timeZone ?? "UTC",
461
- year: "numeric",
462
- month: "2-digit",
463
- day: "2-digit"
464
- }).format(instant);
465
- return parts;
466
- } catch {
467
- return instant.toISOString().slice(0, 10);
555
+ if (!period) throw new TypeError("the revision carries no period");
556
+ return (0, import_schedule.reportingPeriodDate)(period.start, period.source_timezone);
557
+ } catch (error) {
558
+ throw new Error(
559
+ `Cannot compute period_date for revision ${revision.reporting_revision_id}: ${error instanceof Error ? error.message : String(error)}. The batch stays retained and every run fails until the revision's period is repaired (or, if this runtime's timezone data is older than the writer's, until it is upgraded); reset({ discardRetainedPlan: true }) restarts from the beginning, so empty the destination tables first.`,
560
+ { cause: error }
561
+ );
468
562
  }
469
563
  }
470
- async function withinDeadline(operation, milliseconds, signal) {
564
+ async function withinDeadline(operation, milliseconds, signal, context) {
471
565
  signal?.throwIfAborted();
472
566
  let timer;
473
567
  let onAbort;
@@ -476,7 +570,9 @@ async function withinDeadline(operation, milliseconds, signal) {
476
570
  operation(),
477
571
  new Promise((_, reject) => {
478
572
  timer = setTimeout(() => {
479
- const error = new Error("BigQuery call exceeded its deadline; the batch will be retried");
573
+ const error = new Error(
574
+ `BigQuery call exceeded its deadline${context ? ` of ${milliseconds} ms for ${context}` : ""}; the batch will be retried`
575
+ );
480
576
  Object.defineProperty(error, "adcpDeadlineExceeded", { value: true });
481
577
  reject(error);
482
578
  }, milliseconds);
@@ -498,25 +594,32 @@ function isAlreadyExists(error) {
498
594
  const record = error;
499
595
  return record?.code === 409 || !!record?.errors?.some((entry) => entry.reason === "duplicate");
500
596
  }
597
+ function isLoadTimedOut(error) {
598
+ return error?.adcpLoadTimedOut === true;
599
+ }
600
+ function sleep(milliseconds, signal) {
601
+ signal?.throwIfAborted();
602
+ return new Promise((resolve, reject) => {
603
+ const onAbort = () => {
604
+ clearTimeout(timer);
605
+ reject(signal?.reason ?? new Error("aborted"));
606
+ };
607
+ const timer = setTimeout(() => {
608
+ signal?.removeEventListener("abort", onAbort);
609
+ resolve();
610
+ }, milliseconds);
611
+ signal?.addEventListener("abort", onAbort, { once: true });
612
+ });
613
+ }
501
614
  function isFinishedWithError(error) {
502
615
  return error?.adcpJobFailed === true;
503
616
  }
504
- function assertJobSucceeded(metadata) {
505
- const record = Array.isArray(metadata) ? metadata[0] : metadata;
506
- if (record?.status?.state !== "DONE") {
507
- throw new Error("A BigQuery load job for this batch is still running; retry later");
508
- }
509
- if (record.status.errorResult) {
510
- const failure = new Error("A BigQuery load job for this batch failed; it will be retried as a new attempt");
511
- Object.defineProperty(failure, "adcpJobFailed", { value: true });
512
- throw failure;
513
- }
514
- }
515
617
  // Annotate the CommonJS export names for ESM import in node:
516
618
  0 && (module.exports = {
517
619
  REPORTING_WAREHOUSE_SINK_MIGRATION,
518
620
  createBigQueryReportingWarehouseSinkV1,
519
621
  reportingWarehouseCurrentRowsViewSqlV1,
520
622
  reportingWarehouseDefaultTablesSqlV1,
521
- reportingWarehouseJobIdV1
623
+ reportingWarehouseJobIdV1,
624
+ reportingWarehouseLoadDeadlineV1
522
625
  });