Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions app/application.ml
Original file line number Diff line number Diff line change
Expand Up @@ -1095,8 +1095,7 @@ let apply_worker_response state (response : Journal_graph_runtime.response) =
if next == state || stale then next
else report_ui_error next ~operation:"listFavorites" ~phase:"read"
| Favorites_invalidated -> favorites_event state Invalidate
| Journal_graph_runtime.Graph_ready info ->
ignore info.admission_facts;
| Journal_graph_runtime.Graph_ready ->
let state = resolve_worker_errors state in
{ state with write_enabled = true; graph_ready = true; graph_error = None }
| Admission_inspected _ | Admission_unavailable _ -> state
Expand Down
29 changes: 9 additions & 20 deletions app/journal_asset_import.ml
Original file line number Diff line number Diff line change
Expand Up @@ -87,33 +87,15 @@ let staged_of_pick (pick : Json.pick) =
; source_identity = pick.sourceIdentity }
;;

let parse payload =
let picked (wire : Json.event) =
let ( let* ) = Result.bind in
let* wire = read_event payload in
match wire.action, wire.selection with
| "picked", Some selection ->
let* staged = staged_of_pick selection in
Ok (staged, Option.map (fun (request : Json.request) -> request.id) wire.request)
| _ -> Error "Invalid attachment selection"
;;

let decode ~target payload =
Result.map
(fun ((pick : staged), _) ->
Logseq_db_types.Asset_import.
{ operation = pick.operation
; asset = pick.asset
; target
; replace_reference = None
; local_mutation = pick.local_mutation
; metadata_mutation = pick.metadata_mutation
; source_file = pick.source_file
; title = pick.title
; file_type = pick.file_type
})
(parse payload)
;;

let to_import (staged : staged) ~target : Logseq_db_types.Asset_import.t =
{ operation = staged.operation
; asset = staged.asset
Expand All @@ -127,6 +109,13 @@ let to_import (staged : staged) ~target : Logseq_db_types.Asset_import.t =
}
;;

let decode ~target payload =
let ( let* ) = Result.bind in
let* wire = read_event payload in
let* staged, _ = picked wire in
Ok (to_import staged ~target)
;;

type event =
| Picked of staged * int option
| Picked_batch of staged list * int option * string option
Expand All @@ -140,7 +129,7 @@ let decode_event payload =
let* wire = read_event payload in
let request_id = Option.map (fun (request : Json.request) -> request.id) wire.request in
match wire.action with
| "picked" -> Result.map (fun (staged, id) -> Picked (staged, id)) (parse payload)
| "picked" -> Result.map (fun (staged, id) -> Picked (staged, id)) (picked wire)
| "picked-batch" ->
(match wire.items with
| None -> Error "Invalid attachment batch"
Expand Down
36 changes: 3 additions & 33 deletions app/journal_graph_runtime.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,6 @@ type worker_failure =
; error : Error.t
}

type graph_info =
{ graph_uuid : Graph.Uuid.t
; graph_name : string
; schema : Graph.schema_version
; admission_facts : Graph.admission_fact list
; generation : string
; projection_revision : string
}

