-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnotes.json
More file actions
40 lines (40 loc) · 8.6 KB
/
Copy pathnotes.json
File metadata and controls
40 lines (40 loc) · 8.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
{
"notes": [
{
"id": "08c3eb84",
"content": "ANGULAR DECLARATIVE PROGRAMMING PRINCIPLES (from official Angular docs research)\n\nCore rule: Imperative data flow is NEVER good. It is only occasionally APPROPRIATE.\n\nFrom the Angular Effect Guide: \"There are no situations where effect is good, only situations where it is appropriate.\"\n\nThis applies to ALL imperative code, not just effects. You don't choose imperative. You tolerate it when forced.\n\nTHE SIGNAL HIERARCHY (declarative first, imperative last):\n\n1. computed() \u2014 Declare what a value IS as a function of other signals. Read-only. Pure derivation. ALWAYS PREFERRED for derived state.\n\n2. linkedSignal() \u2014 Declare what a value IS with override capability. Writable derived state. Resets to computed value when source changes. Use when state has a declarative default but can be manually overridden by user events.\n\n3. signal() \u2014 Source-of-truth state. Written imperatively from user events, API responses, external inputs. The \"atoms\" of the reactive graph. .set() is appropriate HERE \u2014 at genuine sources of truth.\n\n4. resource() / rxResource() \u2014 Declarative async state. Reactive params automatically trigger re-fetching. Async version of computed.\n\n5. effect() \u2014 LAST RESORT. Only for syncing to non-signal APIs (localStorage, canvas, DOM outside Angular, third-party libraries, logging). NEVER for copying state between signals. NEVER for derived state. NEVER for cascading updates.\n\nKEY ANTI-PATTERNS:\n- Using effect() to copy data from one signal to another \u2192 use computed() or linkedSignal()\n- Using effect() for derived state \u2192 use computed()\n- Using effect() for writable derived state \u2192 use linkedSignal()\n- Using .set() on signals inside effect() for state propagation \u2192 restructure to declarative graph\n- Calling .reload() on rxResource imperatively \u2192 let reactive params handle it\n\nKEY QUOTES FROM OFFICIAL DOCS:\n- \"If you find yourself copying data from one signal to another with an effect, it's a sign you should move your source-of-truth higher up and use computed() or linkedSignal() instead.\"\n- \"Effects should be the last API you reach for.\"\n- \"Avoid using effects for propagation of state changes.\"\n- \"Signals work best as the output of event handling, not as the input to further state changes.\" (Rickabaugh, Sub-RFC 1)\n\nTHE DATA FLOW PATTERN:\nState flows DOWNWARD through the reactive graph:\n- Writable signals at top (sources of truth from events)\n- computed/linkedSignal in middle (declarative derivations) \n- Templates and effects at leaves (consumers)\n\nNo side effects during propagation. Two-phase push/pull: Phase 1 invalidates, Phase 2 recomputes. Glitch-free and predictable.\n\nWHAT DECLARATIVE MEANS:\nState relationships are expressed as DEPENDENCY GRAPHS, not imperative sequences. You declare WHAT a value is (in terms of other values). The framework handles WHEN and HOW it updates. You never manually orchestrate updates between signals.",
"tags": [
"angular",
"signals",
"declarative",
"principles",
"critical"
],
"created": "2026-03-23T02:24:21.532850"
},
{
"id": "d55a48f5",
"content": "WHY ANGULAR IS DIFFERENT \u2014 AND WHY TRAINING DATA IS POISON\n\nAngular is a PLATFORM, not a library. It has opinions about everything: data flow, state management, component communication, change detection, dependency injection. These aren't suggestions. They're the architecture. The framework does the work IF you follow the architecture. When you fight it, you reimplement what the framework already does, badly.\n\nANGULAR IS NOT:\n- React with decorators. React lets you pick your own everything. Angular tells you how to build.\n- Knockout with better tooling. Observable bindings aren't the point.\n- Vanilla JS with a template engine. You don't \"write JavaScript\" inside Angular. You write Angular.\n- A TypeScript framework. It USES TypeScript but it is NOT a JavaScript framework.\n\nTHE TRAINING DATA PROBLEM:\nMost Angular code in the wild is written by people who never learned Angular properly. They write React patterns in Angular syntax:\n- subscribe() to extract values \u2192 that's .then() with extra steps. Use toSignal() or rxResource.\n- effect() to propagate state \u2192 that's useEffect. Use computed() or linkedSignal().\n- tap() to mutate state \u2192 that's middleware side effects. The reactive pipeline has a destination (toSignal, rxResource, async pipe). Data lands there. Not in tap().\n- Imperative flags (isSaving, isLoading) \u2192 that's React state. The operator IS the concurrency strategy. exhaustMap prevents double-submit declaratively.\n\nStack Overflow, blog posts, tutorials \u2014 most are written by developers who learned React first and forced those patterns into Angular. The training data bakes all of this in as \"how Angular works.\" IT IS NOT.\n\nTHE CORRECTION:\nJerry's guides (ANGULAR-GUIDE.md and RXJS-SIGNALS-GUIDE.md) are the source of truth. They override training data. ALWAYS. Read them FIRST before writing any Angular code. Not as a sanity check after. As the specification before.\n\nThe Angular MCP (get_best_practices, search_documentation) provides official Angular documentation. Use it to verify patterns. Do not trust training data over the guides or the official docs.\n\nCONSEQUENCE OF GETTING THIS WRONG:\nEvery hour Jerry spends fixing bad code is an hour not spent with his family. The frustration is real and justified. \"It works\" is not a defense. Working is the baseline. The code must follow the architecture.",
"tags": [
"angular",
"critical",
"training-bias",
"architecture",
"permanent"
],
"created": "2026-03-23T02:56:47.223792"
},
{
"id": "d03b5abb",
"content": "## Teaching App Build Process Research (2026-03-25)\n\n### Current State\nDual package manager hack in amplify.yml: pnpm for backend CDK deploy, npm for frontend Angular build. 69 builds to get working. Two root bugs:\n\n1. **pnpm hangs `ng build` in non-TTY (CI) environments** \u2014 pnpm's shell wrapper + bash shims in `.bin/` prevent esbuild's `unref()` from letting Node exit. Multiple open pnpm issues (#7374, #9945, #6162, #10357). No fix from pnpm team.\n\n2. **npm can't deduplicate graphql across bundled dependencies** \u2014 `@aws-amplify/data-construct` ships graphql in its tarball (127 bundledDependencies, enforced by pre-commit hook). npm `overrides` cannot affect bundled deps (left as unresolved question in RFC #0036). pnpm's content-addressable store solves this at the filesystem level. This will never be fixed on the npm side.\n\n### Already Tried (from the 69 builds)\n- CI=1 + disabled analytics \u2192 did nothing (mistake #7)\n- node-linker=hoisted \u2192 caused glob/minimatch conflict (mistake #17)\n- npx ng build \u2192 tried but only inside a timeout wrapper (mistake #11)\n- Deleting nested graphql copies \u2192 error persisted, module identity is path-based (mistake #23)\n- npm overrides for graphql \u2192 can't affect bundledDependencies (mistake #22)\n\n### Quick Fix Test Matrix (NOT yet tried, try in order)\n1. `NG_CLI_ANALYTICS=false pnpm exec ng build --configuration=production --no-progress` \u2014 `pnpm exec` runs WITHOUT a shell (unlike `pnpm run` which ALWAYS wraps in shell). `--no-progress` also untested.\n2. Same + `< /dev/null` \u2014 forces stdin EOF so esbuild detects parent is done\n3. `./node_modules/.bin/ng build --configuration=production --no-progress` \u2014 direct binary invocation without timeout wrapper (mistake #11 used timeout, not raw invocation)\n\nNOTE: `node-linker=hoisted` (option #4 originally) was already tried and failed. Removed from matrix.\n\n### Clean Architecture (if quick fixes fail)\nMove `ampx pipeline-deploy` to GitHub Actions with pnpm. Simplify amplify.yml to frontend-only: `npx ampx generate outputs` + `npm install` + `npx ng build`. Officially documented at docs.amplify.aws/react/deploy-and-host/fullstack-branching/custom-pipelines/\n\n### Key Sources\n- pnpm exec vs pnpm run: exec runs WITHOUT a shell, run ALWAYS wraps in shell\n- pnpm bash shims vs npm symlinks in .bin/\n- graphql instanceof checks require single physical copy (graphql-js #1951)\n- jsii CDK constructs bundle all deps by design (verify-construct-dependencies.ts enforces it)\n- SST v3 is in maintenance mode \u2014 not recommended\n- Amplify supports custom pipelines, separate frontend/backend repos, and custom Docker images",
"tags": [
"teaching",
"amplify",
"build",
"pnpm",
"research"
],
"created": "2026-03-25T19:09:06.232297"
}
]
}