Skip to content
Open
Show file tree
Hide file tree
Changes from 200 commits
Commits
Show all changes
266 commits
Select commit Hold shift + click to select a range
74992cc
WIP: fix duplicate agglomerate helper meshes
MichaelBuessemeyer Nov 28, 2025
916ac22
some more logging to detect race conditions; and don't reload meshes …
MichaelBuessemeyer Dec 1, 2025
72be4ec
WIP: improve skeleton diffing during agglomerate skeleton syncing
MichaelBuessemeyer Dec 1, 2025
fe981fd
fix syncing of agglomerate skeletons
MichaelBuessemeyer Dec 2, 2025
d55191b
use position from segments list (if no segment index exists) for proo…
MichaelBuessemeyer Dec 2, 2025
ef04517
WIP implement agglomerate skeleton inplace reloading for split actions
MichaelBuessemeyer Dec 2, 2025
06bb51a
fix agglomerate skeleton generation for tests
MichaelBuessemeyer Dec 3, 2025
4cc955c
Fix unnecessary delete&create edges actions & update test snapshots
MichaelBuessemeyer Dec 3, 2025
f0c8440
remove outdated & commented-out code
MichaelBuessemeyer Dec 3, 2025
9e34019
fix proofreading tests checking that missing mapping info is loaded d…
MichaelBuessemeyer Dec 4, 2025
224f226
min test cleanup
MichaelBuessemeyer Dec 4, 2025
83fb056
update snapshots
MichaelBuessemeyer Dec 4, 2025
778ba13
remove unused import
MichaelBuessemeyer Dec 4, 2025
de4c596
WIP add agglomerate meshes tests
MichaelBuessemeyer Dec 10, 2025
d22e77d
WIP: add proofreading auxiliary mesh loading tests
MichaelBuessemeyer Dec 15, 2025
4853771
add editable mapping verion to precomputed mesh route
MichaelBuessemeyer Dec 15, 2025
598eaca
more backend versioning
MichaelBuessemeyer Dec 16, 2025
f368eaa
use versioned mesh routes in frontend
MichaelBuessemeyer Dec 17, 2025
21d3985
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Dec 17, 2025
ba88496
minor backend mesh route versioning fixes
MichaelBuessemeyer Dec 17, 2025
a94b128
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Dec 18, 2025
39ca075
Fix agglomerate mesh auto refreshing frontend test
MichaelBuessemeyer Dec 18, 2025
f97e53f
add split based agglomerate meshes tests where a foreign action is in…
MichaelBuessemeyer Dec 19, 2025
257f008
test mesh refreshing when only polling updates
MichaelBuessemeyer Dec 19, 2025
9f6dbff
fix tests and update snapshots
MichaelBuessemeyer Dec 19, 2025
e5be63e
do not store which proofreading helper meshes are loaded separately f…
MichaelBuessemeyer Dec 20, 2025
bff7cda
WIP add more auxiliary mesh syning tests
MichaelBuessemeyer Dec 22, 2025
3a59b3c
fix auxiliary mesh reloading tests
MichaelBuessemeyer Dec 26, 2025
fe4f88b
move existing agglomerate skeleton auto updating tests
MichaelBuessemeyer Dec 26, 2025
392dbb9
update snapshots & add more tests for agglomerate skeleton auto syncing
MichaelBuessemeyer Dec 30, 2025
eac4f02
WIP: add storing mapping info after applying backend updates in store…
MichaelBuessemeyer Jan 2, 2026
c943955
refactor mechanism to have agglomerate info after applying backend up…
MichaelBuessemeyer Jan 5, 2026
7d17016
WIP fix auxiliary agglomerate mesh auto reloading tests
MichaelBuessemeyer Jan 5, 2026
0de5c5f
fix some tests & use new way of knowing the needed agglomerate id bef…
MichaelBuessemeyer Jan 6, 2026
d3d41d0
fix test checking that agglomerate skeletons are loaded in a mutex co…
MichaelBuessemeyer Jan 8, 2026
ebdd2f7
remove unused import
MichaelBuessemeyer Jan 9, 2026
e46914a
fix agglomerate skeleton auto updating after splitting and add more t…
MichaelBuessemeyer Jan 12, 2026
edf930d
remove mesh versioning
MichaelBuessemeyer Jan 13, 2026
16b83b2
add auto agglomerate refreshing test for split from all neighbors tes…
MichaelBuessemeyer Jan 13, 2026
48dc94c
add agglomerate auto sync test for paritioned min cut with injected s…
MichaelBuessemeyer Jan 13, 2026
4a6b00e
add missing snapshot files
MichaelBuessemeyer Jan 13, 2026
ab0c1c7
add missing snapshots
MichaelBuessemeyer Jan 13, 2026
a2f56ad
Fix agglomerate tree naming as proofreading post processing & update …
MichaelBuessemeyer Jan 13, 2026
082be5a
little frontend clean up
MichaelBuessemeyer Jan 14, 2026
3bdfcad
format backend
MichaelBuessemeyer Jan 14, 2026
bebdc62
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Jan 14, 2026
8b9cc5d
add changelog entry
MichaelBuessemeyer Jan 14, 2026
16b1e1c
disable action logging again
MichaelBuessemeyer Jan 14, 2026
9484af1
fix tests due to error in previous manual merge
MichaelBuessemeyer Jan 14, 2026
c1295b2
apply some feedback
MichaelBuessemeyer Jan 14, 2026
30cb84d
Merge branch 'master' into live-m3-follow-up
fm3 Jan 19, 2026
33282bc
Versioning for TSFullMeshService; remove TODO comments
fm3 Jan 19, 2026
8908e02
some renamings
fm3 Jan 19, 2026
7f081e3
format
fm3 Jan 19, 2026
cf2466c
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
hotzenklotz Jan 28, 2026
a5ae555
formatting with biome2
hotzenklotz Jan 29, 2026
fa2748b
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
hotzenklotz Jan 29, 2026
4340658
Merge branch 'biome2-formatting' into live-m3-follow-up
hotzenklotz Jan 29, 2026
4cbd530
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
hotzenklotz Jan 29, 2026
d59c0a0
apply some feedback
MichaelBuessemeyer Jan 30, 2026
7e1e580
remove meta info from update action snapshots in proofreading tests
MichaelBuessemeyer Feb 1, 2026
6456265
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Feb 2, 2026
7c7cfdd
format FE
MichaelBuessemeyer Feb 2, 2026
62c970f
versionify segment statistic routes in FE & rename all editableMappin…
MichaelBuessemeyer Feb 2, 2026
0debdce
versionify adhoc mesh requests
MichaelBuessemeyer Feb 2, 2026
ac7d2f0
change adhoc mutex acquisition to a subscription model
MichaelBuessemeyer Feb 3, 2026
883bdf6
format, fix typo, fix left over occurrence of done saving action
MichaelBuessemeyer Feb 3, 2026
d26da96
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Feb 3, 2026
60f4121
fix test
MichaelBuessemeyer Feb 3, 2026
2ae8221
fix mutex acquisition for agglomerate skeleton loading
MichaelBuessemeyer Feb 3, 2026
2b60f2c
guard proofreading post updates with annotation mutex and enforce sav…
MichaelBuessemeyer Feb 4, 2026
aefe756
update snapshot tests -> post processing updates are now included in …
MichaelBuessemeyer Feb 4, 2026
995c4fc
fix backend mesh route versioning
MichaelBuessemeyer Feb 4, 2026
84df9f3
add agglomerateId & tracingId as optional prop to tree prototype to b…
MichaelBuessemeyer Feb 4, 2026
27b2d8e
finish adding tracingId to agglomerateInfo of trees in FE; fixing tes…
MichaelBuessemeyer Feb 5, 2026
a92d328
WIP: Enforce agglomerate tree updates only on synced trees
MichaelBuessemeyer Feb 12, 2026
6fd4f89
- Fix bug where forwarding updates from the backend without rebasing …
MichaelBuessemeyer Feb 16, 2026
5a7edce
add test ensuring simply forwarded update actions are not replayed by…
MichaelBuessemeyer Feb 19, 2026
c1f039c
sort imports
MichaelBuessemeyer Feb 19, 2026
4566421
add success message to end of FE typechecking to give more direct fee…
MichaelBuessemeyer Feb 19, 2026
a806ce0
fix tests and do not edit segment list, if split operation is incomplete
MichaelBuessemeyer Feb 19, 2026
f86f06e
remove isProofreadingAuxiliaryMesh property
MichaelBuessemeyer Feb 19, 2026
de1d1ce
add deep edge diffing tests
MichaelBuessemeyer Feb 19, 2026
efe2b0e
resolve some small open PR todos
MichaelBuessemeyer Feb 19, 2026
ad692a8
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Feb 20, 2026
6676869
add some tests for functions of agglomerate_skeleton_syncing_saga_hel…
MichaelBuessemeyer Feb 20, 2026
a83f559
make `updatedId` in update actions undefined
MichaelBuessemeyer Feb 20, 2026
9d90a0d
format backend
MichaelBuessemeyer Feb 20, 2026
0571497
add tests checking that newly received agglomerate trees via a rebase…
MichaelBuessemeyer Feb 20, 2026
e5a4aa5
reorganize FE imports
MichaelBuessemeyer Feb 20, 2026
a8061d4
fix deadlock caused by first one saga blocking the ui busy state and …
MichaelBuessemeyer Mar 2, 2026
95e6865
add regression test for dead lock fixed in previous commit. See https…
MichaelBuessemeyer Mar 2, 2026
d6ea1e8
reorder imports in FE
MichaelBuessemeyer Mar 2, 2026
2bbdccf
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 2, 2026
663f2aa
fix imports
MichaelBuessemeyer Mar 2, 2026
0421c3a
WIP deduplicate overloaded tracingId field in agglomerateInfo of aggl…
MichaelBuessemeyer Mar 3, 2026
e86f04b
fix previous commit by also renaming action type constant in "action …
MichaelBuessemeyer Mar 3, 2026
c50cfd0
fix imports
MichaelBuessemeyer Mar 3, 2026
4b96077
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 4, 2026
bb74f1b
small improvements to comments and code
philippotto Mar 4, 2026
b7eca5e
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
philippotto Mar 4, 2026
7b6e16c
apply some feedback (e.g. including grammar correction & function par…
MichaelBuessemeyer Mar 4, 2026
590a660
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 4, 2026
e664126
WIP: adust forwarding and reapplying to support other volume/ editabl…
MichaelBuessemeyer Mar 4, 2026
0cbc107
commit all conflicts (this commit pulls the m4 milestone, already
philippotto Mar 5, 2026
f96be39
resolve conflicts in proofreading_mesh_interaction.spec.ts
philippotto Mar 5, 2026
1640bf1
resolve conflicts in proofreading_test_utils.ts
philippotto Mar 5, 2026
56d9e3e
resolve conflicts in proofreading_skeleton_interaction.spec.ts and pr…
philippotto Mar 5, 2026
b55e00d
resolve conflicts in save_queue_filling_saga.ts
philippotto Mar 5, 2026
8d8731b
resolve conflicts in save_saga.tsx
philippotto Mar 5, 2026
dc7c643
resolve skeletontracing_saga.ts
philippotto Mar 5, 2026
0427dc1
resolve update_actions.ts
philippotto Mar 5, 2026
9437b13
resolve conflicts in store.ts
philippotto Mar 5, 2026
b66cc48
resolve conflicts in context_menu.tsx
philippotto Mar 5, 2026
12bf469
resolve most conflicts in proofread_saga.ts
philippotto Mar 5, 2026
f91e854
Fix previous refactoring supporting an arbitrary amount of editable m…
MichaelBuessemeyer Mar 5, 2026
369a33f
resolve conflicts in proofreading_multi_user.spec.ts and fix ups in p…
philippotto Mar 5, 2026
da5fe9e
fix some imports and some somePosition -> anchorPosition stuff
philippotto Mar 5, 2026
ab30e9c
more import fixes
philippotto Mar 5, 2026
147bafd
fix up in proofreading_multi_user.spec.ts
philippotto Mar 5, 2026
ed4da9d
resolve conflicts in proofread_saga.ts
philippotto Mar 5, 2026
0d50554
fix typescript errors
philippotto Mar 5, 2026
4ff4ec0
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
philippotto Mar 5, 2026
f4ab58c
more fix-ups and add todo comments
philippotto Mar 5, 2026
dd5a03f
remove mocked segmentMeshController in favor of the real thing
philippotto Mar 5, 2026
1429fb9
fix proofreading_multi_user.spec
philippotto Mar 5, 2026
68a2ea6
fix that vitest watcher didn't watch frontend tests
philippotto Mar 5, 2026
d7d4c10
[visualization debugger] fix rendering of skeleton nodes when multipl…
philippotto Mar 5, 2026
1d38ee6
fix test in proofreading_skeleton_interaction.spec.ts
philippotto Mar 5, 2026
d565e8b
fix generated update action tests & fix agglomerate skeleton generati…
MichaelBuessemeyer Mar 5, 2026
cf4da0a
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 5, 2026
55d0f37
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
philippotto Mar 5, 2026
083a66c
use getNestedUpdateActions in spec (still broken, though)
philippotto Mar 5, 2026
3047a47
improve update action fixture typing
MichaelBuessemeyer Mar 7, 2026
7224705
remove metadata prop from updateSegmentPartial update action as meta …
MichaelBuessemeyer Mar 7, 2026
d5b7ee3
WIP fix tests in proofreading_skeleton_interaction.spec.ts (snapshots…
MichaelBuessemeyer Mar 7, 2026
ffb1ca1
move other functions to proofreading_generated_update_actions.spec.ts…
MichaelBuessemeyer Mar 9, 2026
c133690
fix proofreading_auxiliary_mesh_loading.spec.ts tests
MichaelBuessemeyer Mar 9, 2026
3bd3abc
re-add volumetracing_saga_integration_2.spec.ts.snap
MichaelBuessemeyer Mar 10, 2026
af5ca46
fix tests in proofreading_agglomerate_skeleton_syncing.spec.ts
MichaelBuessemeyer Mar 10, 2026
513aaa5
fix import order
MichaelBuessemeyer Mar 10, 2026
0a48112
fix typing in FE
MichaelBuessemeyer Mar 10, 2026
11b777a
only spawn mesh loading but ensure segment synchronously to stay with…
philippotto Mar 10, 2026
82eb465
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 10, 2026
bc787c7
fix import order to fix tests
MichaelBuessemeyer Mar 10, 2026
d00d8a7
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 10, 2026
b66fb60
use NumberLikeMapWrapper
philippotto Mar 10, 2026
5665862
more NumberLikeWrapper refactoring
philippotto Mar 10, 2026
310d3e7
fix tests again
MichaelBuessemeyer Mar 10, 2026
3d78121
more NumberLikeWrapper refactoring
philippotto Mar 10, 2026
6736f3b
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
philippotto Mar 10, 2026
cc35b96
fix missing fallback values when using getAsNumber
philippotto Mar 10, 2026
30d092f
fix obsolete import
philippotto Mar 10, 2026
76f1993
use try-finally blocks to unsubscribe from mutex in proofreading sagas
philippotto Mar 10, 2026
2c937d3
fix incorrect updateSegmentAction and setActiveCellAction in simulate…
MichaelBuessemeyer Mar 10, 2026
175055a
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 10, 2026
26d4711
apply various pr review comments
MichaelBuessemeyer Mar 11, 2026
9b3ba54
fix tests after setting updatedId everywhere to undefined & only snap…
MichaelBuessemeyer Mar 12, 2026
f0b3fa9
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 12, 2026
501ac1d
delete outdated snapshot file
MichaelBuessemeyer Mar 12, 2026
e933529
add test helper for expecting present ids in segment list
MichaelBuessemeyer Mar 12, 2026
a21b3e3
extend expectSegmentList function and use it once in proofreading_mes…
philippotto Mar 12, 2026
cfe859c
fix yield select returning any
philippotto Mar 12, 2026
d700cac
fix missing yield for expectMapping
philippotto Mar 12, 2026
fad3e24
add expectSegmentList checks to remaining proofreading_skeleton_inter…
philippotto Mar 12, 2026
77b4014
always ignore user dispatched proofreading skeleton actions and only …
MichaelBuessemeyer Mar 12, 2026
331e1d9
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 12, 2026
5edc084
add expectSegmentList checks to proofreading_single_user.spec.ts
philippotto Mar 12, 2026
ed3a937
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
philippotto Mar 12, 2026
74df382
add expectSegmentList checks to proofreading_poll_only.spec.ts
philippotto Mar 12, 2026
e3ab139
fix process.env vars in FE code and fix updateSegmentActions which ac…
MichaelBuessemeyer Mar 12, 2026
53adac0
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 12, 2026
8f231ec
add new fixtures; filter unrelated actions away; fix segment position…
philippotto Mar 12, 2026
665bcdf
adapt remaining specs in proofreading_multi_user.spec.ts
philippotto Mar 12, 2026
eeb312e
extract more fixtures for proofreading_multi_user.spec.ts
philippotto Mar 12, 2026
5528f7e
temporarily revert to old (broken) makeProofreadMerge and makeProofre…
philippotto Mar 12, 2026
a4ff9cd
swap param order to match makeProofreadSplit helper
philippotto Mar 12, 2026
f588b04
fix segment id in makeProofreadSplit/Merge again
philippotto Mar 12, 2026
039662e
further fixture extraction
philippotto Mar 12, 2026
6741204
WIP fix generated proofreading update actions tests: include segment…
MichaelBuessemeyer Mar 12, 2026
b41dc89
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 12, 2026
9391c0a
further fixture extraction and fix wrong checks in spec
philippotto Mar 12, 2026
d29d1fa
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
philippotto Mar 12, 2026
ad27cdb
WIP: ore generated update actions updates
MichaelBuessemeyer Mar 12, 2026
66d30e7
extract fixture for mergeSegment1337And5; fix mocked bucket data for …
philippotto Mar 13, 2026
d7fc50d
extract fixture for splitSegment7And1337AndMerge1337And5
philippotto Mar 13, 2026
7c93972
use splitSegment7And1337AndMerge1337And5 fixture
philippotto Mar 13, 2026
151da64
make error msg more helpful
philippotto Mar 13, 2026
7417b02
fix mergeSegment4And6WithAgglomerateTree1And4
philippotto Mar 13, 2026
956f79a
fix splitSegment2And3WithAgglomerateTrees1And4And6 fixture
philippotto Mar 13, 2026
dc697bf
fix splitSegment2And3WithAgglomerateTree1 fixture
philippotto Mar 13, 2026
42e37a4
fix mergeSegment5And6WithAgglomerateTree1 fixture
philippotto Mar 13, 2026
d7f6c01
fix mergeSegment5And6WithAgglomerateTree1And4 fixture
philippotto Mar 13, 2026
b6e015d
fix mergeSegment3And4WithAgglomerateTree1 fixture
philippotto Mar 13, 2026
e8c835c
fix splitSegment2And3WithAgglomerateTree1 fixture
philippotto Mar 13, 2026
713ae8f
format
philippotto Mar 13, 2026
cf8bf7a
use mergeSegment1337And5 fixture
philippotto Mar 13, 2026
d1ccc04
use mergeSegment1337And5 fixture
philippotto Mar 13, 2026
5d506c2
fix typing
philippotto Mar 13, 2026
fcd35be
fix incorrect segment item in test by looking up ids again in handleP…
philippotto Mar 13, 2026
e15a520
fix spec in proofreading_mesh_interaction.spec.ts and fix more incorr…
philippotto Mar 13, 2026
dd9dade
improve more specs in proofreading_mesh_interaction.spec.ts
philippotto Mar 13, 2026
72f4ca8
WIP: add segment list entry assertions to proofreading_agglomerate_sk…
MichaelBuessemeyer Mar 16, 2026
2e597ab
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 16, 2026
2c4c8c6
add todo comment
philippotto Mar 16, 2026
1f52018
try to harden typing regarding optional segment position in gatherInf…
philippotto Mar 16, 2026
3dcb859
deleted commented code
philippotto Mar 16, 2026
59f095d
fix some agglomerate skeleton refreshing test
MichaelBuessemeyer Mar 16, 2026
8de76ed
fix broken tests & update update action fixtures (which weren't alrea…
MichaelBuessemeyer Mar 16, 2026
d43b171
remove publishDebuggingState usages in working tests
MichaelBuessemeyer Mar 16, 2026
737ed94
fix import order & remove unused imports
MichaelBuessemeyer Mar 16, 2026
a6cad15
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 17, 2026
c2f8e69
use NumberLikeMapWrapper and update some comments
philippotto Mar 17, 2026
7afd20c
use getPositionForSegmentId in various places
philippotto Mar 17, 2026
cd62390
use fixture in proofreading_mesh_interaction.spec.ts
philippotto Mar 17, 2026
c6c3d04
re-add another expectSegmentList assertion
philippotto Mar 17, 2026
1eed192
use a fixture in proofreading_mesh_interaction.spec.ts
philippotto Mar 17, 2026
48f5582
remove obsolete todo comments
philippotto Mar 17, 2026
157cbe9
small renamings and comment improvements
philippotto Mar 17, 2026
823c42b
grammar
philippotto Mar 17, 2026
481e52b
remove obsolete comment
philippotto Mar 17, 2026
82fef06
do not clear segment list entry in case mergeSegmentItems action merg…
MichaelBuessemeyer Mar 17, 2026
39a6382
during mesh loading also listen to mergeSegmentItemsAction and stop l…
MichaelBuessemeyer Mar 17, 2026
8cee371
when updating segment list items in proofreading saga make sure to th…
MichaelBuessemeyer Mar 17, 2026
e7375fb
defer rebasing post processing which reloads necessary agglomerate me…
MichaelBuessemeyer Mar 17, 2026
2781c6b
add segment list assertions to proofreading_auxiliary_mesh_loading.sp…
MichaelBuessemeyer Mar 17, 2026
3e7677c
fix test requesting an impossible partitioned split by selecting prop…
MichaelBuessemeyer Mar 17, 2026
f74f8b7
sort imports
MichaelBuessemeyer Mar 17, 2026
cd982f3
use VOLUME_TRACING_ID constant in proofreading_interaction_update_act…
MichaelBuessemeyer Mar 17, 2026
49f293a
Merge branch 'live-m3-follow-up' of github.com:scalableminds/webknoss…
MichaelBuessemeyer Mar 17, 2026
e3417a8
use "getPositionForSegmentId" everywhere except for `expectSegmentList`
MichaelBuessemeyer Mar 17, 2026
6257d99
sort imports
MichaelBuessemeyer Mar 17, 2026
5b9d113
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 19, 2026
7c8af0c
refactor save mutex saga to propagate errors thrown during fetching t…
MichaelBuessemeyer Mar 19, 2026
a13fcaa
in delete edge proofreading case in skeleton reducer always ignore us…
MichaelBuessemeyer Mar 19, 2026
d6fc46b
tests: correct segment id arguments in proofreading actions and remo…
MichaelBuessemeyer Mar 19, 2026
50e354c
Fix bug where initial proofreading action had outdated annotation ver…
MichaelBuessemeyer Mar 19, 2026
da9bc7a
fix TODO comments
MichaelBuessemeyer Mar 23, 2026
9e8477b
upon making mapping editable, update agglomerate info of agglomerate …
MichaelBuessemeyer Mar 23, 2026
2f43c90
fix imports
MichaelBuessemeyer Mar 23, 2026
35912f4
Merge branch 'master' of github.com:scalableminds/webknossos into liv…
MichaelBuessemeyer Mar 23, 2026
8705cfc
remove info from potentially locally forwarded update actions
MichaelBuessemeyer Mar 23, 2026
f4c8fdd
apply segment color changes from partial segment updates to meshes as…
MichaelBuessemeyer Mar 23, 2026
4cc5d25
Add TreeAgglomerateInfo to update actions so that users forwarding ag…
MichaelBuessemeyer Mar 24, 2026
c265add
Sync with backend before checking whether an agglomerate skeleton is …
MichaelBuessemeyer Mar 24, 2026
481f8f1
ensure mutex is freed when agglomerate skeleton is already loaded
MichaelBuessemeyer Mar 24, 2026
7247ff9
auto unsubscribe from adhoc mutex after a timeout to avoid blocking o…
MichaelBuessemeyer Mar 24, 2026
6e6f257
fix test not waiting for agglomerate skeleton being loaded
MichaelBuessemeyer Mar 24, 2026
3794a59
clean up: remove unused returned agglomerate tree name
MichaelBuessemeyer Mar 24, 2026
fddfc60
sort & fix imports
MichaelBuessemeyer Mar 24, 2026
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
4 changes: 1 addition & 3 deletions biome.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -120,9 +120,7 @@

"overrides": [
{
"includes": [
"**/package.json"
],
"includes": ["**/package.json"],
"formatter": {
"lineWidth": 1
}
Expand Down
5 changes: 4 additions & 1 deletion frontend/javascripts/admin/api/mesh.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export type MeshSegmentInfo = {
type ListMeshChunksRequest = {
meshFileName: string;
segmentId: number;
annotationVersion: number | undefined | null;
};

export function getMeshFileChunksForSegment(
Expand All @@ -41,6 +42,7 @@ export function getMeshFileChunksForSegment(
// editableMappingTracingId should be the tracing id, not the editable mapping id.
// If this is set, it is assumed that the request is about an editable mapping.
editableMappingTracingId: string | null | undefined,
annotationVersion: number | undefined | null,
): Promise<MeshSegmentInfo> {
return doWithToken((token) => {
const params = new URLSearchParams();
Expand All @@ -54,6 +56,7 @@ export function getMeshFileChunksForSegment(
const payload: ListMeshChunksRequest = {
meshFileName: meshFile.name,
segmentId,
annotationVersion,
};
return Request.sendJSONReceiveJSON(
`${dataStoreUrl}/data/datasets/${datasetId}/layers/${layerName}/meshes/chunks?${params}`,
Expand All @@ -71,7 +74,7 @@ type MeshChunkDataRequest = {
segmentId: number | null; // Only relevant for neuroglancer precomputed meshes
};

type MeshChunkDataRequestList = {
export type MeshChunkDataRequestList = {
meshFileName: string;
requests: MeshChunkDataRequest[];
};
Expand Down
12 changes: 10 additions & 2 deletions frontend/javascripts/admin/rest_api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -880,11 +880,12 @@ export function getSegmentVolumes(
segmentIds: Array<number>,
additionalCoordinates: AdditionalCoordinate[] | undefined | null,
mappingName: string | null | undefined,
annotationVersion: number | undefined,
): Promise<number[]> {
const requestUrl = getDataOrTracingStoreUrl(layerSourceInfo);
return doWithToken((token) =>
Request.sendJSONReceiveJSON(`${requestUrl}/segmentStatistics/volume?token=${token}`, {
data: { additionalCoordinates, mag, segmentIds, mappingName },
data: { additionalCoordinates, mag, segmentIds, mappingName, annotationVersion },
method: "POST",
}),
);
Expand All @@ -896,6 +897,7 @@ type SegmentStatisticsParametersMeshBased = {
mappingName?: string | null;
additionalCoordinates?: AdditionalCoordinate[] | null;
meshFileName?: string | null;
annotationVersion: number | undefined;
};

export function getSegmentSurfaceArea(
Expand All @@ -905,6 +907,7 @@ export function getSegmentSurfaceArea(
segmentIds: Array<number>,
additionalCoordinates: AdditionalCoordinate[] | undefined | null,
mappingName: string | null | undefined,
annotationVersion: number | undefined,
): Promise<number[]> {
const requestUrl = getDataOrTracingStoreUrl(layerSourceInfo);
return doWithToken((token) => {
Expand All @@ -914,6 +917,7 @@ export function getSegmentSurfaceArea(
mappingName,
additionalCoordinates,
meshFileName,
annotationVersion,
};
return Request.sendJSONReceiveJSON(
`${requestUrl}/segmentStatistics/surfaceArea?token=${token}`,
Expand All @@ -931,11 +935,12 @@ export function getSegmentBoundingBoxes(
segmentIds: Array<number>,
additionalCoordinates: AdditionalCoordinate[] | undefined | null,
mappingName: string | null | undefined,
annotationVersion: number | undefined,
): Promise<Array<{ topLeft: Vector3; width: number; height: number; depth: number }>> {
const requestUrl = getDataOrTracingStoreUrl(layerSourceInfo);
return doWithToken((token) =>
Request.sendJSONReceiveJSON(`${requestUrl}/segmentStatistics/boundingBox?token=${token}`, {
data: { additionalCoordinates, mag, segmentIds, mappingName },
data: { additionalCoordinates, mag, segmentIds, mappingName, annotationVersion },
method: "POST",
}),
);
Expand Down Expand Up @@ -1823,6 +1828,7 @@ type MeshRequest = {
mappingName: string | null | undefined;
mappingType: MappingType | null | undefined;
findNeighbors: boolean;
annotationVersion: number;
};

export function computeAdHocMesh(
Expand Down Expand Up @@ -1880,6 +1886,7 @@ export function getBucketPositionsForAdHocMesh(
mag: Vector3,
additionalCoordinates: AdditionalCoordinate[] | null | undefined,
mappingName: string | null | undefined,
annotationVersion: number,
): Promise<Vector3[]> {
const requestUrl = getDataOrTracingStoreUrl(layerSourceInfo);
return doWithToken(async (token) => {
Expand All @@ -1893,6 +1900,7 @@ export function getBucketPositionsForAdHocMesh(
mag,
additionalCoordinates,
mappingName,
annotationVersion,
},
method: "POST",
},
Expand Down
59 changes: 34 additions & 25 deletions frontend/javascripts/libs/diffable_map.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import isEqual from "lodash-es/isEqual";

const defaultItemsPerBatch = 1000;
let idCounter = 0;
const idSymbol = Symbol("id");
Expand Down Expand Up @@ -417,9 +419,11 @@ class DiffableMap<K extends number, V> implements NotEnumerableByObject {
? "null"
: v === undefined
? "undefined"
: typeof v === "object"
? JSON.stringify(v)
: String(v);
: v instanceof DiffableMap
? v.toString()
: typeof v === "object"
? JSON.stringify(v)
: String(v);
return `${k} => ${vStr}`;
})
.join(", ");
Expand Down Expand Up @@ -468,11 +472,16 @@ function shallowCopy<K extends number, V>(template: DiffableMap<K, V>): Diffable
export function diffDiffableMaps<K extends number, V>(
mapA: DiffableMap<K, V>,
mapB: DiffableMap<K, V>,
useDeepEqualityCheck: boolean = false,
): {
changed: Array<K>;
onlyA: Array<K>;
onlyB: Array<K>;
} {
const areDifferent = useDeepEqualityCheck
? (valueA: V | undefined, valueB: V | undefined) => !isEqual(valueA, valueB)
: (valueA: V | undefined, valueB: V | undefined) => valueA !== valueB;

// For the edge case that one of the maps is empty, we will consider them dependent, anyway
const areDiffsDependent = mapA.getId() === mapB.getId() || mapA.size() === 0 || mapB.size() === 0;
let idx = 0;
Expand Down Expand Up @@ -506,7 +515,7 @@ export function diffDiffableMaps<K extends number, V>(

for (const key of setA.values()) {
if (setB.has(key)) {
if (currentMapA.get(key) !== currentMapB.get(key)) {
if (areDifferent(currentMapA.get(key), currentMapB.get(key))) {
changed.push(key);
} else {
// The key exists in both chunks, do not emit this key.
Expand All @@ -530,32 +539,32 @@ export function diffDiffableMaps<K extends number, V>(
idx++;
}

if (!areDiffsDependent) {
// Since, the DiffableMaps don't share the same structure, we might have
// aggregated false-positives, meaning onlyA and onlyB can include the same
// keys, which might or might not belong to the changed set.
// Construct a set for fast lookup
const setA = new Set(onlyA);
// Intersection of onlyA and onlyB:
const missingChangedIds = onlyB.filter((id) => setA.has(id));
const missingChangedIdSet = new Set(missingChangedIds);
const newOnlyA = onlyA.filter((id) => !missingChangedIdSet.has(id));
const newOnlyB = onlyB.filter((id) => !missingChangedIdSet.has(id));
// Ensure that these elements are not equal before adding them to "changed"
const newChanged = changed.concat(
missingChangedIds.filter((id) => mapA.getOrThrow(id) !== mapB.getOrThrow(id)),
);
if (areDiffsDependent) {
return {
changed: newChanged,
onlyA: newOnlyA,
onlyB: newOnlyB,
changed,
onlyA,
onlyB,
};
}

// Since, the DiffableMaps don't share the same structure, we might have
// aggregated false-positives, meaning onlyA and onlyB can include the same
// keys, which might or might not belong to the changed set.
// Construct a set for fast lookup
const setA = new Set(onlyA);
// Intersection of onlyA and onlyB:
const missingChangedIds = onlyB.filter((id) => setA.has(id));
const missingChangedIdSet = new Set(missingChangedIds);
const newOnlyA = onlyA.filter((id) => !missingChangedIdSet.has(id));
const newOnlyB = onlyB.filter((id) => !missingChangedIdSet.has(id));
// Ensure that these elements are not equal before adding them to "changed"
const newChanged = changed.concat(
missingChangedIds.filter((id) => areDifferent(mapA.getOrThrow(id), mapB.getOrThrow(id))),
);
return {
changed,
onlyA,
onlyB,
changed: newChanged,
onlyA: newOnlyA,
onlyB: newOnlyB,
};
}

Expand Down
5 changes: 5 additions & 0 deletions frontend/javascripts/libs/mjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import mjs, { type Matrix4x4, type Vector16 } from "mjs";
import type { Vector2, Vector3, Vector4 } from "viewer/constants";
import { chunk3 } from "viewer/model/helpers/chunk";
import { mod } from "./utils";

const { M4x4: BareM4x4, V2: BareV2, V3: BareV3 } = mjs(Array);

Expand Down Expand Up @@ -359,6 +360,10 @@ const V3 = {
},

multiply: scale3,

mod(a: Vector3, m: number): Vector3 {
return [mod(a[0], m), mod(a[1], m), mod(a[2], m)];
},
};

const V4 = {
Expand Down
26 changes: 12 additions & 14 deletions frontend/javascripts/libs/number_like_map_wrapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,11 @@ import { getAdaptToTypeFunction } from "./utils";

export class NumberLikeMapWrapper<T extends number | bigint> {
private readonly map: Map<T, T>;
private readonly adapt: (key: number) => T;
private readonly adaptKey: (key: number) => T;

constructor(mapping: Mapping) {
this.map = mapping as Map<T, T>;
this.adapt = getAdaptToTypeFunction(mapping) as (key: number) => T;
}

private convertKey(key: number): T {
// Adapt numeric keys (or values) to number or bigint depending
// on the current mapping type.
return this.adapt(key);
this.adaptKey = getAdaptToTypeFunction(mapping) as (key: number) => T;
}

get size(): number {
Expand All @@ -25,23 +19,27 @@ export class NumberLikeMapWrapper<T extends number | bigint> {
}

delete(key: number): boolean {
return this.map.delete(this.convertKey(key));
return this.map.delete(this.adaptKey(key));
}

get(key: number): T | undefined {
return this.map.get(this.convertKey(key));
return this.map.get(this.adaptKey(key));
}

getAsNumber(key: number): number {
return Number(this.get(key));
getAsNumber(key: number): number | undefined {
const val = this.get(key);
if (val === undefined) {
return val;
}
return Number(val);
}

has(key: number): boolean {
return this.map.has(this.convertKey(key));
return this.map.has(this.adaptKey(key));
}

set(key: number, value: T): this {
this.map.set(this.convertKey(key), value);
this.map.set(this.adaptKey(key), value);
return this;
}
}
50 changes: 50 additions & 0 deletions frontend/javascripts/libs/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -593,6 +593,56 @@ export function diffArrays<T>(
};
}

/*
* Diffs two number based arrays. The input is not manipulated.
* Returns three arrays in the from of { both, onlyA, onlyB }.
* both contains the numbers present in both arrays;
* onlyA the numbers present only in array a;
* onlyB the numbers present only in array b.
*/
export function diffNumberArrays(
a: number[],
b: number[],
): { both: number[]; onlyA: number[]; onlyB: number[] } {
// Create sorted copies to avoid mutating inputs
const A = [...a].sort((x, y) => x - y);
const B = [...b].sort((x, y) => x - y);

const both: number[] = [];
const onlyA: number[] = [];
const onlyB: number[] = [];

let indexA = 0;
let indexB = 0;

while (indexA < A.length && indexB < B.length) {
if (A[indexA] === B[indexB]) {
both.push(A[indexA]);
indexA++;
indexB++;
} else if (A[indexA] < B[indexB]) {
onlyA.push(A[indexA]);
indexA++;
} else {
onlyB.push(B[indexB]);
indexB++;
}
}

// Remaining elements
while (indexA < A.length) {
onlyA.push(A[indexA]);
indexA++;
}

while (indexB < B.length) {
onlyB.push(B[indexB]);
indexB++;
}

return { both, onlyA, onlyB };
}

export function diffMaps<K, V>(
stateA: Map<K, V>,
stateB: Map<K, V>,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,9 @@ describe("Annotation API (E2E)", () => {
],
},
];
const createTreesUpdateActions = Array.from(diffTrees(tracingId, new DiffableMap(), trees));
const createTreesUpdateActions = Array.from(
diffTrees(tracingId, new DiffableMap(), trees, false),
);
const updateTreeGroupsUpdateAction = updateTreeGroups(treeGroups, tracingId);
const [saveQueue] = addVersionNumbers(
createSaveQueueFromUpdateActions(
Expand All @@ -280,7 +282,9 @@ describe("Annotation API (E2E)", () => {
const createdExplorational = await createExplorational(datasetId, "skeleton", false, null);
const { tracingId } = createdExplorational.annotationLayers[0];
let trees = createTreeMapFromTreeArray(generateDummyTrees(5, 6));
const createTreesUpdateActions = Array.from(diffTrees(tracingId, new DiffableMap(), trees));
const createTreesUpdateActions = Array.from(
diffTrees(tracingId, new DiffableMap(), trees, false),
);
const metadata = [
{
key: "city",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ const sampleColorLayer: APIColorLayer = {
};

export const sampleHdf5AgglomerateName = "sampleHdf5Mapping";
export const sampleMappingFileName = "sampleMappingFile";
// this is a uint32 segmentation layer
const sampleSegmentationLayer: APISegmentationLayer = {
name: "segmentation",
Expand Down
Loading
Loading