@ai-matrx/records 0.52.0 → 0.53.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.
@@ -130,6 +130,7 @@ __export(react_exports, {
130
130
  useRecordsActor: () => useRecordsActor,
131
131
  useRecordsClient: () => useRecordsClient,
132
132
  useTable: () => useTable,
133
+ useTableArchive: () => useTableArchive,
133
134
  useTables: () => useTables
134
135
  });
135
136
  module.exports = __toCommonJS(react_exports);
@@ -819,6 +820,7 @@ var STORE_DOORS = [
819
820
  { 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" },
820
821
  { name: "storage_modes", args: "", returns: "text[]", security: "invoker" },
821
822
  { name: "store_is_open", args: "p_organization_id uuid DEFAULT NULL::uuid", returns: "boolean", security: "invoker" },
823
+ { name: "store_off_sentence", args: "p_organization_id uuid", returns: "text", security: "invoker" },
822
824
  { name: "subscription_cadences", args: "p_organization_id uuid", returns: "text[]", security: "definer" },
823
825
  { name: "subscription_declare", args: "p_organization_id uuid, p_table_id uuid, p_spec jsonb", returns: "uuid", security: "definer" },
824
826
  { name: "subscription_mute", args: "p_organization_id uuid, p_rule_id uuid, p_muted boolean DEFAULT true", returns: "boolean", security: "definer" },
@@ -2096,6 +2098,19 @@ var DOORS = {
2096
2098
  fieldOptions: "field_options",
2097
2099
  parityValues: "parity_values",
2098
2100
  tableDeclare: "table_declare",
2101
+ // GETTING RID OF A TABLE — which is a JOB, NOT A STATEMENT (VERIFIER-11 F3).
2102
+ // `record_delete` above is the store's one soft-delete door and it is right
2103
+ // for a record; aimed at a TABLE it recurses through everything the Table
2104
+ // contains inside one transaction, and that is unbounded by construction. A
2105
+ // person pressing "Delete this table" on 1,430 records the product itself
2106
+ // had just imported waited twelve seconds and was told `57014`, "canceling
2107
+ // statement due to statement timeout … Nothing was changed. Try a smaller
2108
+ // page" — advice that means nothing when what you are doing is getting rid
2109
+ // of a table. `custom.table_archive` does the same work in passes and
2110
+ // answers each one with numbers, so a screen shows a sentence and a count
2111
+ // instead of a spinner and an SQLSTATE. It is STATELESS, so a run cut in
2112
+ // half resumes exactly where it stopped: there is no job row to lose.
2113
+ tableArchive: "table_archive",
2099
2114
  // ADDING A COLUMN — the first thing anybody does with a table, and until
2100
2115
  // 2026-09-19 there was no door for it. A Field is a record (REC-25), so a
2101
2116
  // screen wrote one with `record_write`; that door writes ONE row with
@@ -2751,6 +2766,18 @@ function createRecordsClient(config) {
2751
2766
  "recordRestore"
2752
2767
  );
2753
2768
  },
2769
+ async tableArchive({ table_id, chunk, includeTable }) {
2770
+ return callDoor(
2771
+ DOORS.tableArchive,
2772
+ {
2773
+ p_organization_id: org,
2774
+ p_table_id: table_id,
2775
+ p_chunk: chunk ?? 50,
2776
+ p_include_table: includeTable ?? true
2777
+ },
2778
+ "tableArchive"
2779
+ );
2780
+ },
2754
2781
  async recordRead({ record_id, withComputed = false }) {
2755
2782
  const door = await callDoor(
2756
2783
  DOORS.readRecord,
@@ -4822,6 +4849,85 @@ function useRecordMutation() {
4822
4849
  [client, run, saving, error, conflict]
4823
4850
  );
4824
4851
  }
4852
+ var MIN_ARCHIVE_CHUNK = 10;
4853
+ function useTableArchive(tableId, options) {
4854
+ const client = useRecordsClient();
4855
+ const chunk = options?.chunk ?? 50;
4856
+ const includeTable = options?.includeTable ?? true;
4857
+ const [progress, setProgress] = (0, import_react2.useState)(null);
4858
+ const [running, setRunning] = (0, import_react2.useState)(false);
4859
+ const [passes, setPasses] = (0, import_react2.useState)(0);
4860
+ const [error, setError] = (0, import_react2.useState)(null);
4861
+ const [interrupted, setInterrupted] = (0, import_react2.useState)(false);
4862
+ const [chunkInUse, setChunkInUse] = (0, import_react2.useState)(chunk);
4863
+ const [slowedDown, setSlowedDown] = (0, import_react2.useState)(false);
4864
+ const cut = (0, import_react2.useRef)(false);
4865
+ const preview = (0, import_react2.useCallback)(async () => {
4866
+ setError(null);
4867
+ const answered = await client.tableArchive({ table_id: tableId, chunk: 0, includeTable });
4868
+ if (!answered.ok) {
4869
+ setError(answered.error);
4870
+ return null;
4871
+ }
4872
+ setProgress(answered.data);
4873
+ return answered.data;
4874
+ }, [client, tableId, includeTable]);
4875
+ const loop = (0, import_react2.useCallback)(async () => {
4876
+ cut.current = false;
4877
+ setRunning(true);
4878
+ setError(null);
4879
+ setInterrupted(false);
4880
+ setPasses(0);
4881
+ let last = null;
4882
+ let size = chunk;
4883
+ setChunkInUse(size);
4884
+ setSlowedDown(false);
4885
+ try {
4886
+ for (; ; ) {
4887
+ const answered = await client.tableArchive({ table_id: tableId, chunk: size, includeTable });
4888
+ if (!answered.ok) {
4889
+ if (answered.error.code === "timed_out" && size > MIN_ARCHIVE_CHUNK) {
4890
+ size = Math.max(MIN_ARCHIVE_CHUNK, Math.floor(size / 2));
4891
+ setChunkInUse(size);
4892
+ setSlowedDown(true);
4893
+ continue;
4894
+ }
4895
+ setError(answered.error);
4896
+ setInterrupted(true);
4897
+ return last;
4898
+ }
4899
+ last = answered.data;
4900
+ setProgress(answered.data);
4901
+ setPasses((n) => n + 1);
4902
+ if (answered.data.done) return answered.data;
4903
+ if (cut.current) {
4904
+ setInterrupted(true);
4905
+ return answered.data;
4906
+ }
4907
+ }
4908
+ } finally {
4909
+ setRunning(false);
4910
+ }
4911
+ }, [client, tableId, chunk, includeTable]);
4912
+ return (0, import_react2.useMemo)(
4913
+ () => ({
4914
+ progress,
4915
+ running,
4916
+ passes,
4917
+ chunkInUse,
4918
+ slowedDown,
4919
+ error,
4920
+ interrupted,
4921
+ preview,
4922
+ start: loop,
4923
+ carryOn: loop,
4924
+ stop: () => {
4925
+ cut.current = true;
4926
+ }
4927
+ }),
4928
+ [progress, running, passes, chunkInUse, slowedDown, error, interrupted, preview, loop]
4929
+ );
4930
+ }
4825
4931
  function useEntityFields(token) {
4826
4932
  return useAsync(
4827
4933
  (client) => token ? client.entityFields({ token }) : Promise.resolve({ ok: true, data: [] }),