@adcp/sdk 15.2.2 → 15.4.0
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.
- package/dist/lib/core/ConversationTypes.d.mts +5 -0
- package/dist/lib/core/ConversationTypes.d.ts +5 -0
- package/dist/lib/core/SingleAgentClient.d.mts +19 -1
- package/dist/lib/core/SingleAgentClient.d.ts +19 -1
- package/dist/lib/core/SingleAgentClient.js +38 -7
- package/dist/lib/core/SingleAgentClient.mjs +38 -7
- package/dist/lib/index.d.mts +1 -1
- package/dist/lib/index.d.ts +1 -1
- package/dist/lib/reporting/ledger/handler.d.mts +6 -0
- package/dist/lib/reporting/ledger/handler.d.ts +6 -0
- package/dist/lib/reporting/ledger/handler.js +36 -7
- package/dist/lib/reporting/ledger/handler.mjs +35 -7
- package/dist/lib/reporting/ledger/index.d.mts +1 -0
- package/dist/lib/reporting/ledger/index.d.ts +1 -0
- package/dist/lib/reporting/ledger/index.js +3 -1
- package/dist/lib/reporting/ledger/index.mjs +1 -0
- package/dist/lib/reporting/ledger/lifecycle.js +3 -2
- package/dist/lib/reporting/ledger/lifecycle.mjs +3 -2
- package/dist/lib/reporting/ledger/managed-postgres.js +5 -5
- package/dist/lib/reporting/ledger/managed-postgres.mjs +5 -5
- package/dist/lib/reporting/ledger/postgres.d.mts +4 -1
- package/dist/lib/reporting/ledger/postgres.d.ts +4 -1
- package/dist/lib/reporting/ledger/postgres.js +38 -0
- package/dist/lib/reporting/ledger/postgres.mjs +38 -0
- package/dist/lib/reporting/ledger/producer.js +3 -2
- package/dist/lib/reporting/ledger/producer.mjs +3 -2
- package/dist/lib/reporting/ledger/revision-metadata.d.mts +17 -0
- package/dist/lib/reporting/ledger/revision-metadata.d.ts +17 -0
- package/dist/lib/reporting/ledger/revision-metadata.js +71 -0
- package/dist/lib/reporting/ledger/revision-metadata.mjs +44 -0
- package/dist/lib/reporting/ledger/row-encoding.d.mts +128 -0
- package/dist/lib/reporting/ledger/row-encoding.d.ts +128 -0
- package/dist/lib/reporting/ledger/row-encoding.js +355 -0
- package/dist/lib/reporting/ledger/row-encoding.mjs +315 -0
- package/dist/lib/reporting/ledger/types.d.mts +37 -0
- package/dist/lib/reporting/ledger/types.d.ts +37 -0
- package/dist/lib/schemas-data/v2.5/_provenance.json +1 -1
- package/dist/lib/testing/storyboard/validations.d.mts +1 -1
- package/dist/lib/testing/storyboard/validations.d.ts +1 -1
- package/dist/lib/version.d.mts +3 -3
- package/dist/lib/version.d.ts +3 -3
- package/dist/lib/version.js +3 -3
- package/dist/lib/version.mjs +3 -3
- package/docs/TYPE-SUMMARY.md +2 -1
- package/docs/guides/PUSH-NOTIFICATION-CONFIG.md +39 -0
- package/docs/llms.txt +1 -1
- package/docs/migration-14.x-rc-worksheet.md +4 -4
- package/package.json +1 -1
|
@@ -3,6 +3,7 @@ import { canonicalJsonV1 } from "../source/index.mjs";
|
|
|
3
3
|
import { moreSevereReportingHealthV1, projectManagedDelivery } from "./handler.mjs";
|
|
4
4
|
import { compareReportingInstants } from "./instant.mjs";
|
|
5
5
|
import { projectReportingObligationHealthV1 } from "./health.mjs";
|
|
6
|
+
import { listAdjustmentMetadataFromStore, listRevisionMetadataFromStore } from "./revision-metadata.mjs";
|
|
6
7
|
async function resolveLedgerAsOf(input, attempt) {
|
|
7
8
|
const resolved = await input.store.readLedgerInstant?.() ?? (input.now ?? (() => /* @__PURE__ */ new Date()))().toISOString();
|
|
8
9
|
if (input.ledgerAsOf === void 0) return resolved;
|
|
@@ -53,7 +54,7 @@ async function reconcileReportingStatusLifecycleV1(input, attempt = 0) {
|
|
|
53
54
|
const transactionalNotifications = input.store.transactionalNotificationActivity === true;
|
|
54
55
|
assertNotificationModesCompatible(input.store, input.subscribers);
|
|
55
56
|
let ledgerAsOf = await resolveLedgerAsOf(input, attempt);
|
|
56
|
-
const revisions = await input.store
|
|
57
|
+
const revisions = await listRevisionMetadataFromStore(input.store, obligation.reporting_obligation_id);
|
|
57
58
|
let projected = revisions;
|
|
58
59
|
const projectCore = (at) => projectReportingObligationHealthV1(
|
|
59
60
|
obligation,
|
|
@@ -182,7 +183,7 @@ async function composeManagedLifecycleProjection(input, obligation, revisions, c
|
|
|
182
183
|
ledgerAsOf: input.ledgerAsOf
|
|
183
184
|
});
|
|
184
185
|
if (!managed) return { projection: coreProjection };
|
|
185
|
-
const stored = await input.store
|
|
186
|
+
const stored = await listAdjustmentMetadataFromStore(input.store, obligation.reporting_obligation_id);
|
|
186
187
|
const visibleAdjustmentIds = managed.visibleAdjustmentIds;
|
|
187
188
|
const adjustments = visibleAdjustmentIds ? stored.filter((value) => visibleAdjustmentIds.includes(value.reporting_adjustment_id)) : stored.filter((value) => compareReportingInstants(value.createdAt, input.ledgerAsOf) <= 0);
|
|
188
189
|
const rosterAuthoritative = managed.obligatedConsumerRosterComplete === true && managed.receiptEvidenceComplete !== false;
|
|
@@ -987,7 +987,7 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
987
987
|
])
|
|
988
988
|
);
|
|
989
989
|
const candidates = await client.query(
|
|
990
|
-
`SELECT binding.data AS binding, obligation.data AS obligation, revision.
|
|
990
|
+
`SELECT binding.data AS binding, obligation.data AS obligation, revision.revision_id AS revision_id,
|
|
991
991
|
GREATEST(COALESCE(MAX(existing.attempt), 0), COALESCE(MAX(tomb.highest_attempt), 0))::integer + 1
|
|
992
992
|
AS attempt
|
|
993
993
|
FROM adcp_reporting_managed_bindings binding
|
|
@@ -1007,7 +1007,7 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
1007
1007
|
ON tomb.configuration_id = binding.configuration_id AND tomb.revision_id = revision.revision_id
|
|
1008
1008
|
WHERE ($1::text IS NULL OR binding.account_id = $1)
|
|
1009
1009
|
GROUP BY binding.configuration_id, binding.data, obligation.obligation_id, obligation.data,
|
|
1010
|
-
revision.revision_id
|
|
1010
|
+
revision.revision_id
|
|
1011
1011
|
HAVING NOT COALESCE(BOOL_OR(existing.status IN ('pending','available','delivered')), false)
|
|
1012
1012
|
AND NOT COALESCE(BOOL_OR(tomb.reached_success), false)
|
|
1013
1013
|
AND GREATEST(COALESCE(MAX(existing.attempt), 0), COALESCE(MAX(tomb.highest_attempt), 0))
|
|
@@ -1022,11 +1022,11 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
1022
1022
|
const remaining = remainingByAccount.get(binding.account_id) ?? 0;
|
|
1023
1023
|
if (remaining <= 0) continue;
|
|
1024
1024
|
const obligation = candidate.obligation;
|
|
1025
|
-
const
|
|
1025
|
+
const revisionId = candidate.revision_id;
|
|
1026
1026
|
const created_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1027
1027
|
const materialization = {
|
|
1028
1028
|
reporting_materialization_id: `rmat_${(0, import_node_crypto.randomUUID)()}`,
|
|
1029
|
-
reporting_revision_id:
|
|
1029
|
+
reporting_revision_id: revisionId,
|
|
1030
1030
|
reporting_obligation_id: obligation.reporting_obligation_id,
|
|
1031
1031
|
delivery_config_id: binding.delivery_config_id,
|
|
1032
1032
|
delivery_config_version: binding.delivery_config_version,
|
|
@@ -1049,7 +1049,7 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
1049
1049
|
binding.account_id,
|
|
1050
1050
|
binding.configurationId,
|
|
1051
1051
|
obligation.reporting_obligation_id,
|
|
1052
|
-
|
|
1052
|
+
revisionId,
|
|
1053
1053
|
binding.destination_ref,
|
|
1054
1054
|
binding.authorization_generation,
|
|
1055
1055
|
candidate.attempt,
|
|
@@ -972,7 +972,7 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
972
972
|
])
|
|
973
973
|
);
|
|
974
974
|
const candidates = await client.query(
|
|
975
|
-
`SELECT binding.data AS binding, obligation.data AS obligation, revision.
|
|
975
|
+
`SELECT binding.data AS binding, obligation.data AS obligation, revision.revision_id AS revision_id,
|
|
976
976
|
GREATEST(COALESCE(MAX(existing.attempt), 0), COALESCE(MAX(tomb.highest_attempt), 0))::integer + 1
|
|
977
977
|
AS attempt
|
|
978
978
|
FROM adcp_reporting_managed_bindings binding
|
|
@@ -992,7 +992,7 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
992
992
|
ON tomb.configuration_id = binding.configuration_id AND tomb.revision_id = revision.revision_id
|
|
993
993
|
WHERE ($1::text IS NULL OR binding.account_id = $1)
|
|
994
994
|
GROUP BY binding.configuration_id, binding.data, obligation.obligation_id, obligation.data,
|
|
995
|
-
revision.revision_id
|
|
995
|
+
revision.revision_id
|
|
996
996
|
HAVING NOT COALESCE(BOOL_OR(existing.status IN ('pending','available','delivered')), false)
|
|
997
997
|
AND NOT COALESCE(BOOL_OR(tomb.reached_success), false)
|
|
998
998
|
AND GREATEST(COALESCE(MAX(existing.attempt), 0), COALESCE(MAX(tomb.highest_attempt), 0))
|
|
@@ -1007,11 +1007,11 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
1007
1007
|
const remaining = remainingByAccount.get(binding.account_id) ?? 0;
|
|
1008
1008
|
if (remaining <= 0) continue;
|
|
1009
1009
|
const obligation = candidate.obligation;
|
|
1010
|
-
const
|
|
1010
|
+
const revisionId = candidate.revision_id;
|
|
1011
1011
|
const created_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
1012
1012
|
const materialization = {
|
|
1013
1013
|
reporting_materialization_id: `rmat_${randomUUID()}`,
|
|
1014
|
-
reporting_revision_id:
|
|
1014
|
+
reporting_revision_id: revisionId,
|
|
1015
1015
|
reporting_obligation_id: obligation.reporting_obligation_id,
|
|
1016
1016
|
delivery_config_id: binding.delivery_config_id,
|
|
1017
1017
|
delivery_config_version: binding.delivery_config_version,
|
|
@@ -1034,7 +1034,7 @@ class PostgresReportingManagedDeliveryStore {
|
|
|
1034
1034
|
binding.account_id,
|
|
1035
1035
|
binding.configurationId,
|
|
1036
1036
|
obligation.reporting_obligation_id,
|
|
1037
|
-
|
|
1037
|
+
revisionId,
|
|
1038
1038
|
binding.destination_ref,
|
|
1039
1039
|
binding.authorization_generation,
|
|
1040
1040
|
candidate.attempt,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { REPORTING_LEDGER_AUTHORITY } from './types.mjs';
|
|
2
|
-
import type { ReportingLedgerConfigurationV1, ReportingLedgerAdjustmentV1, ReportingLedgerConsumerStatusV1, ReportingLedgerIssueV1, ReportingLedgerLeaseV1, ReportingLedgerObligationV1, ReportingLedgerPageV1, ReportingLedgerRevisionV1, ReportingLedgerSnapshotQueryV1, ReportingLedgerSnapshotV1, ReportingLedgerStatusTransitionV1, ReportingLedgerNotificationActivityPortV1, ReportingLedgerTransactionV1, ReportingObservedFinalityV1, ReportingLedgerStore, ReportingConsumerStatusBatchInputV1, ReportingConsumerStatusBatchResultV1, ReportingConsumerStatusReplayInputV1, ReportingLedgerRevisionMetadataV1, ReportingManagedLifecycleProjectionV1, ReportingLedgerAuthorityV1 } from './types.mjs';
|
|
2
|
+
import type { ReportingLedgerConfigurationV1, ReportingLedgerAdjustmentMetadataV1, ReportingLedgerAdjustmentV1, ReportingLedgerConsumerStatusV1, ReportingLedgerIssueV1, ReportingLedgerLeaseV1, ReportingLedgerObligationV1, ReportingLedgerPageV1, ReportingLedgerRevisionV1, ReportingLedgerSnapshotQueryV1, ReportingLedgerSnapshotV1, ReportingLedgerStatusTransitionV1, ReportingLedgerNotificationActivityPortV1, ReportingLedgerTransactionV1, ReportingObservedFinalityV1, ReportingLedgerStore, ReportingConsumerStatusBatchInputV1, ReportingConsumerStatusBatchResultV1, ReportingConsumerStatusReplayInputV1, ReportingLedgerRevisionMetadataV1, ReportingRevisionRowsPageV1, ReportingRevisionRowsReadV1, ReportingManagedLifecycleProjectionV1, ReportingLedgerAuthorityV1 } from './types.mjs';
|
|
3
3
|
import type { ReportingConsumerMismatchEscalationV1 } from './types.mjs';
|
|
4
4
|
type QueryResultRow = Record<string, unknown>;
|
|
5
5
|
interface ReportingPgResult<Row extends QueryResultRow> {
|
|
@@ -144,12 +144,15 @@ export declare class PostgresReportingLedgerStore implements ReportingLedgerStor
|
|
|
144
144
|
}>;
|
|
145
145
|
getRevision(id: string, accountId: string): Promise<ReportingLedgerRevisionV1 | null>;
|
|
146
146
|
getRevisionMetadata(id: string, accountId: string): Promise<ReportingLedgerRevisionMetadataV1 | null>;
|
|
147
|
+
readRevisionRows(input: ReportingRevisionRowsReadV1): Promise<ReportingRevisionRowsPageV1 | null>;
|
|
147
148
|
listRevisions(obligationId: string): Promise<ReportingLedgerRevisionV1[]>;
|
|
149
|
+
listRevisionMetadata(obligationId: string, accountId?: string): Promise<ReportingLedgerRevisionMetadataV1[]>;
|
|
148
150
|
commitAdjustment(adjustment: ReportingLedgerAdjustmentV1, lease: ReportingLedgerLeaseV1): Promise<{
|
|
149
151
|
inserted: boolean;
|
|
150
152
|
value: ReportingLedgerAdjustmentV1;
|
|
151
153
|
}>;
|
|
152
154
|
listAdjustments(obligationId: string): Promise<ReportingLedgerAdjustmentV1[]>;
|
|
155
|
+
listAdjustmentMetadata(obligationId: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
|
|
153
156
|
putConsumerStatus(status: ReportingLedgerConsumerStatusV1): Promise<{
|
|
154
157
|
inserted: boolean;
|
|
155
158
|
value: ReportingLedgerConsumerStatusV1;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { REPORTING_LEDGER_AUTHORITY } from './types';
|
|
2
|
-
import type { ReportingLedgerConfigurationV1, ReportingLedgerAdjustmentV1, ReportingLedgerConsumerStatusV1, ReportingLedgerIssueV1, ReportingLedgerLeaseV1, ReportingLedgerObligationV1, ReportingLedgerPageV1, ReportingLedgerRevisionV1, ReportingLedgerSnapshotQueryV1, ReportingLedgerSnapshotV1, ReportingLedgerStatusTransitionV1, ReportingLedgerNotificationActivityPortV1, ReportingLedgerTransactionV1, ReportingObservedFinalityV1, ReportingLedgerStore, ReportingConsumerStatusBatchInputV1, ReportingConsumerStatusBatchResultV1, ReportingConsumerStatusReplayInputV1, ReportingLedgerRevisionMetadataV1, ReportingManagedLifecycleProjectionV1, ReportingLedgerAuthorityV1 } from './types';
|
|
2
|
+
import type { ReportingLedgerConfigurationV1, ReportingLedgerAdjustmentMetadataV1, ReportingLedgerAdjustmentV1, ReportingLedgerConsumerStatusV1, ReportingLedgerIssueV1, ReportingLedgerLeaseV1, ReportingLedgerObligationV1, ReportingLedgerPageV1, ReportingLedgerRevisionV1, ReportingLedgerSnapshotQueryV1, ReportingLedgerSnapshotV1, ReportingLedgerStatusTransitionV1, ReportingLedgerNotificationActivityPortV1, ReportingLedgerTransactionV1, ReportingObservedFinalityV1, ReportingLedgerStore, ReportingConsumerStatusBatchInputV1, ReportingConsumerStatusBatchResultV1, ReportingConsumerStatusReplayInputV1, ReportingLedgerRevisionMetadataV1, ReportingRevisionRowsPageV1, ReportingRevisionRowsReadV1, ReportingManagedLifecycleProjectionV1, ReportingLedgerAuthorityV1 } from './types';
|
|
3
3
|
import type { ReportingConsumerMismatchEscalationV1 } from './types';
|
|
4
4
|
type QueryResultRow = Record<string, unknown>;
|
|
5
5
|
interface ReportingPgResult<Row extends QueryResultRow> {
|
|
@@ -144,12 +144,15 @@ export declare class PostgresReportingLedgerStore implements ReportingLedgerStor
|
|
|
144
144
|
}>;
|
|
145
145
|
getRevision(id: string, accountId: string): Promise<ReportingLedgerRevisionV1 | null>;
|
|
146
146
|
getRevisionMetadata(id: string, accountId: string): Promise<ReportingLedgerRevisionMetadataV1 | null>;
|
|
147
|
+
readRevisionRows(input: ReportingRevisionRowsReadV1): Promise<ReportingRevisionRowsPageV1 | null>;
|
|
147
148
|
listRevisions(obligationId: string): Promise<ReportingLedgerRevisionV1[]>;
|
|
149
|
+
listRevisionMetadata(obligationId: string, accountId?: string): Promise<ReportingLedgerRevisionMetadataV1[]>;
|
|
148
150
|
commitAdjustment(adjustment: ReportingLedgerAdjustmentV1, lease: ReportingLedgerLeaseV1): Promise<{
|
|
149
151
|
inserted: boolean;
|
|
150
152
|
value: ReportingLedgerAdjustmentV1;
|
|
151
153
|
}>;
|
|
152
154
|
listAdjustments(obligationId: string): Promise<ReportingLedgerAdjustmentV1[]>;
|
|
155
|
+
listAdjustmentMetadata(obligationId: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
|
|
153
156
|
putConsumerStatus(status: ReportingLedgerConsumerStatusV1): Promise<{
|
|
154
157
|
inserted: boolean;
|
|
155
158
|
value: ReportingLedgerConsumerStatusV1;
|
|
@@ -695,6 +695,26 @@ ${managedDueArm} )
|
|
|
695
695
|
[id, accountId]
|
|
696
696
|
);
|
|
697
697
|
}
|
|
698
|
+
async readRevisionRows(input) {
|
|
699
|
+
if (!Number.isSafeInteger(input.offset) || input.offset < 0 || !Number.isSafeInteger(input.limit) || input.limit < 1) {
|
|
700
|
+
throw new RangeError("Reporting row page bounds are invalid");
|
|
701
|
+
}
|
|
702
|
+
const result = await this.query(
|
|
703
|
+
`SELECT jsonb_array_length(revision.data->'rows') AS total,
|
|
704
|
+
jsonb_path_query_array(
|
|
705
|
+
revision.data->'rows',
|
|
706
|
+
'$[$from to $to]',
|
|
707
|
+
jsonb_build_object('from', $3::bigint, 'to', $3::bigint + $4::bigint - 1)
|
|
708
|
+
) AS rows
|
|
709
|
+
FROM adcp_reporting_revisions revision
|
|
710
|
+
JOIN adcp_reporting_obligations obligation ON obligation.obligation_id = revision.obligation_id
|
|
711
|
+
WHERE revision.revision_id = $1 AND obligation.account_id = $2`,
|
|
712
|
+
[input.reporting_revision_id, input.account_id, input.offset, input.limit]
|
|
713
|
+
);
|
|
714
|
+
const row = result.rows[0];
|
|
715
|
+
if (!row) return null;
|
|
716
|
+
return { rows: clone(row.rows), total: Number(row.total) };
|
|
717
|
+
}
|
|
698
718
|
async listRevisions(obligationId) {
|
|
699
719
|
const result = await this.query(
|
|
700
720
|
`SELECT data FROM adcp_reporting_revisions WHERE obligation_id = $1
|
|
@@ -703,6 +723,16 @@ ${managedDueArm} )
|
|
|
703
723
|
);
|
|
704
724
|
return result.rows.map((row) => clone(row.data));
|
|
705
725
|
}
|
|
726
|
+
async listRevisionMetadata(obligationId, accountId) {
|
|
727
|
+
const result = await this.query(
|
|
728
|
+
`SELECT revision.data - 'rows' AS data FROM adcp_reporting_revisions revision
|
|
729
|
+
JOIN adcp_reporting_obligations obligation ON obligation.obligation_id = revision.obligation_id
|
|
730
|
+
WHERE revision.obligation_id = $1 AND ($2::text IS NULL OR obligation.account_id = $2)
|
|
731
|
+
ORDER BY revision.revision_number, revision.revision_id`,
|
|
732
|
+
[obligationId, accountId ?? null]
|
|
733
|
+
);
|
|
734
|
+
return result.rows.map((row) => clone(row.data));
|
|
735
|
+
}
|
|
706
736
|
async commitAdjustment(adjustment, lease) {
|
|
707
737
|
assertLeaseTarget(adjustment.reporting_obligation_id, lease);
|
|
708
738
|
validateBoundRows(adjustment);
|
|
@@ -766,6 +796,14 @@ ${managedDueArm} )
|
|
|
766
796
|
);
|
|
767
797
|
return result.rows.map((row) => clone(row.data));
|
|
768
798
|
}
|
|
799
|
+
async listAdjustmentMetadata(obligationId) {
|
|
800
|
+
const result = await this.query(
|
|
801
|
+
`SELECT data - 'rows' AS data FROM adcp_reporting_adjustments WHERE obligation_id = $1
|
|
802
|
+
ORDER BY adjustment_number, adjustment_id`,
|
|
803
|
+
[obligationId]
|
|
804
|
+
);
|
|
805
|
+
return result.rows.map((row) => clone(row.data));
|
|
806
|
+
}
|
|
769
807
|
async putConsumerStatus(status) {
|
|
770
808
|
const obligation = await this.getObligation(status.reporting_obligation_id);
|
|
771
809
|
if (!obligation) throw new Error("Reporting consumer status obligation is unavailable");
|
|
@@ -686,6 +686,26 @@ ${managedDueArm} )
|
|
|
686
686
|
[id, accountId]
|
|
687
687
|
);
|
|
688
688
|
}
|
|
689
|
+
async readRevisionRows(input) {
|
|
690
|
+
if (!Number.isSafeInteger(input.offset) || input.offset < 0 || !Number.isSafeInteger(input.limit) || input.limit < 1) {
|
|
691
|
+
throw new RangeError("Reporting row page bounds are invalid");
|
|
692
|
+
}
|
|
693
|
+
const result = await this.query(
|
|
694
|
+
`SELECT jsonb_array_length(revision.data->'rows') AS total,
|
|
695
|
+
jsonb_path_query_array(
|
|
696
|
+
revision.data->'rows',
|
|
697
|
+
'$[$from to $to]',
|
|
698
|
+
jsonb_build_object('from', $3::bigint, 'to', $3::bigint + $4::bigint - 1)
|
|
699
|
+
) AS rows
|
|
700
|
+
FROM adcp_reporting_revisions revision
|
|
701
|
+
JOIN adcp_reporting_obligations obligation ON obligation.obligation_id = revision.obligation_id
|
|
702
|
+
WHERE revision.revision_id = $1 AND obligation.account_id = $2`,
|
|
703
|
+
[input.reporting_revision_id, input.account_id, input.offset, input.limit]
|
|
704
|
+
);
|
|
705
|
+
const row = result.rows[0];
|
|
706
|
+
if (!row) return null;
|
|
707
|
+
return { rows: clone(row.rows), total: Number(row.total) };
|
|
708
|
+
}
|
|
689
709
|
async listRevisions(obligationId) {
|
|
690
710
|
const result = await this.query(
|
|
691
711
|
`SELECT data FROM adcp_reporting_revisions WHERE obligation_id = $1
|
|
@@ -694,6 +714,16 @@ ${managedDueArm} )
|
|
|
694
714
|
);
|
|
695
715
|
return result.rows.map((row) => clone(row.data));
|
|
696
716
|
}
|
|
717
|
+
async listRevisionMetadata(obligationId, accountId) {
|
|
718
|
+
const result = await this.query(
|
|
719
|
+
`SELECT revision.data - 'rows' AS data FROM adcp_reporting_revisions revision
|
|
720
|
+
JOIN adcp_reporting_obligations obligation ON obligation.obligation_id = revision.obligation_id
|
|
721
|
+
WHERE revision.obligation_id = $1 AND ($2::text IS NULL OR obligation.account_id = $2)
|
|
722
|
+
ORDER BY revision.revision_number, revision.revision_id`,
|
|
723
|
+
[obligationId, accountId ?? null]
|
|
724
|
+
);
|
|
725
|
+
return result.rows.map((row) => clone(row.data));
|
|
726
|
+
}
|
|
697
727
|
async commitAdjustment(adjustment, lease) {
|
|
698
728
|
assertLeaseTarget(adjustment.reporting_obligation_id, lease);
|
|
699
729
|
validateBoundRows(adjustment);
|
|
@@ -757,6 +787,14 @@ ${managedDueArm} )
|
|
|
757
787
|
);
|
|
758
788
|
return result.rows.map((row) => clone(row.data));
|
|
759
789
|
}
|
|
790
|
+
async listAdjustmentMetadata(obligationId) {
|
|
791
|
+
const result = await this.query(
|
|
792
|
+
`SELECT data - 'rows' AS data FROM adcp_reporting_adjustments WHERE obligation_id = $1
|
|
793
|
+
ORDER BY adjustment_number, adjustment_id`,
|
|
794
|
+
[obligationId]
|
|
795
|
+
);
|
|
796
|
+
return result.rows.map((row) => clone(row.data));
|
|
797
|
+
}
|
|
760
798
|
async putConsumerStatus(status) {
|
|
761
799
|
const obligation = await this.getObligation(status.reporting_obligation_id);
|
|
762
800
|
if (!obligation) throw new Error("Reporting consumer status obligation is unavailable");
|
|
@@ -32,6 +32,7 @@ var import_source = require('../source/index.js');
|
|
|
32
32
|
var import_coverage = require('./coverage.js');
|
|
33
33
|
var import_schedule = require('./schedule.js');
|
|
34
34
|
var import_lifecycle = require('./lifecycle.js');
|
|
35
|
+
var import_revision_metadata = require('./revision-metadata.js');
|
|
35
36
|
const DEFAULT_LEASE_MS = 3e5;
|
|
36
37
|
const EXECUTION_DEADLINE_MS = 24e4;
|
|
37
38
|
const DEFAULT_SETTLEMENT_GRACE_MS = 1e4;
|
|
@@ -268,8 +269,8 @@ function createReportingProducer(options) {
|
|
|
268
269
|
);
|
|
269
270
|
}
|
|
270
271
|
}
|
|
271
|
-
const previous = await options.store
|
|
272
|
-
const adjustments = await options.store
|
|
272
|
+
const previous = await (0, import_revision_metadata.listRevisionMetadataFromStore)(options.store, obligation.reporting_obligation_id);
|
|
273
|
+
const adjustments = await (0, import_revision_metadata.listAdjustmentMetadataFromStore)(options.store, obligation.reporting_obligation_id);
|
|
273
274
|
const publicationCount = previous.length + adjustments.length;
|
|
274
275
|
if (publicationCount > 0) {
|
|
275
276
|
const scheduledAt = nextPublicationAt(obligation, publicationCount);
|
|
@@ -28,6 +28,7 @@ import {
|
|
|
28
28
|
reconcileReportingStatusLifecycleV1,
|
|
29
29
|
retryReportingStatusNotificationsV1
|
|
30
30
|
} from "./lifecycle.mjs";
|
|
31
|
+
import { listAdjustmentMetadataFromStore, listRevisionMetadataFromStore } from "./revision-metadata.mjs";
|
|
31
32
|
const DEFAULT_LEASE_MS = 3e5;
|
|
32
33
|
const EXECUTION_DEADLINE_MS = 24e4;
|
|
33
34
|
const DEFAULT_SETTLEMENT_GRACE_MS = 1e4;
|
|
@@ -264,8 +265,8 @@ function createReportingProducer(options) {
|
|
|
264
265
|
);
|
|
265
266
|
}
|
|
266
267
|
}
|
|
267
|
-
const previous = await options.store
|
|
268
|
-
const adjustments = await options.store
|
|
268
|
+
const previous = await listRevisionMetadataFromStore(options.store, obligation.reporting_obligation_id);
|
|
269
|
+
const adjustments = await listAdjustmentMetadataFromStore(options.store, obligation.reporting_obligation_id);
|
|
269
270
|
const publicationCount = previous.length + adjustments.length;
|
|
270
271
|
if (publicationCount > 0) {
|
|
271
272
|
const scheduledAt = nextPublicationAt(obligation, publicationCount);
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReportingLedgerAdjustmentMetadataV1, ReportingLedgerRevisionMetadataV1, ReportingLedgerStore, ReportingRevisionRowsPageV1, ReportingRevisionRowsReadV1 } from './types.mjs';
|
|
2
|
+
/**
|
|
3
|
+
* Row-free revision listing for paths that only need identity, finality,
|
|
4
|
+
* supersession, binding and wire metadata. Prefers the store's
|
|
5
|
+
* `listRevisionMetadata`; a store without it is read through `listRevisions`
|
|
6
|
+
* and its rows are dropped before they reach the caller.
|
|
7
|
+
*/
|
|
8
|
+
export declare function listRevisionMetadataFromStore(store: Pick<ReportingLedgerStore, 'listRevisions' | 'listRevisionMetadata'>, reporting_obligation_id: string): Promise<ReportingLedgerRevisionMetadataV1[]>;
|
|
9
|
+
/** Row-free counterpart of {@link listRevisionMetadataFromStore} for adjustments. */
|
|
10
|
+
export declare function listAdjustmentMetadataFromStore(store: Pick<ReportingLedgerStore, 'listAdjustments' | 'listAdjustmentMetadata'>, reporting_obligation_id: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
|
|
11
|
+
/** Account-scoped revision metadata, preferring the store's row-free read. */
|
|
12
|
+
export declare function getRevisionMetadataFromStore(store: Pick<ReportingLedgerStore, 'getRevision' | 'getRevisionMetadata'>, reporting_revision_id: string, account_id: string): Promise<ReportingLedgerRevisionMetadataV1 | null>;
|
|
13
|
+
/**
|
|
14
|
+
* One page of a revision's rows. Prefers the store's paged reader; otherwise
|
|
15
|
+
* loads the revision through `getRevision` and slices it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readRevisionRowsFromStore(store: Pick<ReportingLedgerStore, 'getRevision' | 'readRevisionRows'>, input: ReportingRevisionRowsReadV1): Promise<ReportingRevisionRowsPageV1 | null>;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { ReportingLedgerAdjustmentMetadataV1, ReportingLedgerRevisionMetadataV1, ReportingLedgerStore, ReportingRevisionRowsPageV1, ReportingRevisionRowsReadV1 } from './types';
|
|
2
|
+
/**
|
|
3
|
+
* Row-free revision listing for paths that only need identity, finality,
|
|
4
|
+
* supersession, binding and wire metadata. Prefers the store's
|
|
5
|
+
* `listRevisionMetadata`; a store without it is read through `listRevisions`
|
|
6
|
+
* and its rows are dropped before they reach the caller.
|
|
7
|
+
*/
|
|
8
|
+
export declare function listRevisionMetadataFromStore(store: Pick<ReportingLedgerStore, 'listRevisions' | 'listRevisionMetadata'>, reporting_obligation_id: string): Promise<ReportingLedgerRevisionMetadataV1[]>;
|
|
9
|
+
/** Row-free counterpart of {@link listRevisionMetadataFromStore} for adjustments. */
|
|
10
|
+
export declare function listAdjustmentMetadataFromStore(store: Pick<ReportingLedgerStore, 'listAdjustments' | 'listAdjustmentMetadata'>, reporting_obligation_id: string): Promise<ReportingLedgerAdjustmentMetadataV1[]>;
|
|
11
|
+
/** Account-scoped revision metadata, preferring the store's row-free read. */
|
|
12
|
+
export declare function getRevisionMetadataFromStore(store: Pick<ReportingLedgerStore, 'getRevision' | 'getRevisionMetadata'>, reporting_revision_id: string, account_id: string): Promise<ReportingLedgerRevisionMetadataV1 | null>;
|
|
13
|
+
/**
|
|
14
|
+
* One page of a revision's rows. Prefers the store's paged reader; otherwise
|
|
15
|
+
* loads the revision through `getRevision` and slices it.
|
|
16
|
+
*/
|
|
17
|
+
export declare function readRevisionRowsFromStore(store: Pick<ReportingLedgerStore, 'getRevision' | 'readRevisionRows'>, input: ReportingRevisionRowsReadV1): Promise<ReportingRevisionRowsPageV1 | null>;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
var revision_metadata_exports = {};
|
|
20
|
+
__export(revision_metadata_exports, {
|
|
21
|
+
getRevisionMetadataFromStore: () => getRevisionMetadataFromStore,
|
|
22
|
+
listAdjustmentMetadataFromStore: () => listAdjustmentMetadataFromStore,
|
|
23
|
+
listRevisionMetadataFromStore: () => listRevisionMetadataFromStore,
|
|
24
|
+
readRevisionRowsFromStore: () => readRevisionRowsFromStore
|
|
25
|
+
});
|
|
26
|
+
module.exports = __toCommonJS(revision_metadata_exports);
|
|
27
|
+
async function listRevisionMetadataFromStore(store, reporting_obligation_id) {
|
|
28
|
+
if (typeof store.listRevisionMetadata === "function") {
|
|
29
|
+
return store.listRevisionMetadata(reporting_obligation_id);
|
|
30
|
+
}
|
|
31
|
+
const revisions = await store.listRevisions(reporting_obligation_id);
|
|
32
|
+
return revisions.map(({ rows: _rows, ...metadata }) => metadata);
|
|
33
|
+
}
|
|
34
|
+
async function listAdjustmentMetadataFromStore(store, reporting_obligation_id) {
|
|
35
|
+
if (typeof store.listAdjustmentMetadata === "function") {
|
|
36
|
+
return store.listAdjustmentMetadata(reporting_obligation_id);
|
|
37
|
+
}
|
|
38
|
+
const adjustments = await store.listAdjustments(reporting_obligation_id);
|
|
39
|
+
return adjustments.map(({ rows: _rows, ...metadata }) => metadata);
|
|
40
|
+
}
|
|
41
|
+
async function getRevisionMetadataFromStore(store, reporting_revision_id, account_id) {
|
|
42
|
+
if (typeof store.getRevisionMetadata === "function") {
|
|
43
|
+
return store.getRevisionMetadata(reporting_revision_id, account_id);
|
|
44
|
+
}
|
|
45
|
+
const revision = await store.getRevision(reporting_revision_id, account_id);
|
|
46
|
+
if (!revision) return null;
|
|
47
|
+
const { rows: _rows, ...metadata } = revision;
|
|
48
|
+
return metadata;
|
|
49
|
+
}
|
|
50
|
+
async function readRevisionRowsFromStore(store, input) {
|
|
51
|
+
if (!Number.isSafeInteger(input.offset) || input.offset < 0) {
|
|
52
|
+
throw new RangeError("Reporting row page offset must be a non-negative integer");
|
|
53
|
+
}
|
|
54
|
+
if (!Number.isSafeInteger(input.limit) || input.limit < 1) {
|
|
55
|
+
throw new RangeError("Reporting row page limit must be a positive integer");
|
|
56
|
+
}
|
|
57
|
+
if (typeof store.readRevisionRows === "function") return store.readRevisionRows(input);
|
|
58
|
+
const revision = await store.getRevision(input.reporting_revision_id, input.account_id);
|
|
59
|
+
if (!revision) return null;
|
|
60
|
+
return {
|
|
61
|
+
rows: revision.rows.slice(input.offset, input.offset + input.limit),
|
|
62
|
+
total: revision.rows.length
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
66
|
+
0 && (module.exports = {
|
|
67
|
+
getRevisionMetadataFromStore,
|
|
68
|
+
listAdjustmentMetadataFromStore,
|
|
69
|
+
listRevisionMetadataFromStore,
|
|
70
|
+
readRevisionRowsFromStore
|
|
71
|
+
});
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
async function listRevisionMetadataFromStore(store, reporting_obligation_id) {
|
|
2
|
+
if (typeof store.listRevisionMetadata === "function") {
|
|
3
|
+
return store.listRevisionMetadata(reporting_obligation_id);
|
|
4
|
+
}
|
|
5
|
+
const revisions = await store.listRevisions(reporting_obligation_id);
|
|
6
|
+
return revisions.map(({ rows: _rows, ...metadata }) => metadata);
|
|
7
|
+
}
|
|
8
|
+
async function listAdjustmentMetadataFromStore(store, reporting_obligation_id) {
|
|
9
|
+
if (typeof store.listAdjustmentMetadata === "function") {
|
|
10
|
+
return store.listAdjustmentMetadata(reporting_obligation_id);
|
|
11
|
+
}
|
|
12
|
+
const adjustments = await store.listAdjustments(reporting_obligation_id);
|
|
13
|
+
return adjustments.map(({ rows: _rows, ...metadata }) => metadata);
|
|
14
|
+
}
|
|
15
|
+
async function getRevisionMetadataFromStore(store, reporting_revision_id, account_id) {
|
|
16
|
+
if (typeof store.getRevisionMetadata === "function") {
|
|
17
|
+
return store.getRevisionMetadata(reporting_revision_id, account_id);
|
|
18
|
+
}
|
|
19
|
+
const revision = await store.getRevision(reporting_revision_id, account_id);
|
|
20
|
+
if (!revision) return null;
|
|
21
|
+
const { rows: _rows, ...metadata } = revision;
|
|
22
|
+
return metadata;
|
|
23
|
+
}
|
|
24
|
+
async function readRevisionRowsFromStore(store, input) {
|
|
25
|
+
if (!Number.isSafeInteger(input.offset) || input.offset < 0) {
|
|
26
|
+
throw new RangeError("Reporting row page offset must be a non-negative integer");
|
|
27
|
+
}
|
|
28
|
+
if (!Number.isSafeInteger(input.limit) || input.limit < 1) {
|
|
29
|
+
throw new RangeError("Reporting row page limit must be a positive integer");
|
|
30
|
+
}
|
|
31
|
+
if (typeof store.readRevisionRows === "function") return store.readRevisionRows(input);
|
|
32
|
+
const revision = await store.getRevision(input.reporting_revision_id, input.account_id);
|
|
33
|
+
if (!revision) return null;
|
|
34
|
+
return {
|
|
35
|
+
rows: revision.rows.slice(input.offset, input.offset + input.limit),
|
|
36
|
+
total: revision.rows.length
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
export {
|
|
40
|
+
getRevisionMetadataFromStore,
|
|
41
|
+
listAdjustmentMetadataFromStore,
|
|
42
|
+
listRevisionMetadataFromStore,
|
|
43
|
+
readRevisionRowsFromStore
|
|
44
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Canonical JSONL row encoding for reporting revisions (shared SDK
|
|
3
|
+
* persistence contract, `reporting-row-storage` v1).
|
|
4
|
+
*
|
|
5
|
+
* Rows are stored as `JCS(row) + "\n"` in ordinal order. JCS escapes newline
|
|
6
|
+
* characters inside strings, so the `0x0A` byte only ever separates rows.
|
|
7
|
+
* Rows are grouped into segments (the unit of verification and paged reads)
|
|
8
|
+
* and chunks (the unit of storage). Boundaries are fixed by the contract so
|
|
9
|
+
* every SDK produces byte-identical chunks and manifests for the same rows:
|
|
10
|
+
*
|
|
11
|
+
* - a new chunk starts when the current chunk holds
|
|
12
|
+
* {@link REPORTING_ROW_CHUNK_MAX_ROWS} rows, or when appending the next row
|
|
13
|
+
* would exceed {@link REPORTING_ROW_CHUNK_MAX_BYTES} canonical bytes;
|
|
14
|
+
* - segments restart at each chunk boundary and close every
|
|
15
|
+
* {@link REPORTING_ROW_SEGMENT_MAX_ROWS} rows.
|
|
16
|
+
*
|
|
17
|
+
* A row larger than the chunk byte limit forms its own segment and chunk.
|
|
18
|
+
* Digests always cover uncompressed canonical bytes.
|
|
19
|
+
*/
|
|
20
|
+
export declare const REPORTING_ROW_ENCODING_V1: "adcp_canonical_jsonl_v1";
|
|
21
|
+
export declare const REPORTING_ROW_SEGMENT_MAX_ROWS = 500;
|
|
22
|
+
export declare const REPORTING_ROW_CHUNK_MAX_SEGMENTS = 20;
|
|
23
|
+
export declare const REPORTING_ROW_CHUNK_MAX_ROWS: number;
|
|
24
|
+
export declare const REPORTING_ROW_CHUNK_MAX_BYTES: number;
|
|
25
|
+
export type ReportingRowEncodingErrorCode = 'INVALID_ROW' | 'MANIFEST_MISMATCH' | 'CHUNK_INTEGRITY_FAILED' | 'ENVELOPE_INTEGRITY_FAILED';
|
|
26
|
+
export declare class ReportingRowEncodingError extends Error {
|
|
27
|
+
readonly code: ReportingRowEncodingErrorCode;
|
|
28
|
+
constructor(code: ReportingRowEncodingErrorCode, detail: string);
|
|
29
|
+
}
|
|
30
|
+
export declare function isReportingRowEncodingError(error: unknown): error is ReportingRowEncodingError;
|
|
31
|
+
export interface ReportingRowSegmentManifestV1 {
|
|
32
|
+
first_ordinal: number;
|
|
33
|
+
row_count: number;
|
|
34
|
+
/** Offset of the segment within its chunk's uncompressed canonical bytes. */
|
|
35
|
+
byte_offset: number;
|
|
36
|
+
byte_count: number;
|
|
37
|
+
sha256: string;
|
|
38
|
+
}
|
|
39
|
+
export interface ReportingRowChunkManifestV1 {
|
|
40
|
+
chunk_index: number;
|
|
41
|
+
first_ordinal: number;
|
|
42
|
+
row_count: number;
|
|
43
|
+
byte_count: number;
|
|
44
|
+
sha256: string;
|
|
45
|
+
segments: ReportingRowSegmentManifestV1[];
|
|
46
|
+
}
|
|
47
|
+
export interface ReportingRowChunkV1 {
|
|
48
|
+
manifest: ReportingRowChunkManifestV1;
|
|
49
|
+
/** Uncompressed canonical JSONL bytes. */
|
|
50
|
+
bytes: Buffer;
|
|
51
|
+
}
|
|
52
|
+
export interface ReportingEncodedRowsV1 {
|
|
53
|
+
encoding: typeof REPORTING_ROW_ENCODING_V1;
|
|
54
|
+
rowCount: number;
|
|
55
|
+
/** Total canonical JSONL bytes across all chunks. */
|
|
56
|
+
byteCount: number;
|
|
57
|
+
chunks: ReportingRowChunkV1[];
|
|
58
|
+
manifests: ReportingRowChunkManifestV1[];
|
|
59
|
+
/** `sha256(JCS(manifests))`; bound immutably on the revision header. */
|
|
60
|
+
rowManifestSha256: string;
|
|
61
|
+
}
|
|
62
|
+
export interface ReportingRevisionEnvelopeInputV1 {
|
|
63
|
+
reporting_revision_id: string;
|
|
64
|
+
row_count: number;
|
|
65
|
+
control_totals: readonly unknown[];
|
|
66
|
+
}
|
|
67
|
+
export interface ReportingRevisionEnvelopeDigestV1 {
|
|
68
|
+
sha256: string;
|
|
69
|
+
/** Byte length of the canonical envelope; equals `binding.byteCount`. */
|
|
70
|
+
byteCount: number;
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Canonicalize one row for storage. Refuses values whose canonical bytes are
|
|
74
|
+
* not portable across conforming JCS implementations: non-plain objects,
|
|
75
|
+
* non-finite numbers, integers outside ±(2^53 − 1), and lone surrogates.
|
|
76
|
+
*/
|
|
77
|
+
export declare function canonicalReportingRowV1(row: unknown, ordinal?: number): string;
|
|
78
|
+
/** Encode rows into contract-fixed canonical JSONL chunks and manifests. */
|
|
79
|
+
export declare function encodeReportingRowsV1(rows: readonly unknown[]): ReportingEncodedRowsV1;
|
|
80
|
+
/** `sha256(JCS(manifests))` over the ordered chunk manifests, locators excluded. */
|
|
81
|
+
export declare function reportingRowManifestSha256V1(manifests: readonly ReportingRowChunkManifestV1[]): string;
|
|
82
|
+
/**
|
|
83
|
+
* Verify that a manifest set is internally consistent and matches the
|
|
84
|
+
* header's committed `row_manifest_sha256` and `row_count`. Ordinals must be
|
|
85
|
+
* contiguous from zero, chunk and segment boundaries must follow the contract
|
|
86
|
+
* limits, and segment byte ranges must tile their chunk exactly.
|
|
87
|
+
*/
|
|
88
|
+
export declare function verifyReportingRowManifestsV1(manifests: readonly ReportingRowChunkManifestV1[], expected: {
|
|
89
|
+
rowCount: number;
|
|
90
|
+
rowManifestSha256: string;
|
|
91
|
+
}): void;
|
|
92
|
+
/**
|
|
93
|
+
* Verify a whole chunk's canonical bytes against its manifest: total digest,
|
|
94
|
+
* byte count, and every segment's digest and line count.
|
|
95
|
+
*/
|
|
96
|
+
export declare function verifyReportingRowChunkV1(manifest: ReportingRowChunkManifestV1, bytes: Uint8Array): void;
|
|
97
|
+
/**
|
|
98
|
+
* Verify and decode a contiguous range of segments `[fromSegment, toSegment]`
|
|
99
|
+
* (inclusive). `bytes` must hold exactly those segments' canonical bytes,
|
|
100
|
+
* starting at the first segment's `byte_offset` — the shape returned by a
|
|
101
|
+
* ranged object read. Rows are released only after every segment verifies.
|
|
102
|
+
*/
|
|
103
|
+
export declare function decodeVerifiedReportingRowSegmentsV1(manifest: ReportingRowChunkManifestV1, segmentRange: readonly [fromSegment: number, toSegment: number], bytes: Uint8Array): Record<string, unknown>[];
|
|
104
|
+
/**
|
|
105
|
+
* Streaming hasher for the protocol revision binding
|
|
106
|
+
* `sha256(JCS({reporting_revision_id, row_count, control_totals, reporting_rows}))`.
|
|
107
|
+
* Feed verified chunk bytes in order; rows are never parsed.
|
|
108
|
+
*/
|
|
109
|
+
export declare function createReportingRevisionEnvelopeHasherV1(envelope: ReportingRevisionEnvelopeInputV1): {
|
|
110
|
+
update(chunkBytes: Uint8Array): void;
|
|
111
|
+
digest(): ReportingRevisionEnvelopeDigestV1;
|
|
112
|
+
};
|
|
113
|
+
/** Envelope digest over already-encoded chunk bytes. */
|
|
114
|
+
export declare function reportingRevisionEnvelopeDigestV1(envelope: ReportingRevisionEnvelopeInputV1, chunks: Iterable<Uint8Array>): ReportingRevisionEnvelopeDigestV1;
|
|
115
|
+
/** Streaming hasher for digest profile `rows_v1`: `sha256(JCS(rows))`. */
|
|
116
|
+
export declare function createReportingRowsOnlyHasherV1(rowCount: number): {
|
|
117
|
+
update(chunkBytes: Uint8Array): void;
|
|
118
|
+
digest(): ReportingRevisionEnvelopeDigestV1;
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* Throw unless the canonical chunks reproduce the header's committed revision
|
|
122
|
+
* binding. Used at write time (proof that chunks and envelope agree) and for
|
|
123
|
+
* full-revision reads.
|
|
124
|
+
*/
|
|
125
|
+
export declare function assertReportingRevisionEnvelopeV1(envelope: ReportingRevisionEnvelopeInputV1, chunks: Iterable<Uint8Array>, expected: {
|
|
126
|
+
sha256: string;
|
|
127
|
+
byteCount?: number;
|
|
128
|
+
}): void;
|