* [AI] Make TypeScript work in test files across packages Match the CRDT package's tsconfig pattern in loot-core, desktop-client, api, and desktop-electron so test files participate in the project graph (IDE intellisense, project-wide typecheck) while production builds still emit clean declaration files. - Remove test-file exclusions from each package's main tsconfig - Add tsconfig.build.json for loot-core and api with test exclusions, used by the build scripts - Add e2e/tsconfig.json for desktop-client and desktop-electron with Playwright types - Fix latent type errors in test files now caught by typecheck - Disable typescript/unbound-method for test files (mock matcher pattern) Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Release notes * [AI] Address review feedback on test type fixes - goal-template.test.ts: extract amounts to typed locals so single-value assertions no longer compare against unknown - category-template-context.test.ts: replace `as unknown as DbCategory` double-cast with a fully-typed object using `satisfies DbCategory` (the previous mock had `is_income: true` which doesn't match the `1 | 0` shape the cast was hiding) - api/tsconfig.build.json: broaden test exclude pattern to `**/*.test.ts` Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * [AI] Widen toMatchThemeScreenshots matcher to accept Page The matcher's runtime impl already handled both Page and Locator (via `typeof locator.page === 'function'` branch), but the type only declared Locator. Call sites pass a Page (`expect(page).toMatchThemeScreenshots()`), which now compiles cleanly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * [AI] Type window.Actual in e2e fixtures and refactor matcher - Pull loot-core/typings/window.ts into the e2e tsconfig include so the ambient `window.Actual` augmentation is visible. - Refactor toMatchThemeScreenshots to derive a Page once via `'page' in target`, then call evaluate on the page consistently. The previous union-typed access (locator.evaluate, locator.page) didn't typecheck on Locator | Page. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * [AI] Drop tsconfig.build.json for loot-core and api The build-config indirection was incomplete protection: typecheck (`tsgo -b` against the main tsconfig, which now includes test files) already emits `*.test.d.ts` into `@types/`, and the build step does not clean before re-emitting. The same is observable in crdt's `dist/`, which currently contains test declarations on disk. What actually keeps test declarations out of the npm tarball is the `files` field in package.json — and loot-core already uses that mechanism for source files (`\!src/**/*.test.ts`). Extending the same pattern to `@types/` is more direct than maintaining a duplicate tsconfig that doesn't reliably do its job. - Delete loot-core/tsconfig.build.json; revert build to `tsgo -b`; add `\!@types/**/*.test.d.ts*`, `\!@types/**/__tests__/**`, `\!@types/**/__mocks__/**` to `files`. - Delete api/tsconfig.build.json; revert build to `vite build && tsgo --emitDeclarationOnly`; add `\!@types/**/*.test.d.ts*` to `files`. Verified: `yarn pack --dry-run` excludes all test declarations from both packages while production declarations still pack (428 .d.ts files for loot-core, methods.d.ts for api). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * [AI] Standardise crdt to drop tsconfig.build.json Apply the same simplification as loot-core and api: a single tsconfig per package, with `files`-field negations preventing test declarations from being published. Note: this also fixes a pre-existing issue where crdt was shipping `crdt/timestamp.test.d.ts` and `crdt/merkle.test.d.ts` to npm. The old `tsconfig.build.json` excluded test files from declaration emit, but the `typecheck` script (`tsgo -b` via the main tsconfig) had already emitted them into `dist/` and the build did not clean first, so they were packed via `"files": ["dist"]`. After this change, `yarn pack --dry-run` packs only production declarations (10 .d.ts files) and excludes the test ones. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@actual-app/crdt
This package contains the core CRDT logic that enables Actual's syncing. It is shared between the client and server. We may or may not follow semver when updating this package; any usage of it outside Actual is undocumented and at your own risk.
protobuf
We use protobuf to encode messages as binary data to send across the network.
Generating protobuf
The protobuf is generated by using the protoc compiler.
This can be installed by downloading one of the pre-built binaries and placing it in your $PATH. The version used to build the current protobuf is v3.20.1. You'll also need to download the latest version of protoc-gen-js. For convenience, you can put both of these binaries in ./bin.
Once installed, the protobuf can be generated by running ./bin/generate-proto.
However there is one very important thing to remember! The default output includes this near the top:
var global = (function() { return this || window || global || self || Function('return this')(); }).call(null);
This will not work with our CSP directives. You must manually modify this to this:
var global = globalThis;