ndomo 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.bun-version +1 -0
- package/.dockerignore +79 -0
- package/.editorconfig +18 -0
- package/.env.example +19 -0
- package/.github/CODEOWNERS +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +62 -0
- package/.github/ISSUE_TEMPLATE/config.yml +2 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +34 -0
- package/.github/dependabot.yml +36 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/release.yml +30 -0
- package/.github/workflows/gitleaks.yml +28 -0
- package/.github/workflows/release-please.yml +27 -0
- package/.github/workflows/smoke.yml +29 -0
- package/.husky/commit-msg +1 -0
- package/CHANGELOG.md +114 -0
- package/Dockerfile +32 -0
- package/README.es.md +174 -0
- package/README.md +187 -0
- package/agents/chronicler.md +98 -0
- package/agents/ci-smith.md +136 -0
- package/agents/craftsman.md +341 -0
- package/agents/deploy-smith.md +138 -0
- package/agents/foreman.md +377 -0
- package/agents/go-smith.md +164 -0
- package/agents/guild.md +188 -0
- package/agents/inspector.md +83 -0
- package/agents/js-smith.md +127 -0
- package/agents/ops-scout.md +173 -0
- package/agents/painter.md +200 -0
- package/agents/python-smith.md +120 -0
- package/agents/ranger.md +307 -0
- package/agents/release-smith.md +165 -0
- package/agents/rust-smith.md +159 -0
- package/agents/sage.md +178 -0
- package/agents/scout.md +144 -0
- package/agents/scribe.md +156 -0
- package/agents/smith.md +201 -0
- package/agents/vue-smith.md +155 -0
- package/agents/warden.md +216 -0
- package/agents/zig-smith.md +156 -0
- package/bin/ndomo-analyses.ts +4 -0
- package/bin/ndomo-status.ts +4 -0
- package/biome.json +57 -0
- package/bun.lock +514 -0
- package/commitlint.config.js +3 -0
- package/config/ndomo.config.json +258 -0
- package/config/ndomo.schema.json +166 -0
- package/docs/agents.md +375 -0
- package/docs/bugs/plan-create-orphan-fk.md +131 -0
- package/docs/bugs/task_create_batch-order-index-collision.md +158 -0
- package/docs/configuration.md +276 -0
- package/docs/database.md +364 -0
- package/docs/features/feature-flexible-builder-v1.md +724 -0
- package/docs/features/feature-flexible-builder-v2.md +882 -0
- package/docs/features/feature-flexible-builder.md +974 -0
- package/docs/http-server.md +244 -0
- package/docs/installation.md +259 -0
- package/docs/integrations.md +129 -0
- package/docs/operations/anti-pattern-sub-agent-verify-2026-06-21.md +32 -0
- package/docs/operations/audit-v1.md +417 -0
- package/docs/operations/audit-v2.md +197 -0
- package/docs/operations/audit-v3.md +306 -0
- package/docs/operations/db-optimize-foundations.md +123 -0
- package/docs/operations/verify-gate-architecture.md +82 -0
- package/docs/workflows.md +448 -0
- package/opencode.json +5 -0
- package/package.json +65 -0
- package/release-please-config.json +11 -0
- package/scripts/dev-bust-cache.sh +164 -0
- package/scripts/install.sh +688 -0
- package/scripts/smoke-e2e.ts +704 -0
- package/scripts/smoke-hot.ts +417 -0
- package/scripts/smoke-http.sh +228 -0
- package/scripts/smoke-v4.ts +256 -0
- package/scripts/smoke-v5.ts +397 -0
- package/scripts/smoke.sh +9 -0
- package/scripts/uninstall.sh +224 -0
- package/skills/api-security-best-practices/SKILL.md +915 -0
- package/skills/bash-scripting/SKILL.md +201 -0
- package/skills/bun/SKILL.md +313 -0
- package/skills/cavecrew/SKILL.md +82 -0
- package/skills/caveman/SKILL.md +74 -0
- package/skills/caveman-review/README.md +33 -0
- package/skills/caveman-review/SKILL.md +55 -0
- package/skills/find-skills/SKILL.md +142 -0
- package/skills/frontend-design/LICENSE.txt +177 -0
- package/skills/frontend-design/SKILL.md +55 -0
- package/skills/golang-patterns/SKILL.md +674 -0
- package/skills/golang-security/SKILL.md +185 -0
- package/skills/golang-security/evals/evals.json +595 -0
- package/skills/golang-security/references/architecture.md +268 -0
- package/skills/golang-security/references/checklist.md +80 -0
- package/skills/golang-security/references/cookies.md +200 -0
- package/skills/golang-security/references/cryptography.md +424 -0
- package/skills/golang-security/references/filesystem.md +285 -0
- package/skills/golang-security/references/injection.md +315 -0
- package/skills/golang-security/references/logging.md +163 -0
- package/skills/golang-security/references/memory-safety.md +241 -0
- package/skills/golang-security/references/network.md +253 -0
- package/skills/golang-security/references/secrets.md +189 -0
- package/skills/golang-security/references/third-party.md +159 -0
- package/skills/golang-security/references/threat-modeling.md +189 -0
- package/skills/golang-testing/SKILL.md +720 -0
- package/skills/grill-me/SKILL.md +7 -0
- package/skills/javascript-testing-patterns/SKILL.md +537 -0
- package/skills/javascript-testing-patterns/references/advanced-testing-patterns.md +513 -0
- package/skills/modern-javascript-patterns/SKILL.md +43 -0
- package/skills/modern-javascript-patterns/references/advanced-patterns.md +487 -0
- package/skills/modern-javascript-patterns/references/details.md +457 -0
- package/skills/python-anti-patterns/SKILL.md +349 -0
- package/skills/python-design-patterns/SKILL.md +85 -0
- package/skills/python-design-patterns/references/details.md +353 -0
- package/skills/python-error-handling/SKILL.md +193 -0
- package/skills/python-error-handling/references/details.md +171 -0
- package/skills/python-testing-patterns/SKILL.md +278 -0
- package/skills/python-testing-patterns/references/advanced-patterns.md +411 -0
- package/skills/python-testing-patterns/references/details.md +349 -0
- package/skills/rust-patterns/SKILL.md +500 -0
- package/skills/rust-testing/SKILL.md +501 -0
- package/skills/security-review/SKILL.md +504 -0
- package/skills/security-review/cloud-infrastructure-security.md +361 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/references/animation-class-based-technique.md +254 -0
- package/skills/vue-best-practices/references/animation-state-driven-technique.md +291 -0
- package/skills/vue-best-practices/references/component-async.md +97 -0
- package/skills/vue-best-practices/references/component-data-flow.md +307 -0
- package/skills/vue-best-practices/references/component-fallthrough-attrs.md +174 -0
- package/skills/vue-best-practices/references/component-keep-alive.md +137 -0
- package/skills/vue-best-practices/references/component-slots.md +216 -0
- package/skills/vue-best-practices/references/component-suspense.md +228 -0
- package/skills/vue-best-practices/references/component-teleport.md +108 -0
- package/skills/vue-best-practices/references/component-transition-group.md +128 -0
- package/skills/vue-best-practices/references/component-transition.md +125 -0
- package/skills/vue-best-practices/references/composables.md +290 -0
- package/skills/vue-best-practices/references/directives.md +162 -0
- package/skills/vue-best-practices/references/perf-avoid-component-abstraction-in-lists.md +159 -0
- package/skills/vue-best-practices/references/perf-v-once-v-memo-directives.md +182 -0
- package/skills/vue-best-practices/references/perf-virtualize-large-lists.md +187 -0
- package/skills/vue-best-practices/references/plugins.md +166 -0
- package/skills/vue-best-practices/references/reactivity.md +344 -0
- package/skills/vue-best-practices/references/render-functions.md +201 -0
- package/skills/vue-best-practices/references/sfc.md +310 -0
- package/skills/vue-best-practices/references/state-management.md +135 -0
- package/skills/vue-best-practices/references/updated-hook-performance.md +187 -0
- package/skills/vue-pinia-best-practices/SKILL.md +21 -0
- package/skills/vue-pinia-best-practices/reference/pinia-no-active-pinia-error.md +248 -0
- package/skills/vue-pinia-best-practices/reference/pinia-setup-store-return-all-state.md +227 -0
- package/skills/vue-pinia-best-practices/reference/pinia-store-destructuring-breaks-reactivity.md +193 -0
- package/skills/vue-pinia-best-practices/reference/state-url-for-ephemeral-filters.md +238 -0
- package/skills/vue-pinia-best-practices/reference/state-use-pinia-for-large-apps.md +262 -0
- package/skills/vue-pinia-best-practices/reference/store-method-binding-parentheses.md +191 -0
- package/skills/zig-0.16/SKILL.md +840 -0
- package/skills/zig-0.16/scripts/check-zig-version.sh +21 -0
- package/src/cli/analyses.ts +280 -0
- package/src/cli/index.ts +108 -0
- package/src/cli/serve.ts +192 -0
- package/src/cli/smoke.ts +131 -0
- package/src/cli/status.test.ts +204 -0
- package/src/cli/status.ts +263 -0
- package/src/cli/vacuum.test.ts +82 -0
- package/src/cli/vacuum.ts +96 -0
- package/src/config/schema.test.ts +88 -0
- package/src/config/schema.ts +64 -0
- package/src/db/analyses-migration.test.ts +210 -0
- package/src/db/analyses.test.ts +466 -0
- package/src/db/analyses.ts +375 -0
- package/src/db/auto-checkpoint.ts +131 -0
- package/src/db/client.test.ts +129 -0
- package/src/db/client.ts +55 -0
- package/src/db/fts-escape.ts +20 -0
- package/src/db/incidents.test.ts +201 -0
- package/src/db/incidents.ts +93 -0
- package/src/db/index.ts +86 -0
- package/src/db/migrations-v13.test.ts +141 -0
- package/src/db/migrations-v8.test.ts +301 -0
- package/src/db/migrations.ts +147 -0
- package/src/db/plan-archive.test.ts +180 -0
- package/src/db/plan-archive.ts +274 -0
- package/src/db/plan-create.test.ts +276 -0
- package/src/db/plan-create.ts +78 -0
- package/src/db/plan-files.test.ts +289 -0
- package/src/db/plan-update-status.ts +287 -0
- package/src/db/plans.test.ts +490 -0
- package/src/db/plans.ts +534 -0
- package/src/db/resolve-project-dir.test.ts +143 -0
- package/src/db/resolve-project-dir.ts +75 -0
- package/src/db/rollbacks.test.ts +150 -0
- package/src/db/rollbacks.ts +67 -0
- package/src/db/schema.ts +907 -0
- package/src/db/sessions.test.ts +80 -0
- package/src/db/sessions.ts +135 -0
- package/src/db/shutdown.test.ts +147 -0
- package/src/db/shutdown.ts +45 -0
- package/src/db/tasks.test.ts +921 -0
- package/src/db/tasks.ts +747 -0
- package/src/db/types.ts +619 -0
- package/src/http/__tests__/auth.test.ts +196 -0
- package/src/http/__tests__/routes.test.ts +465 -0
- package/src/http/__tests__/sse.test.ts +317 -0
- package/src/http/auth.ts +72 -0
- package/src/http/middleware/cors.ts +53 -0
- package/src/http/middleware/security-headers.ts +21 -0
- package/src/http/routes/events.ts +112 -0
- package/src/http/routes/health.ts +51 -0
- package/src/http/routes/plans.ts +66 -0
- package/src/http/routes/sessions.ts +50 -0
- package/src/http/routes/tasks.ts +60 -0
- package/src/http/server.ts +95 -0
- package/src/http/sse.ts +116 -0
- package/src/index.ts +37 -0
- package/src/lib.ts +65 -0
- package/src/mem/scoped.ts +65 -0
- package/src/orchestrator/background.test.ts +268 -0
- package/src/orchestrator/background.ts +293 -0
- package/src/orchestrator/memory-hook.ts +182 -0
- package/src/orchestrator/reconciler.ts +123 -0
- package/src/orchestrator/scheduler.test.ts +300 -0
- package/src/orchestrator/scheduler.ts +243 -0
- package/src/plugin.test.ts +2574 -0
- package/src/plugin.ts +1690 -0
- package/src/sdk/client.ts +66 -0
- package/src/worktrees/manager.ts +236 -0
- package/src/worktrees/state.ts +87 -0
- package/tests/integration/ranger-flow.test.ts +257 -0
- package/tools/analysis_archive.ts +28 -0
- package/tools/analysis_create.ts +55 -0
- package/tools/analysis_get.ts +33 -0
- package/tools/analysis_link_plan.ts +44 -0
- package/tools/analysis_list.ts +48 -0
- package/tools/analysis_search.ts +36 -0
- package/tools/analysis_update.ts +44 -0
- package/tools/plan_approve.ts +31 -0
- package/tools/plan_create.ts +58 -0
- package/tools/plan_get.ts +40 -0
- package/tools/plan_list.ts +37 -0
- package/tools/plan_search.ts +34 -0
- package/tools/plan_update_status.ts +71 -0
- package/tools/session_checkpoint.ts +31 -0
- package/tools/session_end.ts +26 -0
- package/tools/session_start.ts +43 -0
- package/tools/task_create_batch.ts +70 -0
- package/tools/task_list.ts +35 -0
- package/tools/task_next_for_agent.ts +30 -0
- package/tools/task_search.ts +34 -0
- package/tools/task_update_status.ts +37 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,487 @@
|
|
|
1
|
+
# Advanced Modern JavaScript Patterns
|
|
2
|
+
|
|
3
|
+
Advanced patterns covering functional programming, modern class features, ES6 modules, iterators, generators, modern operators, and performance optimization.
|
|
4
|
+
|
|
5
|
+
## Functional Programming Patterns
|
|
6
|
+
|
|
7
|
+
### 1. Array Methods
|
|
8
|
+
|
|
9
|
+
**Map, Filter, Reduce:**
|
|
10
|
+
|
|
11
|
+
```javascript
|
|
12
|
+
const users = [
|
|
13
|
+
{ id: 1, name: "John", age: 30, active: true },
|
|
14
|
+
{ id: 2, name: "Jane", age: 25, active: false },
|
|
15
|
+
{ id: 3, name: "Bob", age: 35, active: true },
|
|
16
|
+
];
|
|
17
|
+
|
|
18
|
+
// Map - Transform array
|
|
19
|
+
const names = users.map((user) => user.name);
|
|
20
|
+
const upperNames = users.map((user) => user.name.toUpperCase());
|
|
21
|
+
|
|
22
|
+
// Filter - Select elements
|
|
23
|
+
const activeUsers = users.filter((user) => user.active);
|
|
24
|
+
const adults = users.filter((user) => user.age >= 18);
|
|
25
|
+
|
|
26
|
+
// Reduce - Aggregate data
|
|
27
|
+
const totalAge = users.reduce((sum, user) => sum + user.age, 0);
|
|
28
|
+
const avgAge = totalAge / users.length;
|
|
29
|
+
|
|
30
|
+
// Group by property
|
|
31
|
+
const byActive = users.reduce((groups, user) => {
|
|
32
|
+
const key = user.active ? "active" : "inactive";
|
|
33
|
+
return {
|
|
34
|
+
...groups,
|
|
35
|
+
[key]: [...(groups[key] || []), user],
|
|
36
|
+
};
|
|
37
|
+
}, {});
|
|
38
|
+
|
|
39
|
+
// Chaining methods
|
|
40
|
+
const result = users
|
|
41
|
+
.filter((user) => user.active)
|
|
42
|
+
.map((user) => user.name)
|
|
43
|
+
.sort()
|
|
44
|
+
.join(", ");
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Advanced Array Methods:**
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
// Find - First matching element
|
|
51
|
+
const user = users.find((u) => u.id === 2);
|
|
52
|
+
|
|
53
|
+
// FindIndex - Index of first match
|
|
54
|
+
const index = users.findIndex((u) => u.name === "Jane");
|
|
55
|
+
|
|
56
|
+
// Some - At least one matches
|
|
57
|
+
const hasActive = users.some((u) => u.active);
|
|
58
|
+
|
|
59
|
+
// Every - All match
|
|
60
|
+
const allAdults = users.every((u) => u.age >= 18);
|
|
61
|
+
|
|
62
|
+
// FlatMap - Map and flatten
|
|
63
|
+
const userTags = [
|
|
64
|
+
{ name: "John", tags: ["admin", "user"] },
|
|
65
|
+
{ name: "Jane", tags: ["user"] },
|
|
66
|
+
];
|
|
67
|
+
const allTags = userTags.flatMap((u) => u.tags);
|
|
68
|
+
|
|
69
|
+
// From - Create array from iterable
|
|
70
|
+
const str = "hello";
|
|
71
|
+
const chars = Array.from(str);
|
|
72
|
+
const numbers = Array.from({ length: 5 }, (_, i) => i + 1);
|
|
73
|
+
|
|
74
|
+
// Of - Create array from arguments
|
|
75
|
+
const arr = Array.of(1, 2, 3);
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### 2. Higher-Order Functions
|
|
79
|
+
|
|
80
|
+
**Functions as Arguments:**
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
// Custom forEach
|
|
84
|
+
function forEach(array, callback) {
|
|
85
|
+
for (let i = 0; i < array.length; i++) {
|
|
86
|
+
callback(array[i], i, array);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// Custom map
|
|
91
|
+
function map(array, transform) {
|
|
92
|
+
const result = [];
|
|
93
|
+
for (const item of array) {
|
|
94
|
+
result.push(transform(item));
|
|
95
|
+
}
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Custom filter
|
|
100
|
+
function filter(array, predicate) {
|
|
101
|
+
const result = [];
|
|
102
|
+
for (const item of array) {
|
|
103
|
+
if (predicate(item)) {
|
|
104
|
+
result.push(item);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return result;
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
**Functions Returning Functions:**
|
|
112
|
+
|
|
113
|
+
```javascript
|
|
114
|
+
// Currying
|
|
115
|
+
const multiply = (a) => (b) => a * b;
|
|
116
|
+
const double = multiply(2);
|
|
117
|
+
const triple = multiply(3);
|
|
118
|
+
|
|
119
|
+
console.log(double(5)); // 10
|
|
120
|
+
console.log(triple(5)); // 15
|
|
121
|
+
|
|
122
|
+
// Partial application
|
|
123
|
+
function partial(fn, ...args) {
|
|
124
|
+
return (...moreArgs) => fn(...args, ...moreArgs);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const add = (a, b, c) => a + b + c;
|
|
128
|
+
const add5 = partial(add, 5);
|
|
129
|
+
console.log(add5(3, 2)); // 10
|
|
130
|
+
|
|
131
|
+
// Memoization
|
|
132
|
+
function memoize(fn) {
|
|
133
|
+
const cache = new Map();
|
|
134
|
+
return (...args) => {
|
|
135
|
+
const key = JSON.stringify(args);
|
|
136
|
+
if (cache.has(key)) {
|
|
137
|
+
return cache.get(key);
|
|
138
|
+
}
|
|
139
|
+
const result = fn(...args);
|
|
140
|
+
cache.set(key, result);
|
|
141
|
+
return result;
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const fibonacci = memoize((n) => {
|
|
146
|
+
if (n <= 1) return n;
|
|
147
|
+
return fibonacci(n - 1) + fibonacci(n - 2);
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### 3. Composition and Piping
|
|
152
|
+
|
|
153
|
+
```javascript
|
|
154
|
+
// Function composition
|
|
155
|
+
const compose =
|
|
156
|
+
(...fns) =>
|
|
157
|
+
(x) =>
|
|
158
|
+
fns.reduceRight((acc, fn) => fn(acc), x);
|
|
159
|
+
|
|
160
|
+
const pipe =
|
|
161
|
+
(...fns) =>
|
|
162
|
+
(x) =>
|
|
163
|
+
fns.reduce((acc, fn) => fn(acc), x);
|
|
164
|
+
|
|
165
|
+
// Example usage
|
|
166
|
+
const addOne = (x) => x + 1;
|
|
167
|
+
const double = (x) => x * 2;
|
|
168
|
+
const square = (x) => x * x;
|
|
169
|
+
|
|
170
|
+
const composed = compose(square, double, addOne);
|
|
171
|
+
console.log(composed(3)); // ((3 + 1) * 2)^2 = 64
|
|
172
|
+
|
|
173
|
+
const piped = pipe(addOne, double, square);
|
|
174
|
+
console.log(piped(3)); // ((3 + 1) * 2)^2 = 64
|
|
175
|
+
|
|
176
|
+
// Practical example
|
|
177
|
+
const processUser = pipe(
|
|
178
|
+
(user) => ({ ...user, name: user.name.trim() }),
|
|
179
|
+
(user) => ({ ...user, email: user.email.toLowerCase() }),
|
|
180
|
+
(user) => ({ ...user, age: parseInt(user.age) }),
|
|
181
|
+
);
|
|
182
|
+
|
|
183
|
+
const user = processUser({
|
|
184
|
+
name: " John ",
|
|
185
|
+
email: "JOHN@EXAMPLE.COM",
|
|
186
|
+
age: "30",
|
|
187
|
+
});
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
### 4. Pure Functions and Immutability
|
|
191
|
+
|
|
192
|
+
```javascript
|
|
193
|
+
// Impure function (modifies input)
|
|
194
|
+
function addItemImpure(cart, item) {
|
|
195
|
+
cart.items.push(item);
|
|
196
|
+
cart.total += item.price;
|
|
197
|
+
return cart;
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
// Pure function (no side effects)
|
|
201
|
+
function addItemPure(cart, item) {
|
|
202
|
+
return {
|
|
203
|
+
...cart,
|
|
204
|
+
items: [...cart.items, item],
|
|
205
|
+
total: cart.total + item.price,
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
// Immutable array operations
|
|
210
|
+
const numbers = [1, 2, 3, 4, 5];
|
|
211
|
+
|
|
212
|
+
// Add to array
|
|
213
|
+
const withSix = [...numbers, 6];
|
|
214
|
+
|
|
215
|
+
// Remove from array
|
|
216
|
+
const withoutThree = numbers.filter((n) => n !== 3);
|
|
217
|
+
|
|
218
|
+
// Update array element
|
|
219
|
+
const doubled = numbers.map((n) => (n === 3 ? n * 2 : n));
|
|
220
|
+
|
|
221
|
+
// Immutable object operations
|
|
222
|
+
const user = { name: "John", age: 30 };
|
|
223
|
+
|
|
224
|
+
// Update property
|
|
225
|
+
const olderUser = { ...user, age: 31 };
|
|
226
|
+
|
|
227
|
+
// Add property
|
|
228
|
+
const withEmail = { ...user, email: "john@example.com" };
|
|
229
|
+
|
|
230
|
+
// Remove property
|
|
231
|
+
const { age, ...withoutAge } = user;
|
|
232
|
+
|
|
233
|
+
// Deep cloning (simple approach)
|
|
234
|
+
const deepClone = (obj) => JSON.parse(JSON.stringify(obj));
|
|
235
|
+
|
|
236
|
+
// Better deep cloning
|
|
237
|
+
const structuredClone = (obj) => globalThis.structuredClone(obj);
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
## Modern Class Features
|
|
241
|
+
|
|
242
|
+
```javascript
|
|
243
|
+
// Class syntax
|
|
244
|
+
class User {
|
|
245
|
+
// Private fields
|
|
246
|
+
#password;
|
|
247
|
+
|
|
248
|
+
// Public fields
|
|
249
|
+
id;
|
|
250
|
+
name;
|
|
251
|
+
|
|
252
|
+
// Static field
|
|
253
|
+
static count = 0;
|
|
254
|
+
|
|
255
|
+
constructor(id, name, password) {
|
|
256
|
+
this.id = id;
|
|
257
|
+
this.name = name;
|
|
258
|
+
this.#password = password;
|
|
259
|
+
User.count++;
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
// Public method
|
|
263
|
+
greet() {
|
|
264
|
+
return `Hello, ${this.name}`;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Private method
|
|
268
|
+
#hashPassword(password) {
|
|
269
|
+
return `hashed_${password}`;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Getter
|
|
273
|
+
get displayName() {
|
|
274
|
+
return this.name.toUpperCase();
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// Setter
|
|
278
|
+
set password(newPassword) {
|
|
279
|
+
this.#password = this.#hashPassword(newPassword);
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
// Static method
|
|
283
|
+
static create(id, name, password) {
|
|
284
|
+
return new User(id, name, password);
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// Inheritance
|
|
289
|
+
class Admin extends User {
|
|
290
|
+
constructor(id, name, password, role) {
|
|
291
|
+
super(id, name, password);
|
|
292
|
+
this.role = role;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
greet() {
|
|
296
|
+
return `${super.greet()}, I'm an admin`;
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
```
|
|
300
|
+
|
|
301
|
+
## Modules (ES6)
|
|
302
|
+
|
|
303
|
+
```javascript
|
|
304
|
+
// Exporting
|
|
305
|
+
// math.js
|
|
306
|
+
export const PI = 3.14159;
|
|
307
|
+
export function add(a, b) {
|
|
308
|
+
return a + b;
|
|
309
|
+
}
|
|
310
|
+
export class Calculator {
|
|
311
|
+
// ...
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
// Default export
|
|
315
|
+
export default function multiply(a, b) {
|
|
316
|
+
return a * b;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Importing
|
|
320
|
+
// app.js
|
|
321
|
+
import multiply, { PI, add, Calculator } from "./math.js";
|
|
322
|
+
|
|
323
|
+
// Rename imports
|
|
324
|
+
import { add as sum } from "./math.js";
|
|
325
|
+
|
|
326
|
+
// Import all
|
|
327
|
+
import * as Math from "./math.js";
|
|
328
|
+
|
|
329
|
+
// Dynamic imports
|
|
330
|
+
const module = await import("./math.js");
|
|
331
|
+
const { add } = await import("./math.js");
|
|
332
|
+
|
|
333
|
+
// Conditional loading
|
|
334
|
+
if (condition) {
|
|
335
|
+
const module = await import("./feature.js");
|
|
336
|
+
module.init();
|
|
337
|
+
}
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
## Iterators and Generators
|
|
341
|
+
|
|
342
|
+
```javascript
|
|
343
|
+
// Custom iterator
|
|
344
|
+
const range = {
|
|
345
|
+
from: 1,
|
|
346
|
+
to: 5,
|
|
347
|
+
|
|
348
|
+
[Symbol.iterator]() {
|
|
349
|
+
return {
|
|
350
|
+
current: this.from,
|
|
351
|
+
last: this.to,
|
|
352
|
+
|
|
353
|
+
next() {
|
|
354
|
+
if (this.current <= this.last) {
|
|
355
|
+
return { done: false, value: this.current++ };
|
|
356
|
+
} else {
|
|
357
|
+
return { done: true };
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
};
|
|
361
|
+
},
|
|
362
|
+
};
|
|
363
|
+
|
|
364
|
+
for (const num of range) {
|
|
365
|
+
console.log(num); // 1, 2, 3, 4, 5
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// Generator function
|
|
369
|
+
function* rangeGenerator(from, to) {
|
|
370
|
+
for (let i = from; i <= to; i++) {
|
|
371
|
+
yield i;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
for (const num of rangeGenerator(1, 5)) {
|
|
376
|
+
console.log(num);
|
|
377
|
+
}
|
|
378
|
+
|
|
379
|
+
// Infinite generator
|
|
380
|
+
function* fibonacci() {
|
|
381
|
+
let [prev, curr] = [0, 1];
|
|
382
|
+
while (true) {
|
|
383
|
+
yield curr;
|
|
384
|
+
[prev, curr] = [curr, prev + curr];
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
// Async generator
|
|
389
|
+
async function* fetchPages(url) {
|
|
390
|
+
let page = 1;
|
|
391
|
+
while (true) {
|
|
392
|
+
const response = await fetch(`${url}?page=${page}`);
|
|
393
|
+
const data = await response.json();
|
|
394
|
+
if (data.length === 0) break;
|
|
395
|
+
yield data;
|
|
396
|
+
page++;
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
for await (const page of fetchPages("/api/users")) {
|
|
401
|
+
console.log(page);
|
|
402
|
+
}
|
|
403
|
+
```
|
|
404
|
+
|
|
405
|
+
## Modern Operators
|
|
406
|
+
|
|
407
|
+
```javascript
|
|
408
|
+
// Optional chaining
|
|
409
|
+
const user = { name: "John", address: { city: "NYC" } };
|
|
410
|
+
const city = user?.address?.city;
|
|
411
|
+
const zipCode = user?.address?.zipCode; // undefined
|
|
412
|
+
|
|
413
|
+
// Function call
|
|
414
|
+
const result = obj.method?.();
|
|
415
|
+
|
|
416
|
+
// Array access
|
|
417
|
+
const first = arr?.[0];
|
|
418
|
+
|
|
419
|
+
// Nullish coalescing
|
|
420
|
+
const value = null ?? "default"; // 'default'
|
|
421
|
+
const value = undefined ?? "default"; // 'default'
|
|
422
|
+
const value = 0 ?? "default"; // 0 (not 'default')
|
|
423
|
+
const value = "" ?? "default"; // '' (not 'default')
|
|
424
|
+
|
|
425
|
+
// Logical assignment
|
|
426
|
+
let a = null;
|
|
427
|
+
a ??= "default"; // a = 'default'
|
|
428
|
+
|
|
429
|
+
let b = 5;
|
|
430
|
+
b ??= 10; // b = 5 (unchanged)
|
|
431
|
+
|
|
432
|
+
let obj = { count: 0 };
|
|
433
|
+
obj.count ||= 1; // obj.count = 1
|
|
434
|
+
obj.count &&= 2; // obj.count = 2
|
|
435
|
+
```
|
|
436
|
+
|
|
437
|
+
## Performance Optimization
|
|
438
|
+
|
|
439
|
+
```javascript
|
|
440
|
+
// Debounce
|
|
441
|
+
function debounce(fn, delay) {
|
|
442
|
+
let timeoutId;
|
|
443
|
+
return (...args) => {
|
|
444
|
+
clearTimeout(timeoutId);
|
|
445
|
+
timeoutId = setTimeout(() => fn(...args), delay);
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
const searchDebounced = debounce(search, 300);
|
|
450
|
+
|
|
451
|
+
// Throttle
|
|
452
|
+
function throttle(fn, limit) {
|
|
453
|
+
let inThrottle;
|
|
454
|
+
return (...args) => {
|
|
455
|
+
if (!inThrottle) {
|
|
456
|
+
fn(...args);
|
|
457
|
+
inThrottle = true;
|
|
458
|
+
setTimeout(() => (inThrottle = false), limit);
|
|
459
|
+
}
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
|
|
463
|
+
const scrollThrottled = throttle(handleScroll, 100);
|
|
464
|
+
|
|
465
|
+
// Lazy evaluation
|
|
466
|
+
function* lazyMap(iterable, transform) {
|
|
467
|
+
for (const item of iterable) {
|
|
468
|
+
yield transform(item);
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
// Use only what you need
|
|
473
|
+
const numbers = [1, 2, 3, 4, 5];
|
|
474
|
+
const doubled = lazyMap(numbers, (x) => x * 2);
|
|
475
|
+
const first = doubled.next().value; // Only computes first value
|
|
476
|
+
```
|
|
477
|
+
|
|
478
|
+
## Common Pitfalls
|
|
479
|
+
|
|
480
|
+
1. **this binding confusion**: Use arrow functions or bind()
|
|
481
|
+
2. **Async/await without error handling**: Always use try/catch
|
|
482
|
+
3. **Promise creation unnecessary**: Don't wrap already async functions
|
|
483
|
+
4. **Mutation of objects**: Use spread operator or Object.assign()
|
|
484
|
+
5. **Forgetting await**: Async functions return promises
|
|
485
|
+
6. **Blocking event loop**: Avoid synchronous operations
|
|
486
|
+
7. **Memory leaks**: Clean up event listeners and timers
|
|
487
|
+
8. **Not handling promise rejections**: Use catch() or try/catch
|