Folds the WebDAV + Nextcloud slice notes into the long-term plan in
the same format as prior slices and renumbers the Remaining Slice
Plan so SuperSync becomes slice 1 (next) and LocalFile slice 2.
Captures the consensus-driven decisions from the WebDAV slice
(port reuse instead of new `WebDavNativeHttpExecutor`, no-retry
preservation, monolithic spec move, Nextcloud generic widened,
`md5HashSync` → `hash-wasm` async, CORS heuristic tightened,
inline `registerPlugin` dropped) plus follow-up commit history
(namespace/server-format specs, xmldom devDeps move, CORS pattern
broadening).
Records the bundle-size delta (75.77 KB CJS / 73.23 KB ESM after
the slice) and the architectural deferrals (parser O(n) walk,
LocalFile's `md5HashPromise`).
Includes a more concrete plan for the SuperSync slice: port reuse,
response-validators staying app-side because of the
\`@sp/shared-schema\` boundary ban, localStorage storage port,
\`isTransientNetworkError\` promotion path, compression direct
\`@sp/sync-core\` import, and the privacy-sweep starting points.
Add a "Current Fifth Slice" section mirroring the Current First through
Fourth Slice summaries, capturing PR 5a (provider error classes), PR 5b
(Dropbox provider proper), and the post-review cleanup pass.
Renumber the Remaining Slice Plan now that the Dropbox slice has shipped:
WebDAV + Nextcloud is now slice 1 (next), SuperSync slice 2, LocalFile
slice 3. The WebDAV entry calls out the WebDavNativeHttpExecutor port
shape, the errorMeta / urlPathOnly log-helper promotion, and the
A1/A3/B3.x privacy sweep carry-over.
Refresh the top-of-doc Status header so the shipped-vs-remaining
inventory matches the slice summaries.
Capture what landed in the native-HTTP-retry slice and split the
deferred Dropbox + WebDAV provider moves into their own slices, with
the additional package ports (provider error classes, platform-info,
fetch-provider, WebDAV native HTTP) called out explicitly so the
shape can be designed and reviewed before the next slice ships.
* refactor(sync): extract framework-agnostic sync types into @sp/sync-core
Stand up packages/sync-core/ as the new home for sync types and
constants that have no Angular/NgRx coupling. This is the thin first
slice of separating sync engine, configuration, and provider concerns
into distinct packages.
Files moved (sources now live in packages/sync-core/src/):
- core/operation.types.ts
- core/action-types.enum.ts
- core/lww-update-action-types.ts
- core/sync-state-corrupted.error.ts
- core/types/apply.types.ts
- sync-providers/provider.const.ts
- util/entity-key.util.ts
Original paths in src/app/op-log/ keep working as thin re-export stubs
so existing callers don't change. op-log/sync-exports.ts now sources
provider.const exports directly from @sp/sync-core.
Files with transitive Angular dependencies (encryption, sync-errors,
provider.interface, vector-clock util) stay in the app for now — moving
them requires introducing a logger port and is part of the next slice.
* refactor(sync): keep @sp/sync-core domain-agnostic
The first slice landed too much Super Productivity-specific content in
@sp/sync-core. The lib should expose generic sync primitives; the host
app supplies the SP-specific config.
Pulled out of the lib (now app-side only):
- ActionType enum (NgRx action strings for SP features)
- ENTITY_TYPES / EntityType union (SP domain entities)
- SyncImportReason union (SP import flows)
- RepairSummary / RepairPayload (SP repair shape)
- WrappedFullStatePayload + appDataComplete helpers (SP wire format)
- SyncProviderId / SyncStatus / ConflictReason / OAUTH_SYNC_PROVIDERS
/ REMOTE_FILE_CONTENT_PREFIX / PRIVATE_CFG_PREFIX (SP providers/keys)
- The @sp/shared-schema dep (also SP-coupled)
Generic-ized in the lib:
- Operation.actionType: string and Operation.entityType: string (lib
carries opaque strings; host narrows in app code)
- Operation.syncImportReason removed; app extends Operation with it
- VectorClock now defined locally as Record<string, number>
- LWW helpers replaced by createLwwUpdateActionTypeHelpers(entityTypes)
factory; the app instantiates it with SP's ENTITY_TYPES
- entity-key.util uses string for entityType
App stubs now redeclare the SP-narrowed Operation, EntityChange,
EntityConflict, ConflictResult, MultiEntityPayload, ApplyOperationsResult
on top of the lib generic types via Omit-and-extend, and re-host all the
SP-specific helpers (WrappedFullStatePayload, extractFullStateFromPayload,
assertValidFullStatePayload, RepairSummary, RepairPayload).
Also added @sp/sync-core to src/tsconfig.spec.json paths so the spec
build uses the source, not the dist (matching shared-schema).
* docs(sync): add @sp/sync-core extraction plan
Roadmap for carving the sync engine out of src/app/op-log/ into a
reusable, framework-agnostic AND domain-agnostic @sp/sync-core package
plus a sibling @sp/sync-providers.
Documents:
- The three-concern split (engine / config / providers) target
- The domain rule: nothing SP-specific lands in the lib (ActionType,
ENTITY_TYPES, SyncImportReason, RepairPayload, SyncProviderId, the
appDataComplete wire format, @sp/shared-schema all stay app-side)
- PR 1 (landed): generic primitives only; app stubs preserve every
pre-existing call site via Omit-and-extend
- PR 2: SyncLogger port + parameterize entity-registry
- PR 3a: pure algorithmic core (vector-clock client wrapper, conflict
detection, op validation, encryption, sync-errors) — needs only the
SyncLogger port
- PR 3b: orchestrators behind ports (OperationStorePort,
ActionDispatchPort, ConflictUiPort, SyncConfigPort) — the high-risk
step where the app/lib boundary becomes load-bearing
- PR 4: lift providers into @sp/sync-providers
- PR 5: ESLint boundary rule
* refactor(sync): address sync-core extraction review
* docs(sync): refine extraction plan follow-ups
---------
Co-authored-by: Claude <noreply@anthropic.com>