chore(lint): LeanCode's strict rules and a pre-push check
The workspace root's analysis_options.yaml includes leancode_lint 27 and enables its analyzer plugin (rules for blocs, Equatable and Flutter layout); the server and the app include that file, while the generated client keeps its own options. Plugins can only be enabled at the root of a pub workspace and only reach packages whose options include the root file, which was verified before settling on this layout. Most rules are warnings, casts, inference and raw types are strict, and the check treats infos as fatal too. lints and flutter_lints are no longer needed.
tool/check.sh checks formatting, runs dart analyze --fatal-infos and the server tests; .git/hooks/pre-push links to it, so every push has to pass it. AGENTS.md describes the checklist and how to install the hook in a fresh clone.
Fixes for the new rules: package imports, run() returns Future<void>, the server setup as one cascade, a primary constructor for the app widget, a const and a redundant argument. The workspace root keeps its conventional name `_` with a documented ignore.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-29 23:06:29 +02:00
|
|
|
# `_` is the conventional name of a pub workspace's root, which is never published or
|
|
|
|
|
# imported, so the naming lint doesn't apply to it.
|
|
|
|
|
name: _ # ignore: package_names
|
2026-09-16 19:24:59 +02:00
|
|
|
publish_to: none
|
|
|
|
|
|
|
|
|
|
environment:
|
|
|
|
|
sdk: '^3.13.0'
|
|
|
|
|
|
|
|
|
|
workspace:
|
|
|
|
|
- halkyon_learn_client
|
|
|
|
|
- halkyon_learn_server
|
|
|
|
|
- halkyon_learn_flutter
|
feat(curator): turn JMdict and the JLPT lists into dictionary files
A package of its own in the workspace, without Serverpod (AGPL, like the
tooling): an adapter per source writes one format for all, documented in
its README, which the server will load. The format is JSON Lines: a
header (source, version, languages, licence, credits), then entries with
a headword and reading, labels (`common`, `jlpt:n5`), a rank, the keys a
search matches, and the entry as cards take it. Everything specific to a
language happens in its adapter (Japanese: forms, readings in kana and
Hepburn romaji, long vowels typed once, meanings without "to" and
articles), so the server's search knows no language.
JMdict comes as jmdict-simplified's JSON, read one entry at a time: all
218,863 entries in some 20 seconds and 300 MB, 16.8 MB gzipped. The JLPT
lists (yomitan-jlpt-vocab, CC BY-SA 4.0, from Waller's CC BY lists) add
levels by JMdict entry, the easiest when a word is on several, and give
the headword its common spelling. Words rank N5 to N1, then the other
common words, then the rest.
The server's image leaves the package out, as it does the client's.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MMm7usAo6q9ZZRoPkWjoxi
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-09 00:25:16 +02:00
|
|
|
- halkyon_learn_curator
|
2026-09-16 19:24:59 +02:00
|
|
|
|
chore(lint): LeanCode's strict rules and a pre-push check
The workspace root's analysis_options.yaml includes leancode_lint 27 and enables its analyzer plugin (rules for blocs, Equatable and Flutter layout); the server and the app include that file, while the generated client keeps its own options. Plugins can only be enabled at the root of a pub workspace and only reach packages whose options include the root file, which was verified before settling on this layout. Most rules are warnings, casts, inference and raw types are strict, and the check treats infos as fatal too. lints and flutter_lints are no longer needed.
tool/check.sh checks formatting, runs dart analyze --fatal-infos and the server tests; .git/hooks/pre-push links to it, so every push has to pass it. AGENTS.md describes the checklist and how to install the hook in a fresh clone.
Fixes for the new rules: package imports, run() returns Future<void>, the server setup as one cascade, a primary constructor for the app widget, a const and a redundant argument. The workspace root keeps its conventional name `_` with a documented ignore.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-09-29 23:06:29 +02:00
|
|
|
dev_dependencies:
|
|
|
|
|
# Referenced by analysis_options.yaml in this directory.
|
|
|
|
|
leancode_lint: ^27.0.0
|
2026-10-12 13:31:22 +02:00
|
|
|
|
|
|
|
|
dependency_overrides:
|
perf(sync): the fork's signed commit with fast merged deletes and batched inserts
The offline sync package's shared part now comes from the fork's branch
halkyon/batch-inserts (949a664, signed), adding two changes to the pin.
A merge only deleting rows skips the projection pass when every visible
row below them goes with them (a card deleted on one device, in a
library of 8,000 cards: 5.4 s for the server to merge, now about 35 ms;
4 s on each other device, now about 0.1 s). And a merge the pass leaves
out writes its new rows up to 1,000 to a statement, its proof also
taking nested studysets (a first push of that library: 35 to 41 s on
the server, now about 5; a device receiving it, 60 s, now 44).
A new sync test deletes a card on one device while another rates it:
the merged delete declines the shortcut there, and both devices end
without the card or its rating.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-17 22:24:30 +02:00
|
|
|
# The offline sync package's shared part from our fork: v0.0.10 with seven
|
2026-10-17 14:47:16 +02:00
|
|
|
# changes. Byte payloads compared as bytes: v0.0.10 compares them byte by byte
|
|
|
|
|
# through a UUID parse that throws for each byte, so a sync touching a few thousand
|
|
|
|
|
# cards kept the server busy for minutes, answering nobody, while its client timed
|
|
|
|
|
# out and sent everything again (2026-10-12). onInboundMerge, called only when
|
|
|
|
|
# changes from the remote peer were merged: onMergeSuccess fires for a space this
|
|
|
|
|
# device only pushed to, so every repository read everything again after each
|
perf(sync): the fork's signed commit with fast merged deletes and batched inserts
The offline sync package's shared part now comes from the fork's branch
halkyon/batch-inserts (949a664, signed), adding two changes to the pin.
A merge only deleting rows skips the projection pass when every visible
row below them goes with them (a card deleted on one device, in a
library of 8,000 cards: 5.4 s for the server to merge, now about 35 ms;
4 s on each other device, now about 0.1 s). And a merge the pass leaves
out writes its new rows up to 1,000 to a statement, its proof also
taking nested studysets (a first push of that library: 35 to 41 s on
the server, now about 5; a device receiving it, 60 s, now 44).
A new sync test deletes a card on one device while another rates it:
the merged delete declines the shortcut there, and both devices end
without the card or its rating.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-17 22:24:30 +02:00
|
|
|
# save's sync (2026-10-17). A local delete, and a merge only inserting new rows
|
|
|
|
|
# or only deleting rows, skip the foreign key projection pass when they can't
|
|
|
|
|
# change it: the pass loaded nearly every synced row, 8 s for one delete and 9.5 s
|
|
|
|
|
# for each rating another device made, in a library of 8,000 cards (2026-10-17).
|
|
|
|
|
# Such a merge writes its new rows up to 1,000 to a statement: a first push of
|
|
|
|
|
# that library took the server 35 s, now 5 (2026-10-17). And projections are
|
2026-10-17 19:21:16 +02:00
|
|
|
# rebuilt once after the synced tables changed, not on every session and merge
|
|
|
|
|
# (upstream #150). Pinned to a signed commit of the fork's branch
|
perf(sync): the fork's signed commit with fast merged deletes and batched inserts
The offline sync package's shared part now comes from the fork's branch
halkyon/batch-inserts (949a664, signed), adding two changes to the pin.
A merge only deleting rows skips the projection pass when every visible
row below them goes with them (a card deleted on one device, in a
library of 8,000 cards: 5.4 s for the server to merge, now about 35 ms;
4 s on each other device, now about 0.1 s). And a merge the pass leaves
out writes its new rows up to 1,000 to a statement, its proof also
taking nested studysets (a first push of that library: 35 to 41 s on
the server, now about 5; a device receiving it, 60 s, now 44).
A new sync test deletes a card on one device while another rates it:
the merged delete declines the shortcut there, and both devices end
without the card or its rating.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-17 22:24:30 +02:00
|
|
|
# halkyon/batch-inserts (on halkyon/fast-merge-deletes, on halkyon/fast-merges,
|
|
|
|
|
# on halkyon/fast-deletes, on halkyon/inbound-merges, on halkyon/byte-payloads);
|
|
|
|
|
# drop each change once a release of the package has it.
|
2026-10-12 13:31:22 +02:00
|
|
|
serverpod_offline_sync:
|
|
|
|
|
git:
|
|
|
|
|
url: https://code.halkyon.app/project-halkyon/serverpod-offline-sync.git
|
|
|
|
|
path: packages/serverpod_offline_sync
|
perf(sync): the fork's signed commit with fast merged deletes and batched inserts
The offline sync package's shared part now comes from the fork's branch
halkyon/batch-inserts (949a664, signed), adding two changes to the pin.
A merge only deleting rows skips the projection pass when every visible
row below them goes with them (a card deleted on one device, in a
library of 8,000 cards: 5.4 s for the server to merge, now about 35 ms;
4 s on each other device, now about 0.1 s). And a merge the pass leaves
out writes its new rows up to 1,000 to a statement, its proof also
taking nested studysets (a first push of that library: 35 to 41 s on
the server, now about 5; a device receiving it, 60 s, now 44).
A new sync test deletes a card on one device while another rates it:
the merged delete declines the shortcut there, and both devices end
without the card or its rating.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Signed-off-by: Tizian 「ティツィアーン」 <raisondetredev@pm.me>
2026-10-17 22:24:30 +02:00
|
|
|
ref: 949a6645e08af27bb61c96d7ddc2b6d145fed554
|