@ai-matrx/records 0.41.0 → 0.43.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/CHANGELOG.md +41 -0
- package/dist/core/index.cjs +75 -7
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +19 -3
- package/dist/core/index.d.ts +19 -3
- package/dist/core/index.js +75 -7
- package/dist/core/index.js.map +1 -1
- package/dist/{field-CVn0-HKo.d.cts → field-CdHqvIIy.d.cts} +30 -4
- package/dist/{field-CVn0-HKo.d.ts → field-CdHqvIIy.d.ts} +30 -4
- package/dist/index.cjs +49 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +85 -7
- package/dist/index.d.ts +85 -7
- package/dist/index.js +49 -4
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +118 -11
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +135 -9
- package/dist/react/index.d.ts +135 -9
- package/dist/react/index.js +118 -11
- package/dist/react/index.js.map +1 -1
- package/dist/use-cases/index.cjs.map +1 -1
- package/dist/use-cases/index.d.cts +1 -1
- package/dist/use-cases/index.d.ts +1 -1
- package/dist/use-cases/index.js.map +1 -1
- package/package.json +1 -1
package/dist/react/index.js
CHANGED
|
@@ -9,6 +9,45 @@ import {
|
|
|
9
9
|
useMemo
|
|
10
10
|
} from "react";
|
|
11
11
|
|
|
12
|
+
// src/ops.ts
|
|
13
|
+
var REMEMBER_MS = 3e4;
|
|
14
|
+
var REMEMBER_MAX = 500;
|
|
15
|
+
var ours = /* @__PURE__ */ new Map();
|
|
16
|
+
function trim(now) {
|
|
17
|
+
for (const [id, at] of ours) {
|
|
18
|
+
if (now - at <= REMEMBER_MS) break;
|
|
19
|
+
ours.delete(id);
|
|
20
|
+
}
|
|
21
|
+
while (ours.size > REMEMBER_MAX) {
|
|
22
|
+
const oldest = ours.keys().next();
|
|
23
|
+
if (oldest.done === true) break;
|
|
24
|
+
ours.delete(oldest.value);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function mintOpId() {
|
|
28
|
+
const id = crypto.randomUUID();
|
|
29
|
+
const now = Date.now();
|
|
30
|
+
ours.set(id, now);
|
|
31
|
+
trim(now);
|
|
32
|
+
return id;
|
|
33
|
+
}
|
|
34
|
+
function isOwnOp(opId) {
|
|
35
|
+
if (!opId) return false;
|
|
36
|
+
const at = ours.get(opId);
|
|
37
|
+
if (at === void 0) return false;
|
|
38
|
+
if (Date.now() - at > REMEMBER_MS) {
|
|
39
|
+
ours.delete(opId);
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
function forgetAllOps() {
|
|
45
|
+
ours.clear();
|
|
46
|
+
}
|
|
47
|
+
function rememberedOpCount() {
|
|
48
|
+
return ours.size;
|
|
49
|
+
}
|
|
50
|
+
|
|
12
51
|
// src/level.ts
|
|
13
52
|
var PERMISSION_LEVELS = [
|
|
14
53
|
"viewer",
|
|
@@ -486,6 +525,7 @@ var STORE_DOORS = [
|
|
|
486
525
|
{ name: "read_paths_outside_the_door", args: "", returns: "TABLE(object_name text, why text)", security: "invoker" },
|
|
487
526
|
{ name: "read_record", args: "p_organization_id uuid, p_record_id uuid, p_by_id boolean DEFAULT false", returns: "jsonb", security: "definer" },
|
|
488
527
|
{ name: "read_records", args: "p_organization_id uuid, p_table_id uuid, p_by_id boolean DEFAULT false, p_limit integer DEFAULT 200, p_offset integer DEFAULT 0", returns: "TABLE(id uuid, document jsonb, level permission_level)", security: "definer" },
|
|
528
|
+
{ name: "read_records_by_ids", args: "p_organization_id uuid, p_table_id uuid, p_record_ids uuid[], p_by_id boolean DEFAULT false", returns: "TABLE(id uuid, document jsonb, level permission_level)", security: "definer" },
|
|
489
529
|
{ name: "realtime_topic_admits", args: "p_topic text", returns: "boolean", security: "definer" },
|
|
490
530
|
{ name: "record_aggregate", args: "p_organization_id uuid, p_table_id uuid, p_group_by jsonb DEFAULT '[]'::jsonb, p_measures jsonb DEFAULT '[]'::jsonb, p_bucket jsonb DEFAULT NULL::jsonb, p_filter jsonb DEFAULT '{}'::jsonb, p_limit integer DEFAULT 200, p_required text DEFAULT 'viewer'::text", returns: "TABLE(groups jsonb, measures jsonb, row_count bigint)", security: "definer" },
|
|
491
531
|
{ name: "record_applicability", args: "p_organization_id uuid, p_record_id uuid", returns: "TABLE(rule_id uuid, rule_name text, rule_version integer, applies boolean, answer jsonb)", security: "invoker" },
|
|
@@ -510,6 +550,7 @@ var STORE_DOORS = [
|
|
|
510
550
|
{ name: "record_values", args: "p_organization_id uuid, p_record_id uuid", returns: "jsonb", security: "invoker" },
|
|
511
551
|
{ name: "record_values_of", args: "p_row custom.record", returns: "jsonb", security: "invoker" },
|
|
512
552
|
{ name: "record_values_versioned", args: "p_organization_id uuid, p_record_id uuid", returns: "TABLE(field_key text, field_id uuid, value jsonb, value_version integer, source jsonb, absent_reason text, actor text, on_behalf_of text, written_at timestamp with time zone, alternates jsonb)", security: "definer" },
|
|
553
|
+
{ name: "record_words", args: "p_organization_id uuid, p_record_id uuid, p_noun text DEFAULT NULL::text", returns: "text", security: "definer" },
|
|
513
554
|
{ name: "record_write", args: "p_organization_id uuid, p_table_id uuid, p_data jsonb", returns: "uuid", security: "definer" },
|
|
514
555
|
{ name: "record_write_many", args: "p_organization_id uuid, p_table_id uuid, p_rows jsonb[], p_ids uuid[] DEFAULT NULL::uuid[]", returns: "uuid[]", security: "definer" },
|
|
515
556
|
{ name: "refusals_claiming_a_level_never_asked", args: "", returns: "TABLE(function_name text, identity_args text, why text)", security: "invoker" },
|
|
@@ -710,18 +751,18 @@ var STORE_KNOBS = [
|
|
|
710
751
|
{ key: "world_publish_enabled", value: "false", type: "boolean" }
|
|
711
752
|
];
|
|
712
753
|
var STORE_REFUSAL_CODES = [
|
|
713
|
-
{ code: "02000", raised_by: "_checklist_instantiate,checklist_declare,checklist_run,checklist_step_complete,checklist_step_refusal,checklist_template_shape,conversation_scope_bind,dashboard_delete,dashboard_run,doc_letterhead,doc_render_body,doc_render_document,doc_render_read,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_save,enrich_pin,entity_field_retire,entity_field_update,entity_record_read,entity_value_write,external_history_event,external_rows,external_stub_upsert,external_writes_set,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,portal_card,portal_declare,portal_invite,portal_preview,portal_principal_bind,portal_revoke,read_record,record_delete,record_restore,record_restore_preview,record_table,record_update,relation_uncarry,share_access,share_grant,share_lane_set,share_people,share_revoke,sign_request_cancel,sign_request_create,sign_request_remind,sign_request_unchanged,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,table_share_outside_revoke,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state" },
|
|
754
|
+
{ code: "02000", raised_by: "_checklist_instantiate,_table_share_invite_payload,checklist_declare,checklist_run,checklist_step_complete,checklist_step_refusal,checklist_template_shape,conversation_scope_bind,dashboard_delete,dashboard_run,doc_letterhead,doc_render_body,doc_render_document,doc_render_read,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_save,enrich_pin,entity_field_retire,entity_field_update,entity_record_read,entity_value_write,external_history_event,external_rows,external_stub_upsert,external_writes_set,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,portal_card,portal_declare,portal_invite,portal_preview,portal_principal_bind,portal_revoke,read_record,record_delete,record_restore,record_restore_preview,record_table,record_update,relation_uncarry,share_access,share_grant,share_lane_set,share_people,share_revoke,sign_request_cancel,sign_request_create,sign_request_remind,sign_request_unchanged,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,table_share_outside_revoke,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state" },
|
|
714
755
|
{ code: "0A000", raised_by: "checklist_step_complete,external_rows,external_source_declare,external_write_through,promote_field,promoted_index_expr,promoted_query_sql,promoted_read,rule_eval,work_assign" },
|
|
715
756
|
{ code: "22003", raised_by: "context_resolve" },
|
|
716
757
|
{ code: "22004", raised_by: "_entity_custom_fields_guard,_value_envelope,actor_word,agg_assert_key,agg_sql,anon_capture,anon_token_issue,anon_write,assert_client_may_reach,booking_declare,capture_submit,checklist_declare,context_resolve,dashboard_block_normalize,dashboard_declare,dashboard_window_sql,doc_render_write,doc_sign,doc_signature_write,doc_template_save,enrich_land,enrich_normalize,external_history_event,external_rows,external_source_declare,external_stub_upsert,external_write_through,external_writes_set,field_history,form_declare,form_submit,home_add,io_comment_write,io_import_begin,io_infer_column,io_outbox_drain,io_restore,migrate_choice_keys,migrate_purge,migrate_reclass,migrate_split,migrate_undo,organization_clear,organization_contents,pipeline_declare,pipeline_gate_preview,portal_declare,portal_invite,portal_principal_bind,provenance_retention_days,provenance_write,query_across_homes,query_by_coordinates,query_rollup,record_delete,record_reparent,record_resolve,record_restore,record_update,record_write,record_write_many,relation_carry,relation_own,rule_declare,share_grant,sign_request_create,sign_request_sign,subscription_declare,table_declare,table_share_outside_invite,value_restore,view_declare,work_approval_decide,work_approval_request,work_template_declare" },
|
|
717
758
|
{ code: "22007", raised_by: "dashboard_window_sql" },
|
|
718
759
|
{ code: "22012", raised_by: "rule_eval" },
|
|
719
|
-
{ code: "22023", raised_by: "_booking_availability,_entity_custom_fields_guard,_value_envelope,_work_shape_guard,actor_word,agg_assert_key,agg_sql,anon_token_issue,booking_declare,containment_parent,dashboard_block_normalize,dashboard_window_sql,doc_render_body,doc_render_write,doc_signature_write,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_history,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pin_agent_cells,pipeline_move,portal_declare,provenance_write,query_by_coordinates,query_rollup,record_update,record_write_many,relation_carry,rule_eval,rule_members,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_rules,visibility_as_of,work_approval_request,work_list,work_slot_hold" },
|
|
760
|
+
{ code: "22023", raised_by: "_booking_availability,_entity_custom_fields_guard,_take_op_id,_value_envelope,_work_shape_guard,actor_word,agg_assert_key,agg_sql,anon_token_issue,booking_declare,containment_parent,dashboard_block_normalize,dashboard_window_sql,doc_render_body,doc_render_write,doc_signature_write,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_history,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pin_agent_cells,pipeline_move,portal_declare,provenance_write,query_by_coordinates,query_rollup,record_update,record_write_many,relation_carry,rule_eval,rule_members,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_rules,visibility_as_of,work_approval_request,work_list,work_slot_hold" },
|
|
720
761
|
{ code: "23503", raised_by: "_booking_availability,_checklist_instantiate,_containment_guard,_field_document_for,_pipeline_stage_key,_record_rule_uses,agg_digest_assemble,anon_publish,anon_rate_take,anon_token_issue,anon_write,assert_organization_wall,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,form_declare,form_submit,home_add,inbound_declare,inbound_mail_land,inbound_set,io_comment_write,io_import_begin,io_import_finish,io_import_report,io_import_rows,io_proposal_accept,migrate_demote,migrate_promote,pipeline_board,pipeline_declare,pipeline_move,pipeline_read,pipeline_transition_refusal,promote_field,promote_table,record_applicability,record_reparent,relation_carry,relation_own,resolve_first_match,rule_applies,rule_declare,rule_eval,rule_members,rule_run,sign_request_create,subscription_mute,subscription_preview,view_declare,work_set_state,work_take_assignment,work_template_instantiate" },
|
|
721
762
|
{ code: "23505", raised_by: "_unique_rule_holds,doc_sign,doc_signature_write,entity_field_declare,field_declare,home_add,inbound_declare,io_proposal_accept,relation_carry,relation_own,share_grant,sign_request_cancel,sign_request_create,table_share_outside_invite,table_share_outside_resend,work_approval_decide,work_slot_hold" },
|
|
722
|
-
{ code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_entity_custom_fields_guard,_field_class_guard,_field_document_for,_field_shape_guard,_field_type_parity_guard,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_work_shape_guard,_workdoors_approval_guard,assert_columns_are_defined,assert_entity_is_organization_scoped,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,doc_sign,doc_signature_write,doc_template_save,entity_field_declare,entity_field_retire,entity_field_update,entity_records_find,entity_table,field_declare,field_retire,field_update,home_add,io_import_rows,migrate_merge,relation_carry,relation_own,sign_request_create,sign_request_sign,table_declare,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
|
|
763
|
+
{ code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_entity_custom_fields_guard,_field_class_guard,_field_document_for,_field_shape_guard,_field_type_parity_guard,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_work_shape_guard,_workdoors_approval_guard,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,doc_sign,doc_signature_write,doc_template_save,entity_field_declare,entity_field_retire,entity_field_update,entity_records_find,entity_table,field_declare,field_retire,field_update,home_add,io_import_rows,migrate_merge,relation_carry,relation_own,sign_request_create,sign_request_sign,table_declare,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
|
|
723
764
|
{ code: "40001", raised_by: "has_visibility_at" },
|
|
724
|
-
{ code: "42501", raised_by: "_doc_render_immutable,_doc_signature_immutable,_field_definition_write,_field_write_door,_rule_definition_write,_store_door,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,conversation_scope_bind,conversation_scope_unbind,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_value_write,external_write_through,form_declare,form_submit,inbound_mail_land,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,migrate_purge,migrate_reclass,my_levels,organization_clear,portal_declare,portal_invitation,portal_invite,portal_principal_bind,promote_table,query_visibility_parity,read_record,read_records,record_table,share_grant,subscription_mute,subscription_preview,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_person" },
|
|
765
|
+
{ code: "42501", raised_by: "_doc_render_immutable,_doc_signature_immutable,_field_definition_write,_field_write_door,_rule_definition_write,_store_door,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,conversation_scope_bind,conversation_scope_unbind,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_value_write,external_write_through,form_declare,form_submit,inbound_mail_land,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,migrate_purge,migrate_reclass,my_levels,organization_clear,portal_declare,portal_invitation,portal_invite,portal_principal_bind,promote_table,query_visibility_parity,read_record,read_records,read_records_by_ids,record_table,share_grant,subscription_mute,subscription_preview,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_person" },
|
|
725
766
|
{ code: "42703", raised_by: "entity_table,portal_declare" },
|
|
726
767
|
{ code: "53400", raised_by: "anon_rate_take,delete_cascade_closure,enrich_due,enrich_land,promote_field" },
|
|
727
768
|
{ code: "54001", raised_by: "record_delete" },
|
|
@@ -1804,6 +1845,13 @@ var DOORS = {
|
|
|
1804
1845
|
// this person could see.
|
|
1805
1846
|
readRecord: "read_record",
|
|
1806
1847
|
readRecords: "read_records",
|
|
1848
|
+
// THE SAME READ DOOR, ADDRESSED BY AN ID SET. A realtime notice names the exact ids that
|
|
1849
|
+
// moved; before this existed the only door that took them was the PAGE door, so a
|
|
1850
|
+
// three-cell change re-read fifty rows in every watching browser. It is a separate NAME
|
|
1851
|
+
// rather than a sixth argument to `read_records` because adding a defaulted argument to a
|
|
1852
|
+
// live Postgres function makes every existing call ambiguous — `is not unique`. Same
|
|
1853
|
+
// ladder, same level, same masking, same page ceiling.
|
|
1854
|
+
readRecordsByIds: "read_records_by_ids",
|
|
1807
1855
|
// DOOR-8, the two clocks. `p_recorded_at` is what the store SAID then;
|
|
1808
1856
|
// `p_world_on` is what was TRUE of the world on that date, read out of dated
|
|
1809
1857
|
// values. A client that answered either one itself would be guessing.
|
|
@@ -2380,17 +2428,18 @@ function createRecordsClient(config) {
|
|
|
2380
2428
|
async recordWrite({ table_id, data }) {
|
|
2381
2429
|
return callDoor(
|
|
2382
2430
|
DOORS.recordWrite,
|
|
2383
|
-
{ p_organization_id: org, p_table_id: table_id, p_data: data },
|
|
2431
|
+
{ p_organization_id: org, p_table_id: table_id, p_data: { ...data, _op_id: mintOpId() } },
|
|
2384
2432
|
"recordWrite"
|
|
2385
2433
|
);
|
|
2386
2434
|
},
|
|
2387
2435
|
async recordWriteMany({ table_id, rows, ids }) {
|
|
2436
|
+
const opId = mintOpId();
|
|
2388
2437
|
return callDoor(
|
|
2389
2438
|
DOORS.recordWriteMany,
|
|
2390
2439
|
{
|
|
2391
2440
|
p_organization_id: org,
|
|
2392
2441
|
p_table_id: table_id,
|
|
2393
|
-
p_rows: rows,
|
|
2442
|
+
p_rows: rows.map((row) => ({ ...row, _op_id: opId })),
|
|
2394
2443
|
...ids === void 0 ? {} : { p_ids: ids }
|
|
2395
2444
|
},
|
|
2396
2445
|
"recordWriteMany"
|
|
@@ -2402,7 +2451,7 @@ function createRecordsClient(config) {
|
|
|
2402
2451
|
{
|
|
2403
2452
|
p_organization_id: org,
|
|
2404
2453
|
p_record_id: record_id,
|
|
2405
|
-
p_patch: patch,
|
|
2454
|
+
p_patch: { ...patch, _op_id: mintOpId() },
|
|
2406
2455
|
...expectedVersion === void 0 ? {} : { p_expected_version: expectedVersion }
|
|
2407
2456
|
},
|
|
2408
2457
|
"recordUpdate"
|
|
@@ -2444,6 +2493,21 @@ function createRecordsClient(config) {
|
|
|
2444
2493
|
}
|
|
2445
2494
|
return ok({ record_id, document, hidden, computed, computedUnavailable });
|
|
2446
2495
|
},
|
|
2496
|
+
async listByIds({ table_id, ids }) {
|
|
2497
|
+
if (ids.length === 0) return ok([]);
|
|
2498
|
+
const door = await callDoor(
|
|
2499
|
+
DOORS.readRecordsByIds,
|
|
2500
|
+
{ p_organization_id: org, p_table_id: table_id, p_record_ids: ids },
|
|
2501
|
+
"listByIds"
|
|
2502
|
+
);
|
|
2503
|
+
if (!door.ok) return err(door.error);
|
|
2504
|
+
return ok(
|
|
2505
|
+
(door.data ?? []).map((row) => {
|
|
2506
|
+
const { document, hidden } = unfold(row.document);
|
|
2507
|
+
return { id: row.id, document, level: row.level, hidden };
|
|
2508
|
+
})
|
|
2509
|
+
);
|
|
2510
|
+
},
|
|
2447
2511
|
async list({ table_id, limit = 50, offset = 0 }) {
|
|
2448
2512
|
const door = await callDoor(
|
|
2449
2513
|
DOORS.readRecords,
|
|
@@ -4162,7 +4226,11 @@ function useAsync(run, deps) {
|
|
|
4162
4226
|
};
|
|
4163
4227
|
}, [client, nonce, ...deps]);
|
|
4164
4228
|
const reload = useCallback(() => setNonce((n) => n + 1), []);
|
|
4165
|
-
|
|
4229
|
+
const setData = useCallback((update) => {
|
|
4230
|
+
if (!alive.current) return;
|
|
4231
|
+
setState((s) => ({ ...s, data: update(s.data) }));
|
|
4232
|
+
}, []);
|
|
4233
|
+
return { ...state, reload, setData };
|
|
4166
4234
|
}
|
|
4167
4235
|
function useTable(tableId) {
|
|
4168
4236
|
return useAsync(
|
|
@@ -4251,14 +4319,49 @@ function useRecords(tableId, options = {}) {
|
|
|
4251
4319
|
[tableId, pageSize, page]
|
|
4252
4320
|
);
|
|
4253
4321
|
const realtime = client.config.realtime;
|
|
4254
|
-
const { reload } = base;
|
|
4322
|
+
const { reload, setData } = base;
|
|
4255
4323
|
useEffect(() => {
|
|
4256
4324
|
if (!realtime || !tableId) return;
|
|
4257
4325
|
return realtime.subscribeRecords(
|
|
4258
4326
|
{ organization_id: client.config.organizationId, table_id: tableId },
|
|
4259
|
-
|
|
4327
|
+
{
|
|
4328
|
+
records(ids) {
|
|
4329
|
+
if (ids === null) {
|
|
4330
|
+
void reload();
|
|
4331
|
+
return;
|
|
4332
|
+
}
|
|
4333
|
+
if (ids.length === 0) return;
|
|
4334
|
+
void (async () => {
|
|
4335
|
+
const answered = await client.listByIds({ table_id: tableId, ids });
|
|
4336
|
+
if (!answered.ok) {
|
|
4337
|
+
void reload();
|
|
4338
|
+
return;
|
|
4339
|
+
}
|
|
4340
|
+
const fresh = new Map(answered.data.map((row) => [row.id, row]));
|
|
4341
|
+
const onThisPage = (id) => (base.data?.rows ?? []).some((row) => row.id === id);
|
|
4342
|
+
const needsThePage = ids.some((id) => !onThisPage(id) && fresh.has(id));
|
|
4343
|
+
if (needsThePage) {
|
|
4344
|
+
void reload();
|
|
4345
|
+
return;
|
|
4346
|
+
}
|
|
4347
|
+
setData(
|
|
4348
|
+
(current) => current === null ? current : {
|
|
4349
|
+
...current,
|
|
4350
|
+
// A named id that came back replaces the row on screen; one that did NOT
|
|
4351
|
+
// is a record this reader may no longer see (deleted, or unshared), so it
|
|
4352
|
+
// leaves the page — exactly what the page read would have done by
|
|
4353
|
+
// omission.
|
|
4354
|
+
rows: current.rows.filter((row) => !(ids.includes(row.id) && !fresh.has(row.id))).map((row) => fresh.get(row.id) ?? row)
|
|
4355
|
+
}
|
|
4356
|
+
);
|
|
4357
|
+
})();
|
|
4358
|
+
},
|
|
4359
|
+
shape() {
|
|
4360
|
+
if (tableId) tableShapeChanged(tableId);
|
|
4361
|
+
}
|
|
4362
|
+
}
|
|
4260
4363
|
);
|
|
4261
|
-
}, [realtime, tableId, client
|
|
4364
|
+
}, [realtime, tableId, client, reload, setData, base.data]);
|
|
4262
4365
|
const live = Boolean(realtime && tableId);
|
|
4263
4366
|
const liveReason = realtime ? tableId ? "Live: changes to this table re-read through the read door." : "Not live: no table selected." : "Not live: this host bound no realtime port, so this list updates when you reload it.";
|
|
4264
4367
|
return { ...base, live, liveReason };
|
|
@@ -4934,10 +5037,12 @@ export {
|
|
|
4934
5037
|
choiceValuesOf,
|
|
4935
5038
|
choicesOf,
|
|
4936
5039
|
err,
|
|
5040
|
+
forgetAllOps,
|
|
4937
5041
|
highestLevel,
|
|
4938
5042
|
holdsARetiredChoice,
|
|
4939
5043
|
indexedDbStore,
|
|
4940
5044
|
isDecided,
|
|
5045
|
+
isOwnOp,
|
|
4941
5046
|
isRecordsErr,
|
|
4942
5047
|
isTheChosen,
|
|
4943
5048
|
looksLikeAnId,
|
|
@@ -4945,12 +5050,14 @@ export {
|
|
|
4945
5050
|
measureKey,
|
|
4946
5051
|
memoryStore,
|
|
4947
5052
|
mintClientKey,
|
|
5053
|
+
mintOpId,
|
|
4948
5054
|
ok,
|
|
4949
5055
|
openCaptureQueue,
|
|
4950
5056
|
optionKey,
|
|
4951
5057
|
optionLabel,
|
|
4952
5058
|
portalPath,
|
|
4953
5059
|
publicFormPath,
|
|
5060
|
+
rememberedOpCount,
|
|
4954
5061
|
scopeChip,
|
|
4955
5062
|
tableShapeChanged,
|
|
4956
5063
|
useEntityFieldMutation,
|