type failure_source =
| Worker_failure of worker_failure
| Projection_failure of string
Expand All @@ -43,7 +34,7 @@ type payload =
* Logseq_db_worker.Protocol.v2_favorites_result
| Favorites_failed of Journal_graph_request.favorites_request * bool * string
| Favorites_invalidated
| Graph_ready of graph_info
| Graph_ready
| Admission_inspected of
{ request : Journal_graph_request.admission_request
; observation : Protocol.v2_admission_inspection
Expand Down Expand Up @@ -2933,34 +2924,13 @@ let receive_response t (protocol_response : Protocol.response) =
| Pull_changes { request_generation; _ } ->
rehydrate_current_interests t ~request_generation ~generation
| _ -> failure_output t operation request_id reason)
| V2_graph_info_outcome
{ graph_uuid
; graph_name
; schema
; admission_facts
; journal_title_format
; generation
; projection_revision
; _
} ->
| V2_graph_info_outcome { journal_title_format; _ } ->
(match operation with
| Graph_info ->
let catalog =
if t.task_catalog_started then [] else [ request_task_catalog t ]
in
{ requests = catalog
; responses =
[ response
(Graph_ready
{ graph_uuid
; graph_name
; schema
; admission_facts
; generation
; projection_revision
})
]
}
{ requests = catalog; responses = [ response Graph_ready ] }
| Capture_format { command; page_uuid; page_revision } ->
let journal_day = Journal_time.local_day command.creation_time in
requests
Expand Down
11 changes: 1 addition & 10 deletions app/journal_graph_runtime.mli
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,6 @@ type worker_failure =
; error : Logseq_db_worker.Error.t
}

type graph_info =
{ graph_uuid : Logseq_db_types.Graph_types.Uuid.t
; graph_name : string
; schema : Logseq_db_types.Graph_types.schema_version
; admission_facts : Logseq_db_types.Graph_types.admission_fact list
; generation : string
; projection_revision : string
}

