@ai-matrx/records 0.52.0 → 0.54.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.
@@ -2706,6 +2706,11 @@ declare const STORE_DOORS: readonly [{
2706
2706
  readonly args: "p_organization_id uuid DEFAULT NULL::uuid";
2707
2707
  readonly returns: "boolean";
2708
2708
  readonly security: "invoker";
2709
+ }, {
2710
+ readonly name: "store_off_sentence";
2711
+ readonly args: "p_organization_id uuid";
2712
+ readonly returns: "text";
2713
+ readonly security: "invoker";
2709
2714
  }, {
2710
2715
  readonly name: "subscription_cadences";
2711
2716
  readonly args: "p_organization_id uuid";
@@ -4053,6 +4058,51 @@ interface TableCapacity {
4053
4058
  /** The knob that decides the ceiling, named so a person can act on it. */
4054
4059
  knob: string;
4055
4060
  }
4061
+ /**
4062
+ * WHAT ONE PASS OF `custom.table_archive` ANSWERS WITH — the numbers a screen
4063
+ * needs to draw a bar and write a sentence, instead of a spinner and an
4064
+ * SQLSTATE (VERIFIER-10 F3, VERIFIER-11 F3).
4065
+ *
4066
+ * Archiving a table is a JOB, NOT A STATEMENT. `custom.record_delete` on a
4067
+ * Table recurses through everything the Table contains inside one transaction,
4068
+ * which is unbounded by construction: at 1,430 records it dies on `57014`,
4069
+ * "canceling statement due to statement timeout", and nothing is changed. The
4070
+ * remedy for a thing that cannot finish in one statement is more statements,
4071
+ * never a longer one — so the caller loops, passing its own `chunk`, until
4072
+ * `done`.
4073
+ *
4074
+ * IT IS RESUMABLE BECAUSE IT IS STATELESS. There is no job row to lose:
4075
+ * `remaining` is read off the records themselves on every call, so a browser
4076
+ * closed halfway, a failed pass or a deploy mid-run all leave a table that is
4077
+ * half archived and a next call that picks up exactly where the last stopped.
4078
+ * Which is why a screen driving this may NEVER say "nothing was changed" after
4079
+ * a pass that moved rows — `archived_total` is what really landed.
4080
+ *
4081
+ * NOTHING IS DELETED. Every row goes through `custom.record_delete`, so every
4082
+ * guard, history capture and outbox row still happens and `recordRestore`
4083
+ * still brings any of them back.
4084
+ */
4085
+ interface TableArchiveProgress {
4086
+ table_id: Uuid;
4087
+ /** The table's own name, so a sentence can use it rather than an id. */
4088
+ table_name: string;
4089
+ /** What THIS pass archived. */
4090
+ archived: number;
4091
+ /** Records of this table still live. Zero is the end of the row work. */
4092
+ remaining: number;
4093
+ /** Records this table has ever held: `remaining` + `archived_total`. */
4094
+ total: number;
4095
+ /** Records of this table already archived, across every pass ever made. */
4096
+ archived_total: number;
4097
+ /** Whether the Table record itself has been archived. */
4098
+ table_archived: boolean;
4099
+ /** Nothing live is left to do. The caller's loop ends here. */
4100
+ done: boolean;
4101
+ /** The chunk the door actually took on — it clamps what it is handed. */
4102
+ chunk: number;
4103
+ /** The store's own sentence about this pass, in the product's voice. */
4104
+ message: string;
4105
+ }
4056
4106
 
4057
4107
  /** FLD-3. A constraint attached to a Field. A Rule, never a behaviour. */
4058
4108
  interface FieldRule {
@@ -4349,6 +4399,25 @@ interface FieldPatch {
4349
4399
  * them changed — a roll-up is always `read`.
4350
4400
  */
4351
4401
  compute_on?: ComputeOn;
4402
+ /**
4403
+ * FLD-11 / REC-15. RE-AIMING A WORKED-OUT COLUMN: the expression, in the same
4404
+ * shape a Rule uses and read by the same evaluator — `{"op":"concat","args":
4405
+ * [{"field":"note"}]}`. Every `{"field": …}` in it names a live Field of this
4406
+ * organization, or `custom._field_document_for` refuses the whole patch by
4407
+ * name and writes nothing.
4408
+ *
4409
+ * `custom.field_update` carries this in its BEHAVIOUR arm — the arm a type
4410
+ * word opens — so send it WITH the word for what the column is
4411
+ * (`type: "formula"`, or `parity_type` / `plain`). The door's spec builder
4412
+ * reads `coalesce(p_patch -> 'expr', v_old -> 'config' -> 'expr')`, so a
4413
+ * re-type that does not carry one deliberately keeps the expression the
4414
+ * column already had; the settings arm has no `expr` key at all, so `expr`
4415
+ * alone is not a change this door makes. `STORE-TAILS-2` asked for the field
4416
+ * because the one client that needed to re-aim an existing formula had no
4417
+ * typed way to say it and reached for `custom.record_update`, which writes the
4418
+ * Field document under the guards rather than through them.
4419
+ */
4420
+ expr?: Record<string, unknown>;
4352
4421
  }
4353
4422
 
4354
4423
  /** One option, as `_choices` names it and as `optionsOf` returns it. */
@@ -7427,13 +7496,52 @@ interface RecordsClient {
7427
7496
  /** Leave it out and the last writer wins; supply it and a loser is TOLD. */
7428
7497
  expectedVersion?: number;
7429
7498
  }): Promise<RecordsResult<number>>;
7430
- /** REC-23. Soft, and reversible within `retention`. */
7499
+ /**
7500
+ * REC-23. Soft, and reversible within `retention`.
7501
+ *
7502
+ * 🚨 NOT FOR A TABLE. A Table is a record, so this door accepts one — and
7503
+ * then recurses through every record the Table contains inside a single
7504
+ * transaction, which is unbounded by construction and dies on `57014` at a
7505
+ * size the product's own import reaches in half a minute. Use
7506
+ * `tableArchive` below, which does the same work in resumable passes.
7507
+ */
7431
7508
  recordDelete(args: {
7432
7509
  record_id: Uuid;
7433
7510
  }): Promise<RecordsResult<Timestamp>>;
7434
7511
  recordRestore(args: {
7435
7512
  record_id: Uuid;
7436
7513
  }): Promise<RecordsResult<void>>;
7514
+ /**
7515
+ * ARCHIVING A WHOLE TABLE — ONE PASS OF IT (VERIFIER-11 F3).
7516
+ *
7517
+ * One call archives at most `chunk` of the table's live records through
7518
+ * `custom.record_delete` (so every guard, history capture and outbox row
7519
+ * still happens; nothing is hard-deleted) and comes back with the numbers a
7520
+ * screen draws progress from. The CALLER LOOPS until `done` — that loop is
7521
+ * the fix, because the one thing a single statement cannot be made to do is
7522
+ * finish.
7523
+ *
7524
+ * `chunk: 0` changes nothing and only reports, so a screen can say "1,430
7525
+ * records will be archived" BEFORE a person commits to it. `includeTable:
7526
+ * false` empties the table and leaves it standing.
7527
+ *
7528
+ * RESUMABLE, WITHOUT A JOB ROW: what remains is read off the records
7529
+ * themselves every call. A pass that fails, a closed tab or a deploy mid-run
7530
+ * leaves a half-archived table and a next call that continues from exactly
7531
+ * there. A caller must therefore never report "nothing happened" after a
7532
+ * failed pass — `archived_total` says what really landed.
7533
+ */
7534
+ tableArchive(args: {
7535
+ table_id: Uuid;
7536
+ /**
7537
+ * How many records this pass takes on. The door clamps it; it answers with what it
7538
+ * took. Default 50 — measured: ~35ms a record against an 8s statement timeout, so
7539
+ * 200 dies on `57014` and is the original defect one level up.
7540
+ */
7541
+ chunk?: number;
7542
+ /** Archive the Table record itself once nothing live is left in it. Default true. */
7543
+ includeTable?: boolean;
7544
+ }): Promise<RecordsResult<TableArchiveProgress>>;
7437
7545
  recordRead(args: {
7438
7546
  record_id: Uuid;
7439
7547
  withComputed?: boolean;
@@ -8927,6 +9035,68 @@ interface UseRecordMutation {
8927
9035
  }
8928
9036
  /** Writes, with optimistic concurrency surfaced instead of swallowed. */
8929
9037
  declare function useRecordMutation(): UseRecordMutation;
9038
+ /**
9039
+ * GETTING RID OF A WHOLE TABLE — the loop, once, for every screen (VERIFIER-11 F3).
9040
+ *
9041
+ * `useRecordMutation().remove` is right for a record and WRONG for a Table:
9042
+ * `custom.record_delete` aimed at a Table recurses through everything it
9043
+ * contains inside one transaction, so on 1,430 records — a size the product's
9044
+ * own import reaches in half a minute — it died twelve seconds in on `57014`,
9045
+ * "canceling statement due to statement timeout", and the screen told the
9046
+ * person nothing had changed and to "try a smaller page". There is no page.
9047
+ *
9048
+ * So archiving a table is a JOB: this hook makes the passes, holds the numbers
9049
+ * the store answers each one with, and stops on `done`.
9050
+ *
9051
+ * WHAT MAKES IT RESUMABLE is that nothing here is the state of the run — the
9052
+ * store reads what remains off the records themselves every call. A refused
9053
+ * pass, a `stop()`, a closed tab or a reload all leave `interrupted` true and a
9054
+ * `carryOn()` that continues from exactly where the last pass stopped. Which is
9055
+ * also why a screen driving this may never say "nothing was changed" after a
9056
+ * failure: `progress.archived_total` is what actually landed, and it is the
9057
+ * number the person is owed.
9058
+ */
9059
+ interface UseTableArchive {
9060
+ /** The numbers from the last pass or preview. Null until something has been asked. */
9061
+ progress: TableArchiveProgress | null;
9062
+ /** A loop is in flight. */
9063
+ running: boolean;
9064
+ /** Passes made since the last `start()`. */
9065
+ passes: number;
9066
+ /**
9067
+ * The pass size in use. It STARTS at `chunk` and HALVES whenever the store
9068
+ * runs out of time, so a screen can say the run slowed down rather than
9069
+ * letting it look stuck. Never below ten: at that point the store is not slow,
9070
+ * it is refusing, and a loop that kept shrinking would hide it.
9071
+ */
9072
+ chunkInUse: number;
9073
+ /**
9074
+ * The loop backed the pass size off because the store ran out of time. An
9075
+ * automatic intervention ANNOUNCES ITSELF: a run that quietly went four times
9076
+ * slower would read as a stuck screen.
9077
+ */
9078
+ slowedDown: boolean;
9079
+ /** The refusal that stopped the loop. The work already done still stands. */
9080
+ error: RecordsError | null;
9081
+ /**
9082
+ * The loop ended with records still live — because a pass was refused or
9083
+ * because `stop()` was called. It is the screen's cue to offer carrying on
9084
+ * rather than to claim a finished or a failed run.
9085
+ */
9086
+ interrupted: boolean;
9087
+ /** Ask what would happen and change NOTHING, so a person sees the number first. */
9088
+ preview: () => Promise<TableArchiveProgress | null>;
9089
+ /** Run passes until done, refused, or stopped. */
9090
+ start: () => Promise<TableArchiveProgress | null>;
9091
+ /** Same loop, said in the word a screen uses after an interruption. */
9092
+ carryOn: () => Promise<TableArchiveProgress | null>;
9093
+ /** Cut cleanly after the pass in flight. Never mid-pass: a pass is one transaction. */
9094
+ stop: () => void;
9095
+ }
9096
+ declare function useTableArchive(tableId: Uuid, options?: {
9097
+ chunk?: number;
9098
+ includeTable?: boolean;
9099
+ }): UseTableArchive;
8930
9100
  interface UseFieldMutation {
8931
9101
  /** Add a column. One call; the store decides what the parity type is made of. */
8932
9102
  declare: (args: {
@@ -9016,4 +9186,4 @@ declare function useFieldMutation(): UseFieldMutation;
9016
9186
  */
9017
9187
  declare function useMergeField(key: string | null, state?: Record<string, unknown>): MergeFieldResolution | null;
9018
9188
 
9019
- export { ABSENCE_REASONS, ACTOR_VOCABULARY, ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DECLARABLE_FIELD_KINDS, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DeclarableFieldKind, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, PORTAL_ARCHIVE_FILTERS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordFilter, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isOwnOp, isPortalArchiveFilter, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, rememberedOpCount, sameDocument, scopeChip, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTables };
9189
+ export { ABSENCE_REASONS, ACTOR_VOCABULARY, ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DECLARABLE_FIELD_KINDS, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DeclarableFieldKind, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, PORTAL_ARCHIVE_FILTERS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordFilter, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableArchiveProgress, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type UseTableArchive, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isOwnOp, isPortalArchiveFilter, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, rememberedOpCount, sameDocument, scopeChip, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTableArchive, useTables };
@@ -2706,6 +2706,11 @@ declare const STORE_DOORS: readonly [{
2706
2706
  readonly args: "p_organization_id uuid DEFAULT NULL::uuid";
2707
2707
  readonly returns: "boolean";
2708
2708
  readonly security: "invoker";
2709
+ }, {
2710
+ readonly name: "store_off_sentence";
2711
+ readonly args: "p_organization_id uuid";
2712
+ readonly returns: "text";
2713
+ readonly security: "invoker";
2709
2714
  }, {
2710
2715
  readonly name: "subscription_cadences";
2711
2716
  readonly args: "p_organization_id uuid";
@@ -4053,6 +4058,51 @@ interface TableCapacity {
4053
4058
  /** The knob that decides the ceiling, named so a person can act on it. */
4054
4059
  knob: string;
4055
4060
  }
4061
+ /**
4062
+ * WHAT ONE PASS OF `custom.table_archive` ANSWERS WITH — the numbers a screen
4063
+ * needs to draw a bar and write a sentence, instead of a spinner and an
4064
+ * SQLSTATE (VERIFIER-10 F3, VERIFIER-11 F3).
4065
+ *
4066
+ * Archiving a table is a JOB, NOT A STATEMENT. `custom.record_delete` on a
4067
+ * Table recurses through everything the Table contains inside one transaction,
4068
+ * which is unbounded by construction: at 1,430 records it dies on `57014`,
4069
+ * "canceling statement due to statement timeout", and nothing is changed. The
4070
+ * remedy for a thing that cannot finish in one statement is more statements,
4071
+ * never a longer one — so the caller loops, passing its own `chunk`, until
4072
+ * `done`.
4073
+ *
4074
+ * IT IS RESUMABLE BECAUSE IT IS STATELESS. There is no job row to lose:
4075
+ * `remaining` is read off the records themselves on every call, so a browser
4076
+ * closed halfway, a failed pass or a deploy mid-run all leave a table that is
4077
+ * half archived and a next call that picks up exactly where the last stopped.
4078
+ * Which is why a screen driving this may NEVER say "nothing was changed" after
4079
+ * a pass that moved rows — `archived_total` is what really landed.
4080
+ *
4081
+ * NOTHING IS DELETED. Every row goes through `custom.record_delete`, so every
4082
+ * guard, history capture and outbox row still happens and `recordRestore`
4083
+ * still brings any of them back.
4084
+ */
4085
+ interface TableArchiveProgress {
4086
+ table_id: Uuid;
4087
+ /** The table's own name, so a sentence can use it rather than an id. */
4088
+ table_name: string;
4089
+ /** What THIS pass archived. */
4090
+ archived: number;
4091
+ /** Records of this table still live. Zero is the end of the row work. */
4092
+ remaining: number;
4093
+ /** Records this table has ever held: `remaining` + `archived_total`. */
4094
+ total: number;
4095
+ /** Records of this table already archived, across every pass ever made. */
4096
+ archived_total: number;
4097
+ /** Whether the Table record itself has been archived. */
4098
+ table_archived: boolean;
4099
+ /** Nothing live is left to do. The caller's loop ends here. */
4100
+ done: boolean;
4101
+ /** The chunk the door actually took on — it clamps what it is handed. */
4102
+ chunk: number;
4103
+ /** The store's own sentence about this pass, in the product's voice. */
4104
+ message: string;
4105
+ }
4056
4106
 
4057
4107
  /** FLD-3. A constraint attached to a Field. A Rule, never a behaviour. */
4058
4108
  interface FieldRule {
@@ -4349,6 +4399,25 @@ interface FieldPatch {
4349
4399
  * them changed — a roll-up is always `read`.
4350
4400
  */
4351
4401
  compute_on?: ComputeOn;
4402
+ /**
4403
+ * FLD-11 / REC-15. RE-AIMING A WORKED-OUT COLUMN: the expression, in the same
4404
+ * shape a Rule uses and read by the same evaluator — `{"op":"concat","args":
4405
+ * [{"field":"note"}]}`. Every `{"field": …}` in it names a live Field of this
4406
+ * organization, or `custom._field_document_for` refuses the whole patch by
4407
+ * name and writes nothing.
4408
+ *
4409
+ * `custom.field_update` carries this in its BEHAVIOUR arm — the arm a type
4410
+ * word opens — so send it WITH the word for what the column is
4411
+ * (`type: "formula"`, or `parity_type` / `plain`). The door's spec builder
4412
+ * reads `coalesce(p_patch -> 'expr', v_old -> 'config' -> 'expr')`, so a
4413
+ * re-type that does not carry one deliberately keeps the expression the
4414
+ * column already had; the settings arm has no `expr` key at all, so `expr`
4415
+ * alone is not a change this door makes. `STORE-TAILS-2` asked for the field
4416
+ * because the one client that needed to re-aim an existing formula had no
4417
+ * typed way to say it and reached for `custom.record_update`, which writes the
4418
+ * Field document under the guards rather than through them.
4419
+ */
4420
+ expr?: Record<string, unknown>;
4352
4421
  }
4353
4422
 
4354
4423
  /** One option, as `_choices` names it and as `optionsOf` returns it. */
@@ -7427,13 +7496,52 @@ interface RecordsClient {
7427
7496
  /** Leave it out and the last writer wins; supply it and a loser is TOLD. */
7428
7497
  expectedVersion?: number;
7429
7498
  }): Promise<RecordsResult<number>>;
7430
- /** REC-23. Soft, and reversible within `retention`. */
7499
+ /**
7500
+ * REC-23. Soft, and reversible within `retention`.
7501
+ *
7502
+ * 🚨 NOT FOR A TABLE. A Table is a record, so this door accepts one — and
7503
+ * then recurses through every record the Table contains inside a single
7504
+ * transaction, which is unbounded by construction and dies on `57014` at a
7505
+ * size the product's own import reaches in half a minute. Use
7506
+ * `tableArchive` below, which does the same work in resumable passes.
7507
+ */
7431
7508
  recordDelete(args: {
7432
7509
  record_id: Uuid;
7433
7510
  }): Promise<RecordsResult<Timestamp>>;
7434
7511
  recordRestore(args: {
7435
7512
  record_id: Uuid;
7436
7513
  }): Promise<RecordsResult<void>>;
7514
+ /**
7515
+ * ARCHIVING A WHOLE TABLE — ONE PASS OF IT (VERIFIER-11 F3).
7516
+ *
7517
+ * One call archives at most `chunk` of the table's live records through
7518
+ * `custom.record_delete` (so every guard, history capture and outbox row
7519
+ * still happens; nothing is hard-deleted) and comes back with the numbers a
7520
+ * screen draws progress from. The CALLER LOOPS until `done` — that loop is
7521
+ * the fix, because the one thing a single statement cannot be made to do is
7522
+ * finish.
7523
+ *
7524
+ * `chunk: 0` changes nothing and only reports, so a screen can say "1,430
7525
+ * records will be archived" BEFORE a person commits to it. `includeTable:
7526
+ * false` empties the table and leaves it standing.
7527
+ *
7528
+ * RESUMABLE, WITHOUT A JOB ROW: what remains is read off the records
7529
+ * themselves every call. A pass that fails, a closed tab or a deploy mid-run
7530
+ * leaves a half-archived table and a next call that continues from exactly
7531
+ * there. A caller must therefore never report "nothing happened" after a
7532
+ * failed pass — `archived_total` says what really landed.
7533
+ */
7534
+ tableArchive(args: {
7535
+ table_id: Uuid;
7536
+ /**
7537
+ * How many records this pass takes on. The door clamps it; it answers with what it
7538
+ * took. Default 50 — measured: ~35ms a record against an 8s statement timeout, so
7539
+ * 200 dies on `57014` and is the original defect one level up.
7540
+ */
7541
+ chunk?: number;
7542
+ /** Archive the Table record itself once nothing live is left in it. Default true. */
7543
+ includeTable?: boolean;
7544
+ }): Promise<RecordsResult<TableArchiveProgress>>;
7437
7545
  recordRead(args: {
7438
7546
  record_id: Uuid;
7439
7547
  withComputed?: boolean;
@@ -8927,6 +9035,68 @@ interface UseRecordMutation {
8927
9035
  }
8928
9036
  /** Writes, with optimistic concurrency surfaced instead of swallowed. */
8929
9037
  declare function useRecordMutation(): UseRecordMutation;
9038
+ /**
9039
+ * GETTING RID OF A WHOLE TABLE — the loop, once, for every screen (VERIFIER-11 F3).
9040
+ *
9041
+ * `useRecordMutation().remove` is right for a record and WRONG for a Table:
9042
+ * `custom.record_delete` aimed at a Table recurses through everything it
9043
+ * contains inside one transaction, so on 1,430 records — a size the product's
9044
+ * own import reaches in half a minute — it died twelve seconds in on `57014`,
9045
+ * "canceling statement due to statement timeout", and the screen told the
9046
+ * person nothing had changed and to "try a smaller page". There is no page.
9047
+ *
9048
+ * So archiving a table is a JOB: this hook makes the passes, holds the numbers
9049
+ * the store answers each one with, and stops on `done`.
9050
+ *
9051
+ * WHAT MAKES IT RESUMABLE is that nothing here is the state of the run — the
9052
+ * store reads what remains off the records themselves every call. A refused
9053
+ * pass, a `stop()`, a closed tab or a reload all leave `interrupted` true and a
9054
+ * `carryOn()` that continues from exactly where the last pass stopped. Which is
9055
+ * also why a screen driving this may never say "nothing was changed" after a
9056
+ * failure: `progress.archived_total` is what actually landed, and it is the
9057
+ * number the person is owed.
9058
+ */
9059
+ interface UseTableArchive {
9060
+ /** The numbers from the last pass or preview. Null until something has been asked. */
9061
+ progress: TableArchiveProgress | null;
9062
+ /** A loop is in flight. */
9063
+ running: boolean;
9064
+ /** Passes made since the last `start()`. */
9065
+ passes: number;
9066
+ /**
9067
+ * The pass size in use. It STARTS at `chunk` and HALVES whenever the store
9068
+ * runs out of time, so a screen can say the run slowed down rather than
9069
+ * letting it look stuck. Never below ten: at that point the store is not slow,
9070
+ * it is refusing, and a loop that kept shrinking would hide it.
9071
+ */
9072
+ chunkInUse: number;
9073
+ /**
9074
+ * The loop backed the pass size off because the store ran out of time. An
9075
+ * automatic intervention ANNOUNCES ITSELF: a run that quietly went four times
9076
+ * slower would read as a stuck screen.
9077
+ */
9078
+ slowedDown: boolean;
9079
+ /** The refusal that stopped the loop. The work already done still stands. */
9080
+ error: RecordsError | null;
9081
+ /**
9082
+ * The loop ended with records still live — because a pass was refused or
9083
+ * because `stop()` was called. It is the screen's cue to offer carrying on
9084
+ * rather than to claim a finished or a failed run.
9085
+ */
9086
+ interrupted: boolean;
9087
+ /** Ask what would happen and change NOTHING, so a person sees the number first. */
9088
+ preview: () => Promise<TableArchiveProgress | null>;
9089
+ /** Run passes until done, refused, or stopped. */
9090
+ start: () => Promise<TableArchiveProgress | null>;
9091
+ /** Same loop, said in the word a screen uses after an interruption. */
9092
+ carryOn: () => Promise<TableArchiveProgress | null>;
9093
+ /** Cut cleanly after the pass in flight. Never mid-pass: a pass is one transaction. */
9094
+ stop: () => void;
9095
+ }
9096
+ declare function useTableArchive(tableId: Uuid, options?: {
9097
+ chunk?: number;
9098
+ includeTable?: boolean;
9099
+ }): UseTableArchive;
8930
9100
  interface UseFieldMutation {
8931
9101
  /** Add a column. One call; the store decides what the parity type is made of. */
8932
9102
  declare: (args: {
@@ -9016,4 +9186,4 @@ declare function useFieldMutation(): UseFieldMutation;
9016
9186
  */
9017
9187
  declare function useMergeField(key: string | null, state?: Record<string, unknown>): MergeFieldResolution | null;
9018
9188
 
9019
- export { ABSENCE_REASONS, ACTOR_VOCABULARY, ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DECLARABLE_FIELD_KINDS, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DeclarableFieldKind, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, PORTAL_ARCHIVE_FILTERS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordFilter, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isOwnOp, isPortalArchiveFilter, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, rememberedOpCount, sameDocument, scopeChip, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTables };
9189
+ export { ABSENCE_REASONS, ACTOR_VOCABULARY, ARCHIVE_LANES, ARCHIVE_LANE_LABEL, ARCHIVE_LANE_MEANS, type AbsenceReason, type Actor, type AggregateBucket, type AggregateFilter, type AggregateMeasure, type AggregateOperation, type AggregateRow, type AggregateWindow, type AnonTokenBinding, type ArchiveLane, type ArchivedDoorRow, type ArchivedRow, type BookingAvailability, type BookingDeclared, type BookingSummary, type BookingWindow, COMPUTE_ON, CONTEXT_POLICIES, type CaptureField, type CaptureFileRef, type CaptureOutcome, type CaptureQuestion, type CaptureQueue, type CaptureQueueCounts, type CaptureQueueOptions, type CaptureQueuePorts, type CaptureQueueStore, type CaptureSheetFace, type CaptureSheetSummary, type CaptureSyncReport, type ChecklistDeclared, type ChecklistRequirement, type ChecklistRequirementKind, type ChecklistRoleSpec, type ChecklistRunStarted, type ChecklistRunStep, type ChecklistRunSummary, type ChecklistSpec, type ChecklistStepCompleted, type ChecklistStepSpec, type ChecklistTemplateShape, type ChecklistTemplateSummary, type ChecklistTrigger, type ChecklistTriggerKind, type ChoiceOption, type ChoiceOptions, type CoerceOptions, type Coerced, type CoercedAnswers, type CoercibleField, type CommentThreadRead, type CommentWritten, type ComputeOn, type ContextPolicy, type ConversationScope, type ConversationScopeContext, type CustomFieldTableType, DECLARABLE_FIELD_KINDS, DEFAULT_ARCHIVE_LANE, DEFAULT_PORTAL_ARCHIVE_FILTER, DELIVERIES, type DashboardBlock, type DashboardBlockKind, type DashboardBlockResult, type DashboardRunResult, type DashboardSummary, type DeclarableFieldKind, type Delivery, type DigestPreview, type DocRenderRow, type DocSignatureCheck, type DocSignatureRow, type DocTemplateRow, type DocToken, type DocUnresolvedToken, ENTITY_TOKENS, type EnrichAlternate, type EnrichCell, type EnrichDeclared, type EnrichDueRow, type EnrichRun, type EnrichSource, type Enrichment, type EnrichmentSummary, type EntityFieldRights, type EntityFieldValue, type EntityRecordMatch, type EntityRecordRead, type EntityRecordsFound, type EntityTableFacts, type EntityToken, type ExternalPrincipalCard, FIELD_KINDS, FIELD_SENSITIVITIES, FIELD_SOURCES, FRESHNESS, type Field, type FieldBehavior, type FieldHistoryEntry, type FieldKind, type FieldPatch, type FieldProposal, type FieldRule, type FieldSensitivity, type FieldSource, type FieldTypeWord, type ForbiddenEnvelopeWord, type FormSummary, type Freshness, type HiddenFieldNotice, type HistoryActor, type HistoryActorKind, type HistoryChange, type Home, type ImportBatchResult, type ImportColumnPlan, type ImportColumnsDeclared, type ImportFinished, type ImportOpened, type ImportOutcome, type ImportPlan, type ImportPolicy, type ImportProposal, type ImportReport, type ImportRun, type InboundAddress, type InboundDeclared, KERNEL_TABLES, type KernelTableName, type KernelTargets, MERGE_FIELD_MODIFIERS, MERGE_FIELD_SEMANTIC_TYPES, MERGE_FIELD_SOURCES, type MergeField, type MergeFieldModifier, type MergeFieldProvenance, type MergeFieldResolution, type MergeFieldSemanticType, type MergeFieldSource, type MergeFieldTransform, type MissingBehavior, type MyLevel, type MySubscription, type NewEntityFieldDeclaration, type NewFieldDeclaration, ON_DELETE, OVERRIDE_POLICIES, type OnDelete, type OverridePolicy, PARITY_FIELD_TYPES, PERMISSION_LEVELS, PER_VALUE_ACCESS_WORDS, PIPELINE_RULE_KINDS, PORTAL_ARCHIVE_FILTERS, type ParityFieldType, type ParityFieldTypeDescriptor, type PerValueAccessWord, type PermissionLevel, type PgError, type Pipeline, type PipelineColumn, type PipelineDeclared, type PipelineGate, type PipelineGatePreview, type PipelineMissingField, type PipelineMoveResult, type PipelineRule, type PipelineRuleKind, type PipelineSpec, type PipelineStage, type PipelineVerdict, type PortalArchiveAnswer, type PortalArchiveFilter, type PortalCard, type PortalInvitation, type PortalPreviewRow, type PortalPrincipal, type PortalRevocation, type PortalSummary, type PortalTableExposure, type PortalTableRef, type PredictedRefusal, type ProvenancePointer, type PublishBinding, type QueuedCapture, type QueuedCaptureFile, type QueuedCaptureState, type QuietHours, REFUSALS_WORTH_REPEATING, RELATION_BINDINGS, RELATION_CARDINALITIES, RELATION_FLAVORS, RETIRED_ACTOR_WORDS, RULE_NODE_KINDS, RULE_USES, type ReadRow, type ReadValue, type RecordComment, type RecordDocument, type RecordFilter, type RecordHistoryEntry, type RecordRead, type RecordRevision, type RecordScopeComment, type RecordScopeContext, type RecordScopeField, type RecordScopeHistoryEntry, type RecordScopeRelation, type RecordScopeWithheld, type RecordsActor, type RecordsChangeSink, type RecordsConfig, type RecordsDataSource, type RecordsError, type RecordsErrorCode, type RecordsErrorSink, type RecordsFilter, RecordsProvider, type RecordsProviderProps, type RecordsRealtimePort, type RecordsResolverPort, type RecordsResponse, type RecordsResult, type RecordsTableQuery, type RegisteredTable, type Relation, type RelationBinding, type RelationCardinality, type RelationCarries, type RelationCoordinate, type RelationDisplay, type RelationFlavor, type RelationProperties, type RelationTarget, type ResolutionTriple, type ResolvedPublishBinding, type RestorePreview, type RestoreResult, type RetiredActorWord, type Rule, type RuleAnswer, type RuleExpression, type RuleNodeKind, type RuleUse, STAGE_RULE_ENFORCEMENT, STAGE_RULE_ON_FAIL, STORAGE_MODES, STORE_DOORS, STORE_KNOBS, STORE_REFUSAL_CODES, type SavedViewRow, type SavedViewSpecIn, type StagePending, type StagePendingOnBoard, type StageRuleEnforcement, type StageRuleOnFail, type StageRuleWarning, type StaleWriteDetail, type StorageMode, type StoreDoorName, type StoreRefusalCode, type StoredRecord, type StuckRow, type Subscription, type SubscriptionBlock, type SubscriptionCadence, type SubscriptionSpec, TABLE_DISPLAYS, TABLE_ORIGINS, TABLE_TYPES, type Table, type TableArchiveProgress, type TableCapacity, type TableDisplay, type TableOrigin, type TableProposal, type TableType, type Timestamp, type UseEntityFieldMutation, type UseFieldMutation, type UseRecordMutation, type UseRecordsOptions, type UseRecordsState, type UseTableArchive, type Uuid, VALUE_ALTERNATE_KEYS, VALUE_ENVELOPE_KEYS, type ValueAlternate, type ValueAlternateKey, type ValueEnvelope, type ValueEnvelopeKey, type ValueSource, type WorkApprovalDecision, type WorkApprovalFiled, type WorkApprover, type WorkAssignment, type WorkAssignmentField, type WorkChange, type WorkDueState, type WorkGraph, type WorkInboxItem, type WorkInboxKind, type WorkInstantiation, type WorkListFlavour, type WorkListItem, type WorkOrigin, type WorkRecordState, type WorkSlotHold, type WorkState, type WorkTemplateNode, type WorkTemplateRelation, type WorkTurn, type WriteConflict, archivedByLine, archivedWhen, asPermissionLevel, atLeast, bookingPath, choiceSlug, choiceValuesOf, choicesOf, coerceTypedAnswer, coerceTypedAnswers, coercionLabel, emptyArchiveLine, emptyPortalArchiveLine, err, fieldKindFor, forgetAllOps, highestLevel, holdsARetiredChoice, indexedDbStore, isArchiveLane, isDecided, isOwnOp, isPortalArchiveFilter, isRecordsErr, isTheChosen, looksLikeAnId, mayDrag, measureKey, memoryStore, mintClientKey, mintOpId, ok, openCaptureQueue, optionKey, optionLabel, portalArchiveConsequence, portalConfirmLine, portalPath, portalTitleTypedBack, publicFormPath, rememberedOpCount, sameDocument, scopeChip, stableFilterKey, tableShapeChanged, useEntityFieldMutation, useEntityFieldRights, useEntityFields, useEntityRecord, useEntityTable, useFieldMutation, useFields, useMergeField, useMyLevel, useMyLevels, useOptionalRecordsClient, useRecord, useRecordMutation, useRecords, useRecordsActor, useRecordsClient, useTable, useTableArchive, useTables };
@@ -691,6 +691,7 @@ var STORE_DOORS = [
691
691
  { name: "stamp_value_envelopes", args: "p_data jsonb, p_actor text, p_on_behalf_of text, p_at timestamp with time zone", returns: "jsonb", security: "invoker" },
692
692
  { name: "storage_modes", args: "", returns: "text[]", security: "invoker" },
693
693
  { name: "store_is_open", args: "p_organization_id uuid DEFAULT NULL::uuid", returns: "boolean", security: "invoker" },
694
+ { name: "store_off_sentence", args: "p_organization_id uuid", returns: "text", security: "invoker" },
694
695
  { name: "subscription_cadences", args: "p_organization_id uuid", returns: "text[]", security: "definer" },
695
696
  { name: "subscription_declare", args: "p_organization_id uuid, p_table_id uuid, p_spec jsonb", returns: "uuid", security: "definer" },
696
697
  { name: "subscription_mute", args: "p_organization_id uuid, p_rule_id uuid, p_muted boolean DEFAULT true", returns: "boolean", security: "definer" },
@@ -1968,6 +1969,19 @@ var DOORS = {
1968
1969
  fieldOptions: "field_options",
1969
1970
  parityValues: "parity_values",
1970
1971
  tableDeclare: "table_declare",
1972
+ // GETTING RID OF A TABLE — which is a JOB, NOT A STATEMENT (VERIFIER-11 F3).
1973
+ // `record_delete` above is the store's one soft-delete door and it is right
1974
+ // for a record; aimed at a TABLE it recurses through everything the Table
1975
+ // contains inside one transaction, and that is unbounded by construction. A
1976
+ // person pressing "Delete this table" on 1,430 records the product itself
1977
+ // had just imported waited twelve seconds and was told `57014`, "canceling
1978
+ // statement due to statement timeout … Nothing was changed. Try a smaller
1979
+ // page" — advice that means nothing when what you are doing is getting rid
1980
+ // of a table. `custom.table_archive` does the same work in passes and
1981
+ // answers each one with numbers, so a screen shows a sentence and a count
1982
+ // instead of a spinner and an SQLSTATE. It is STATELESS, so a run cut in
1983
+ // half resumes exactly where it stopped: there is no job row to lose.
1984
+ tableArchive: "table_archive",
1971
1985
  // ADDING A COLUMN — the first thing anybody does with a table, and until
1972
1986
  // 2026-09-19 there was no door for it. A Field is a record (REC-25), so a
1973
1987
  // screen wrote one with `record_write`; that door writes ONE row with
@@ -2623,6 +2637,18 @@ function createRecordsClient(config) {
2623
2637
  "recordRestore"
2624
2638
  );
2625
2639
  },
2640
+ async tableArchive({ table_id, chunk, includeTable }) {
2641
+ return callDoor(
2642
+ DOORS.tableArchive,
2643
+ {
2644
+ p_organization_id: org,
2645
+ p_table_id: table_id,
2646
+ p_chunk: chunk ?? 50,
2647
+ p_include_table: includeTable ?? true
2648
+ },
2649
+ "tableArchive"
2650
+ );
2651
+ },
2626
2652
  async recordRead({ record_id, withComputed = false }) {
2627
2653
  const door = await callDoor(
2628
2654
  DOORS.readRecord,
@@ -4694,6 +4720,85 @@ function useRecordMutation() {
4694
4720
  [client, run, saving, error, conflict]
4695
4721
  );
4696
4722
  }
4723
+ var MIN_ARCHIVE_CHUNK = 10;
4724
+ function useTableArchive(tableId, options) {
4725
+ const client = useRecordsClient();
4726
+ const chunk = options?.chunk ?? 50;
4727
+ const includeTable = options?.includeTable ?? true;
4728
+ const [progress, setProgress] = useState(null);
4729
+ const [running, setRunning] = useState(false);
4730
+ const [passes, setPasses] = useState(0);
4731
+ const [error, setError] = useState(null);
4732
+ const [interrupted, setInterrupted] = useState(false);
4733
+ const [chunkInUse, setChunkInUse] = useState(chunk);
4734
+ const [slowedDown, setSlowedDown] = useState(false);
4735
+ const cut = useRef(false);
4736
+ const preview = useCallback(async () => {
4737
+ setError(null);
4738
+ const answered = await client.tableArchive({ table_id: tableId, chunk: 0, includeTable });
4739
+ if (!answered.ok) {
4740
+ setError(answered.error);
4741
+ return null;
4742
+ }
4743
+ setProgress(answered.data);
4744
+ return answered.data;
4745
+ }, [client, tableId, includeTable]);
4746
+ const loop = useCallback(async () => {
4747
+ cut.current = false;
4748
+ setRunning(true);
4749
+ setError(null);
4750
+ setInterrupted(false);
4751
+ setPasses(0);
4752
+ let last = null;
4753
+ let size = chunk;
4754
+ setChunkInUse(size);
4755
+ setSlowedDown(false);
4756
+ try {
4757
+ for (; ; ) {
4758
+ const answered = await client.tableArchive({ table_id: tableId, chunk: size, includeTable });
4759
+ if (!answered.ok) {
4760
+ if (answered.error.code === "timed_out" && size > MIN_ARCHIVE_CHUNK) {
4761
+ size = Math.max(MIN_ARCHIVE_CHUNK, Math.floor(size / 2));
4762
+ setChunkInUse(size);
4763
+ setSlowedDown(true);
4764
+ continue;
4765
+ }
4766
+ setError(answered.error);
4767
+ setInterrupted(true);
4768
+ return last;
4769
+ }
4770
+ last = answered.data;
4771
+ setProgress(answered.data);
4772
+ setPasses((n) => n + 1);
4773
+ if (answered.data.done) return answered.data;
4774
+ if (cut.current) {
4775
+ setInterrupted(true);
4776
+ return answered.data;
4777
+ }
4778
+ }
4779
+ } finally {
4780
+ setRunning(false);
4781
+ }
4782
+ }, [client, tableId, chunk, includeTable]);
4783
+ return useMemo2(
4784
+ () => ({
4785
+ progress,
4786
+ running,
4787
+ passes,
4788
+ chunkInUse,
4789
+ slowedDown,
4790
+ error,
4791
+ interrupted,
4792
+ preview,
4793
+ start: loop,
4794
+ carryOn: loop,
4795
+ stop: () => {
4796
+ cut.current = true;
4797
+ }
4798
+ }),
4799
+ [progress, running, passes, chunkInUse, slowedDown, error, interrupted, preview, loop]
4800
+ );
4801
+ }
4697
4802
  function useEntityFields(token) {
4698
4803
  return useAsync(
4699
4804
  (client) => token ? client.entityFields({ token }) : Promise.resolve({ ok: true, data: [] }),
@@ -5587,6 +5692,7 @@ export {
5587
5692
  useRecordsActor,
5588
5693
  useRecordsClient,
5589
5694
  useTable,
5695
+ useTableArchive,
5590
5696
  useTables
5591
5697
  };
5592
5698
  //# sourceMappingURL=index.js.map