type failure_source =
| Worker_failure of worker_failure
| Projection_failure of string
Expand All @@ -38,7 +29,7 @@ type payload =
* Logseq_db_worker.Protocol.v2_favorites_result
| Favorites_failed of Journal_graph_request.favorites_request * bool * string
| Favorites_invalidated
| Graph_ready of graph_info
| Graph_ready
| Admission_inspected of
{ request : Journal_graph_request.admission_request
; observation : Logseq_db_worker.Protocol.v2_admission_inspection
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Payload Free Graph Ready

## Problem

At main b6c1c77c4cd7b94963e4729dfac55b825c838085, Journal_graph_runtime copies
six graph-info fields into Graph_ready. Its sole Application consumer ignores
the payload. The app library has no public_name; repository-wide searches found
no other Graph_ready consumer, registration or serialized representation.

## Proposal

Make the internal Graph_ready notification payload-free and remove its graph_info
record from app/journal_graph_runtime.ml and .mli. Preserve V2_graph_info requests,
correlation, failure handling, task-catalog launch, readiness publication and
independent admission inspection. Do not change worker protocol or its codecs.

## Decision

Adopt the proposal as explicitly authorized by the user on 2026-10-22.
Implementation and verification are local; no push or PR is authorized.

## Alternatives considered

### Remove the graph-info request

Not selected: the successful response gates readiness and starts task-catalog
loading. Other graph-info operations consume journal formatting and revisions.

## Acceptance criteria

- Existing runtime-locality, Application and worker integration tests pass.
- Temporary public Runtime traces normalize only the intentionally removed
internal payload and compare requests/notifications across success, failure,
abandonment/reset, duplicate and stale completion paths.
- Independent admission reads and their tests remain intact.

## Risks

- Removing the internal payload must not remove the actual request or its
failure/correlation boundary. Supported external consumers discovered during
implementation would require reconsidering the scope.

## Consequences

Graph_ready is now an internal payload-free notification; worker protocol and
independent admission inspection are unchanged. Baseline and final runtime-locality
(152 cases), Application (144 cases, including admission refresh and unlock), and
worker integration (15 cases) pass. Temporary runtime replay yields 5,906 identical
records after normalizing only the removed Graph_ready argument, including explicit
success, duplicate, failure, abandonment, reset and stale-completion scenarios.
Native Swift startup/failure boundary tests also pass; no GUI or real graph was used.

## Questions

None. The user authorized this exact internal simplification on 2026-10-22;
no worker wire change, push or PR is authorized.
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Reuse Attachment Decoding

## Problem

At main b6c1c77c4cd7b94963e4729dfac55b825c838085, decode_event parses the
event and its picked branch parses the same JSON again through parse.
decode also duplicates to_import's mapping from staged picks to worker imports.

## Proposal

Share the picked conversion on an already decoded Json.event and reuse
to_import from decode. Preserve all public entry points, typed JSON/UUID
validation, request identities, error strings, batch order and
replace_reference=None. Do not change Swift picking, cancellation, staging,
security scope, ownership or cleanup behavior.

## Decision

Adopt the proposal as explicitly authorized by the user on 2026-10-22.
Implementation and verification are local; no push or PR is authorized.

## Alternatives considered

### Merge the public APIs or narrow the event vocabulary

Not selected: direct import, staged picks and batch events have existing
consumers and tests. Private reuse removes duplication without a protocol change.

## Acceptance criteria

- Existing routes/platform tests pass before and after the change.
- Temporary comparisons cover valid/invalid UUIDs, malformed JSON and typed
fields, absent/valid request IDs, all event kinds, ordered batches and exact
errors/import fields. Public APIs remain unchanged; temporary tests stay out
of the repository.

## Risks

- Reordering validation or using a broader event decoder could change errors or
accept previously invalid inputs. Reuse only the already validated record and
identical field mapping; do not claim a measured performance improvement.

## Consequences

The private picked helper consumes a validated event, and direct decode reuses
to_import. Existing routes/platform suites pass before and after. Seventy-four
temporary inputs produce identical events, import fields and error strings through
decode_event, decode and is_dismissal; staged/direct mapping assertions pass.
Cases cover typed-field errors, UUID validation, request IDs, controls, ordered
batches and malformed inputs. Swift source and lifecycle ownership are unchanged.

## Questions

None. The user authorized implementation and temporary before/after verification
on 2026-10-22, without permanent additional tests, push or PR.
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Shared Sync Operation Reset

## Problem

At main b6c1c77c4cd7b94963e4729dfac55b825c838085, six transitions in
logseq_sync/lib/pure_reducer/core.ml repeat the same nineteen operation-state
resets: authenticate_new_account, restore_local, sign_out,
select_graph_transition, clear_selected_graph_for_catalog and
return_to_graph_picker. Maintaining these identical assignments separately
obscures which resets are common and which lifecycle policies differ.

## Proposal

Extract only those identical assignments into a private pure helper. Keep all
caller-specific account/graph/presentation generations, pending-effect filtering,
mirror inspection, websocket ownership, cancellation, detach and publication
ordering at each caller. Do not apply the helper to fail, whose retained state
differs. No public interface, protected spec, Dune, dependency or wire changes.

## Decision

Adopt the proposal as explicitly authorized by the user on 2026-10-22.
Implementation and verification are local; no push or PR is authorized.

## Alternatives considered

### Generalize every teardown

Not selected: failure, graph selection and account replacement have different
ownership and cancellation policies. A configurable reset framework would hide
those differences and add policy instead of sharing identical assignments.

## Acceptance criteria

- Existing pure core and recovery tests pass before and after the refactor.
- Temporary public-API traces compare inputs, visible state, admitted graph scope,
asset context and complete ordered effects for all six reset paths, including
stale completions after replacement. Evidence stays outside Git.
- No tests are removed, weakened or added permanently for the mechanical change.

## Risks

- Sharing a non-common reset would alter lifecycle behavior. Verify the exact
nineteen-field intersection and preserve every caller-specific assignment.

## Consequences

The six transitions now share one private nineteen-field reset. Every remaining
caller statement, including effect order, matches the baseline after extracting
those assignments; fail is byte-for-byte unchanged. Existing pure core (87 cases)
and recovery (21 cases) pass before and after. Temporary fixture replay covers
121 pure core/recovery/asset cases, with 1,972 identical public input/state/context/
ordered-effect records across builds. No abstract state was inspected.

## Questions

None. On 2026-10-22 the user authorized these three audited simplifications and
actual before/after verification, with temporary evidence only and no push or PR.
Loading
Loading