ads-fe 0.0.1
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/README.md +99 -0
- package/dist/cli.js +545 -0
- package/dist/meta.js +93 -0
- package/package.json +43 -0
- package/skill.md +66 -0
- package/skills/core/SKILL.md +66 -0
- package/skills/core/references/app-development.md +45 -0
- package/skills/core/references/git.md +66 -0
- package/skills/core/references/monorepo.md +124 -0
- package/skills/element-plus-vue3/LICENSE.md +405 -0
- package/skills/element-plus-vue3/LICENSE.txt +202 -0
- package/skills/element-plus-vue3/SKILL.md +218 -0
- package/skills/element-plus-vue3/SYNC.md +5 -0
- package/skills/element-plus-vue3/api/component-api.md +94 -0
- package/skills/element-plus-vue3/api/global-config.md +89 -0
- package/skills/element-plus-vue3/api/props-and-events.md +101 -0
- package/skills/element-plus-vue3/examples/components/button.md +99 -0
- package/skills/element-plus-vue3/examples/components/date-picker.md +115 -0
- package/skills/element-plus-vue3/examples/components/dialog.md +106 -0
- package/skills/element-plus-vue3/examples/components/form.md +127 -0
- package/skills/element-plus-vue3/examples/components/input.md +123 -0
- package/skills/element-plus-vue3/examples/components/message.md +93 -0
- package/skills/element-plus-vue3/examples/components/overview.md +59 -0
- package/skills/element-plus-vue3/examples/components/select.md +133 -0
- package/skills/element-plus-vue3/examples/components/table.md +166 -0
- package/skills/element-plus-vue3/examples/guide/design.md +68 -0
- package/skills/element-plus-vue3/examples/guide/global-config.md +95 -0
- package/skills/element-plus-vue3/examples/guide/i18n.md +95 -0
- package/skills/element-plus-vue3/examples/guide/installation.md +110 -0
- package/skills/element-plus-vue3/examples/guide/quick-start.md +103 -0
- package/skills/element-plus-vue3/examples/guide/theme.md +78 -0
- package/skills/element-plus-vue3/templates/component-usage.md +92 -0
- package/skills/element-plus-vue3/templates/installation.md +82 -0
- package/skills/element-plus-vue3/templates/project-setup.md +83 -0
- package/skills/node/LICENSE.md +21 -0
- package/skills/node/SKILL.md +94 -0
- package/skills/node/SYNC.md +5 -0
- package/skills/node/rules/assets/graceful-server.test.ts +88 -0
- package/skills/node/rules/assets/graceful-server.ts +80 -0
- package/skills/node/rules/async-patterns.md +136 -0
- package/skills/node/rules/caching.md +198 -0
- package/skills/node/rules/environment.md +253 -0
- package/skills/node/rules/error-handling.md +164 -0
- package/skills/node/rules/flaky-tests.md +439 -0
- package/skills/node/rules/graceful-shutdown.md +204 -0
- package/skills/node/rules/logging.md +205 -0
- package/skills/node/rules/modules.md +105 -0
- package/skills/node/rules/node-modules-exploration.md +172 -0
- package/skills/node/rules/performance.md +130 -0
- package/skills/node/rules/profiling.md +183 -0
- package/skills/node/rules/streams.md +213 -0
- package/skills/node/rules/stuck-processes-and-tests.md +124 -0
- package/skills/node/rules/testing.md +218 -0
- package/skills/node/rules/typescript.md +262 -0
- package/skills/node/tile.json +11 -0
- package/skills/nuxt/GENERATION.md +5 -0
- package/skills/nuxt/LICENSE.md +21 -0
- package/skills/nuxt/SKILL.md +55 -0
- package/skills/nuxt/SYNC.md +5 -0
- package/skills/nuxt/references/advanced-hooks.md +289 -0
- package/skills/nuxt/references/advanced-layers.md +299 -0
- package/skills/nuxt/references/advanced-module-authoring.md +554 -0
- package/skills/nuxt/references/best-practices-data-fetching.md +357 -0
- package/skills/nuxt/references/best-practices-ssr.md +355 -0
- package/skills/nuxt/references/core-cli.md +263 -0
- package/skills/nuxt/references/core-config.md +162 -0
- package/skills/nuxt/references/core-data-fetching.md +236 -0
- package/skills/nuxt/references/core-deployment.md +224 -0
- package/skills/nuxt/references/core-directory-structure.md +269 -0
- package/skills/nuxt/references/core-modules.md +292 -0
- package/skills/nuxt/references/core-routing.md +226 -0
- package/skills/nuxt/references/features-components-autoimport.md +328 -0
- package/skills/nuxt/references/features-components.md +264 -0
- package/skills/nuxt/references/features-composables.md +276 -0
- package/skills/nuxt/references/features-server.md +265 -0
- package/skills/nuxt/references/features-state.md +194 -0
- package/skills/nuxt/references/rendering-modes.md +237 -0
- package/skills/pinia/GENERATION.md +5 -0
- package/skills/pinia/LICENSE.md +21 -0
- package/skills/pinia/SKILL.md +59 -0
- package/skills/pinia/SYNC.md +5 -0
- package/skills/pinia/references/advanced-hmr.md +61 -0
- package/skills/pinia/references/advanced-nuxt.md +119 -0
- package/skills/pinia/references/advanced-ssr.md +121 -0
- package/skills/pinia/references/best-practices-outside-component.md +115 -0
- package/skills/pinia/references/best-practices-testing.md +212 -0
- package/skills/pinia/references/core-stores.md +389 -0
- package/skills/pinia/references/features-composables.md +114 -0
- package/skills/pinia/references/features-composing-stores.md +134 -0
- package/skills/pinia/references/features-plugins.md +203 -0
- package/skills/pnpm/GENERATION.md +5 -0
- package/skills/pnpm/LICENSE.md +21 -0
- package/skills/pnpm/SKILL.md +42 -0
- package/skills/pnpm/SYNC.md +5 -0
- package/skills/pnpm/references/best-practices-ci.md +285 -0
- package/skills/pnpm/references/best-practices-migration.md +291 -0
- package/skills/pnpm/references/best-practices-performance.md +284 -0
- package/skills/pnpm/references/core-cli.md +229 -0
- package/skills/pnpm/references/core-config.md +188 -0
- package/skills/pnpm/references/core-store.md +179 -0
- package/skills/pnpm/references/core-workspaces.md +205 -0
- package/skills/pnpm/references/features-aliases.md +168 -0
- package/skills/pnpm/references/features-catalogs.md +159 -0
- package/skills/pnpm/references/features-hooks.md +233 -0
- package/skills/pnpm/references/features-overrides.md +184 -0
- package/skills/pnpm/references/features-patches.md +201 -0
- package/skills/pnpm/references/features-peer-deps.md +250 -0
- package/skills/slidev/LICENSE.md +21 -0
- package/skills/slidev/README.md +61 -0
- package/skills/slidev/SKILL.md +189 -0
- package/skills/slidev/SYNC.md +5 -0
- package/skills/slidev/references/animation-click-marker.md +37 -0
- package/skills/slidev/references/animation-drawing.md +68 -0
- package/skills/slidev/references/animation-rough-marker.md +53 -0
- package/skills/slidev/references/api-slide-hooks.md +37 -0
- package/skills/slidev/references/build-og-image.md +36 -0
- package/skills/slidev/references/build-pdf.md +40 -0
- package/skills/slidev/references/build-remote-assets.md +34 -0
- package/skills/slidev/references/build-seo-meta.md +43 -0
- package/skills/slidev/references/code-groups.md +64 -0
- package/skills/slidev/references/code-import-snippet.md +55 -0
- package/skills/slidev/references/code-line-highlighting.md +50 -0
- package/skills/slidev/references/code-line-numbers.md +46 -0
- package/skills/slidev/references/code-magic-move.md +57 -0
- package/skills/slidev/references/code-max-height.md +37 -0
- package/skills/slidev/references/code-twoslash.md +42 -0
- package/skills/slidev/references/core-animations.md +196 -0
- package/skills/slidev/references/core-cli.md +140 -0
- package/skills/slidev/references/core-components.md +197 -0
- package/skills/slidev/references/core-exporting.md +148 -0
- package/skills/slidev/references/core-frontmatter.md +195 -0
- package/skills/slidev/references/core-global-context.md +155 -0
- package/skills/slidev/references/core-headmatter.md +188 -0
- package/skills/slidev/references/core-hosting.md +152 -0
- package/skills/slidev/references/core-layouts.md +286 -0
- package/skills/slidev/references/core-syntax.md +155 -0
- package/skills/slidev/references/diagram-latex.md +55 -0
- package/skills/slidev/references/diagram-mermaid.md +44 -0
- package/skills/slidev/references/diagram-plantuml.md +45 -0
- package/skills/slidev/references/editor-monaco-run.md +44 -0
- package/skills/slidev/references/editor-monaco-write.md +24 -0
- package/skills/slidev/references/editor-monaco.md +50 -0
- package/skills/slidev/references/editor-prettier.md +40 -0
- package/skills/slidev/references/editor-side.md +23 -0
- package/skills/slidev/references/editor-vscode.md +55 -0
- package/skills/slidev/references/layout-canvas-size.md +25 -0
- package/skills/slidev/references/layout-draggable.md +57 -0
- package/skills/slidev/references/layout-global-layers.md +50 -0
- package/skills/slidev/references/layout-slots.md +75 -0
- package/skills/slidev/references/layout-transform.md +33 -0
- package/skills/slidev/references/layout-zoom.md +39 -0
- package/skills/slidev/references/presenter-notes-ruby.md +35 -0
- package/skills/slidev/references/presenter-recording.md +30 -0
- package/skills/slidev/references/presenter-remote.md +40 -0
- package/skills/slidev/references/presenter-timer.md +34 -0
- package/skills/slidev/references/style-direction.md +34 -0
- package/skills/slidev/references/style-icons.md +46 -0
- package/skills/slidev/references/style-scoped.md +50 -0
- package/skills/slidev/references/syntax-block-frontmatter.md +39 -0
- package/skills/slidev/references/syntax-comark.md +51 -0
- package/skills/slidev/references/syntax-frontmatter-merging.md +49 -0
- package/skills/slidev/references/syntax-importing-slides.md +60 -0
- package/skills/slidev/references/tool-eject-theme.md +27 -0
- package/skills/tsdown/LICENSE.md +22 -0
- package/skills/tsdown/README.md +77 -0
- package/skills/tsdown/SKILL.md +416 -0
- package/skills/tsdown/SYNC.md +5 -0
- package/skills/tsdown/references/README.md +139 -0
- package/skills/tsdown/references/advanced-benchmark.md +8 -0
- package/skills/tsdown/references/advanced-ci.md +89 -0
- package/skills/tsdown/references/advanced-hooks.md +363 -0
- package/skills/tsdown/references/advanced-plugins.md +381 -0
- package/skills/tsdown/references/advanced-programmatic.md +378 -0
- package/skills/tsdown/references/advanced-rolldown-options.md +117 -0
- package/skills/tsdown/references/guide-getting-started.md +183 -0
- package/skills/tsdown/references/guide-introduction.md +42 -0
- package/skills/tsdown/references/guide-migrate-from-tsup.md +199 -0
- package/skills/tsdown/references/option-cjs-default.md +98 -0
- package/skills/tsdown/references/option-cleaning.md +275 -0
- package/skills/tsdown/references/option-config-file.md +291 -0
- package/skills/tsdown/references/option-css.md +301 -0
- package/skills/tsdown/references/option-dependencies.md +385 -0
- package/skills/tsdown/references/option-dts.md +251 -0
- package/skills/tsdown/references/option-entry.md +211 -0
- package/skills/tsdown/references/option-exe.md +120 -0
- package/skills/tsdown/references/option-lint.md +127 -0
- package/skills/tsdown/references/option-log-level.md +91 -0
- package/skills/tsdown/references/option-minification.md +177 -0
- package/skills/tsdown/references/option-output-directory.md +272 -0
- package/skills/tsdown/references/option-output-format.md +183 -0
- package/skills/tsdown/references/option-package-exports.md +320 -0
- package/skills/tsdown/references/option-platform.md +256 -0
- package/skills/tsdown/references/option-root.md +88 -0
- package/skills/tsdown/references/option-shims.md +299 -0
- package/skills/tsdown/references/option-sourcemap.md +301 -0
- package/skills/tsdown/references/option-target.md +222 -0
- package/skills/tsdown/references/option-tree-shaking.md +335 -0
- package/skills/tsdown/references/option-unbundle.md +310 -0
- package/skills/tsdown/references/option-watch-mode.md +261 -0
- package/skills/tsdown/references/recipe-react.md +338 -0
- package/skills/tsdown/references/recipe-solid.md +42 -0
- package/skills/tsdown/references/recipe-svelte.md +54 -0
- package/skills/tsdown/references/recipe-vue.md +387 -0
- package/skills/tsdown/references/recipe-wasm.md +125 -0
- package/skills/tsdown/references/reference-cli.md +472 -0
- package/skills/turborepo/LICENSE.md +7 -0
- package/skills/turborepo/SKILL.md +951 -0
- package/skills/turborepo/SYNC.md +5 -0
- package/skills/turborepo/command/turborepo.md +70 -0
- package/skills/turborepo/references/best-practices/RULE.md +241 -0
- package/skills/turborepo/references/best-practices/dependencies.md +246 -0
- package/skills/turborepo/references/best-practices/packages.md +335 -0
- package/skills/turborepo/references/best-practices/structure.md +297 -0
- package/skills/turborepo/references/boundaries/RULE.md +126 -0
- package/skills/turborepo/references/caching/RULE.md +153 -0
- package/skills/turborepo/references/caching/gotchas.md +190 -0
- package/skills/turborepo/references/caching/remote-cache.md +127 -0
- package/skills/turborepo/references/ci/RULE.md +79 -0
- package/skills/turborepo/references/ci/github-actions.md +162 -0
- package/skills/turborepo/references/ci/patterns.md +145 -0
- package/skills/turborepo/references/ci/vercel.md +103 -0
- package/skills/turborepo/references/cli/RULE.md +100 -0
- package/skills/turborepo/references/cli/commands.md +297 -0
- package/skills/turborepo/references/configuration/RULE.md +235 -0
- package/skills/turborepo/references/configuration/global-options.md +239 -0
- package/skills/turborepo/references/configuration/gotchas.md +368 -0
- package/skills/turborepo/references/configuration/tasks.md +325 -0
- package/skills/turborepo/references/environment/RULE.md +123 -0
- package/skills/turborepo/references/environment/gotchas.md +175 -0
- package/skills/turborepo/references/environment/modes.md +101 -0
- package/skills/turborepo/references/filtering/RULE.md +148 -0
- package/skills/turborepo/references/filtering/patterns.md +152 -0
- package/skills/turborepo/references/watch/RULE.md +99 -0
- package/skills/vite/GENERATION.md +5 -0
- package/skills/vite/LICENSE.md +21 -0
- package/skills/vite/SKILL.md +72 -0
- package/skills/vite/SYNC.md +5 -0
- package/skills/vite/references/build-and-ssr.md +164 -0
- package/skills/vite/references/core-config.md +162 -0
- package/skills/vite/references/core-features.md +205 -0
- package/skills/vite/references/core-plugin-api.md +235 -0
- package/skills/vite/references/environment-api.md +108 -0
- package/skills/vite/references/rolldown-migration.md +157 -0
- package/skills/vitepress/GENERATION.md +5 -0
- package/skills/vitepress/LICENSE.md +21 -0
- package/skills/vitepress/SKILL.md +65 -0
- package/skills/vitepress/SYNC.md +5 -0
- package/skills/vitepress/references/advanced-i18n.md +299 -0
- package/skills/vitepress/references/advanced-ssr.md +228 -0
- package/skills/vitepress/references/core-cli.md +119 -0
- package/skills/vitepress/references/core-config.md +189 -0
- package/skills/vitepress/references/core-markdown.md +277 -0
- package/skills/vitepress/references/core-routing.md +169 -0
- package/skills/vitepress/references/features-code-blocks.md +243 -0
- package/skills/vitepress/references/features-data-loading.md +220 -0
- package/skills/vitepress/references/features-dynamic-routes.md +235 -0
- package/skills/vitepress/references/features-vue.md +224 -0
- package/skills/vitepress/references/recipes-deploy.md +240 -0
- package/skills/vitepress/references/theme-config.md +315 -0
- package/skills/vitepress/references/theme-custom.md +269 -0
- package/skills/vitepress/references/theme-customization.md +290 -0
- package/skills/vitest/GENERATION.md +5 -0
- package/skills/vitest/LICENSE.md +21 -0
- package/skills/vitest/SKILL.md +52 -0
- package/skills/vitest/SYNC.md +5 -0
- package/skills/vitest/references/advanced-environments.md +264 -0
- package/skills/vitest/references/advanced-projects.md +300 -0
- package/skills/vitest/references/advanced-type-testing.md +237 -0
- package/skills/vitest/references/advanced-vi.md +249 -0
- package/skills/vitest/references/core-cli.md +166 -0
- package/skills/vitest/references/core-config.md +174 -0
- package/skills/vitest/references/core-describe.md +193 -0
- package/skills/vitest/references/core-expect.md +219 -0
- package/skills/vitest/references/core-hooks.md +244 -0
- package/skills/vitest/references/core-test-api.md +233 -0
- package/skills/vitest/references/features-concurrency.md +250 -0
- package/skills/vitest/references/features-context.md +238 -0
- package/skills/vitest/references/features-coverage.md +207 -0
- package/skills/vitest/references/features-filtering.md +211 -0
- package/skills/vitest/references/features-mocking.md +265 -0
- package/skills/vitest/references/features-snapshots.md +207 -0
- package/skills/vue/GENERATION.md +5 -0
- package/skills/vue/LICENSE.md +21 -0
- package/skills/vue/SKILL.md +84 -0
- package/skills/vue/SYNC.md +5 -0
- package/skills/vue/references/advanced-patterns.md +314 -0
- package/skills/vue/references/core-new-apis.md +264 -0
- package/skills/vue/references/script-setup-macros.md +204 -0
- package/skills/vue-best-practices/LICENSE.md +21 -0
- package/skills/vue-best-practices/SKILL.md +154 -0
- package/skills/vue-best-practices/SYNC.md +5 -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-router-best-practices/LICENSE.md +21 -0
- package/skills/vue-router-best-practices/SKILL.md +23 -0
- package/skills/vue-router-best-practices/SYNC.md +5 -0
- package/skills/vue-router-best-practices/reference/router-beforeenter-no-param-trigger.md +167 -0
- package/skills/vue-router-best-practices/reference/router-beforerouteenter-no-this.md +176 -0
- package/skills/vue-router-best-practices/reference/router-guard-async-await-pattern.md +227 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-infinite-loop.md +187 -0
- package/skills/vue-router-best-practices/reference/router-navigation-guard-next-deprecated.md +150 -0
- package/skills/vue-router-best-practices/reference/router-param-change-no-lifecycle.md +181 -0
- package/skills/vue-router-best-practices/reference/router-simple-routing-cleanup.md +209 -0
- package/skills/vue-router-best-practices/reference/router-use-vue-router-for-production.md +183 -0
- package/skills/vue-testing-best-practices/LICENSE.md +21 -0
- package/skills/vue-testing-best-practices/SKILL.md +29 -0
- package/skills/vue-testing-best-practices/SYNC.md +5 -0
- package/skills/vue-testing-best-practices/reference/async-component-testing.md +163 -0
- package/skills/vue-testing-best-practices/reference/teleport-testing-complexity.md +158 -0
- package/skills/vue-testing-best-practices/reference/testing-async-await-flushpromises.md +175 -0
- package/skills/vue-testing-best-practices/reference/testing-browser-vs-node-runners.md +208 -0
- package/skills/vue-testing-best-practices/reference/testing-component-blackbox-approach.md +144 -0
- package/skills/vue-testing-best-practices/reference/testing-composables-helper-wrapper.md +238 -0
- package/skills/vue-testing-best-practices/reference/testing-e2e-playwright-recommended.md +242 -0
- package/skills/vue-testing-best-practices/reference/testing-no-snapshot-only.md +197 -0
- package/skills/vue-testing-best-practices/reference/testing-pinia-store-setup.md +228 -0
- package/skills/vue-testing-best-practices/reference/testing-suspense-async-components.md +229 -0
- package/skills/vue-testing-best-practices/reference/testing-vitest-recommended-for-vue.md +204 -0
- package/skills/vueuse-functions/LICENSE.md +21 -0
- package/skills/vueuse-functions/SKILL.md +419 -0
- package/skills/vueuse-functions/SYNC.md +5 -0
- package/skills/vueuse-functions/references/computedAsync.md +195 -0
- package/skills/vueuse-functions/references/computedEager.md +62 -0
- package/skills/vueuse-functions/references/computedInject.md +137 -0
- package/skills/vueuse-functions/references/computedWithControl.md +98 -0
- package/skills/vueuse-functions/references/createEventHook.md +86 -0
- package/skills/vueuse-functions/references/createGenericProjection.md +25 -0
- package/skills/vueuse-functions/references/createGlobalState.md +95 -0
- package/skills/vueuse-functions/references/createInjectionState.md +226 -0
- package/skills/vueuse-functions/references/createProjection.md +31 -0
- package/skills/vueuse-functions/references/createRef.md +54 -0
- package/skills/vueuse-functions/references/createReusableTemplate.md +361 -0
- package/skills/vueuse-functions/references/createSharedComposable.md +42 -0
- package/skills/vueuse-functions/references/createTemplatePromise.md +306 -0
- package/skills/vueuse-functions/references/createUnrefFn.md +51 -0
- package/skills/vueuse-functions/references/extendRef.md +76 -0
- package/skills/vueuse-functions/references/from.md +80 -0
- package/skills/vueuse-functions/references/get.md +30 -0
- package/skills/vueuse-functions/references/injectLocal.md +35 -0
- package/skills/vueuse-functions/references/isDefined.md +31 -0
- package/skills/vueuse-functions/references/logicAnd.md +40 -0
- package/skills/vueuse-functions/references/logicNot.md +36 -0
- package/skills/vueuse-functions/references/logicOr.md +40 -0
- package/skills/vueuse-functions/references/makeDestructurable.md +41 -0
- package/skills/vueuse-functions/references/onClickOutside.md +228 -0
- package/skills/vueuse-functions/references/onElementRemoval.md +88 -0
- package/skills/vueuse-functions/references/onKeyStroke.md +212 -0
- package/skills/vueuse-functions/references/onLongPress.md +235 -0
- package/skills/vueuse-functions/references/onStartTyping.md +53 -0
- package/skills/vueuse-functions/references/provideLocal.md +37 -0
- package/skills/vueuse-functions/references/reactify.md +144 -0
- package/skills/vueuse-functions/references/reactifyObject.md +62 -0
- package/skills/vueuse-functions/references/reactiveComputed.md +34 -0
- package/skills/vueuse-functions/references/reactiveOmit.md +86 -0
- package/skills/vueuse-functions/references/reactivePick.md +106 -0
- package/skills/vueuse-functions/references/refAutoReset.md +46 -0
- package/skills/vueuse-functions/references/refDebounced.md +81 -0
- package/skills/vueuse-functions/references/refDefault.md +36 -0
- package/skills/vueuse-functions/references/refManualReset.md +48 -0
- package/skills/vueuse-functions/references/refThrottled.md +99 -0
- package/skills/vueuse-functions/references/refWithControl.md +146 -0
- package/skills/vueuse-functions/references/set.md +30 -0
- package/skills/vueuse-functions/references/syncRef.md +195 -0
- package/skills/vueuse-functions/references/syncRefs.md +128 -0
- package/skills/vueuse-functions/references/templateRef.md +86 -0
- package/skills/vueuse-functions/references/toObserver.md +38 -0
- package/skills/vueuse-functions/references/toReactive.md +41 -0
- package/skills/vueuse-functions/references/toRef.md +74 -0
- package/skills/vueuse-functions/references/toRefs.md +78 -0
- package/skills/vueuse-functions/references/tryOnBeforeMount.md +34 -0
- package/skills/vueuse-functions/references/tryOnBeforeUnmount.md +32 -0
- package/skills/vueuse-functions/references/tryOnMounted.md +34 -0
- package/skills/vueuse-functions/references/tryOnScopeDispose.md +31 -0
- package/skills/vueuse-functions/references/tryOnUnmounted.md +32 -0
- package/skills/vueuse-functions/references/unrefElement.md +54 -0
- package/skills/vueuse-functions/references/until.md +161 -0
- package/skills/vueuse-functions/references/useAbs.md +31 -0
- package/skills/vueuse-functions/references/useActiveElement.md +86 -0
- package/skills/vueuse-functions/references/useAnimate.md +180 -0
- package/skills/vueuse-functions/references/useArrayDifference.md +84 -0
- package/skills/vueuse-functions/references/useArrayEvery.md +59 -0
- package/skills/vueuse-functions/references/useArrayFilter.md +63 -0
- package/skills/vueuse-functions/references/useArrayFind.md +50 -0
- package/skills/vueuse-functions/references/useArrayFindIndex.md +59 -0
- package/skills/vueuse-functions/references/useArrayFindLast.md +52 -0
- package/skills/vueuse-functions/references/useArrayIncludes.md +63 -0
- package/skills/vueuse-functions/references/useArrayJoin.md +74 -0
- package/skills/vueuse-functions/references/useArrayMap.md +59 -0
- package/skills/vueuse-functions/references/useArrayReduce.md +81 -0
- package/skills/vueuse-functions/references/useArraySome.md +59 -0
- package/skills/vueuse-functions/references/useArrayUnique.md +76 -0
- package/skills/vueuse-functions/references/useAsyncQueue.md +136 -0
- package/skills/vueuse-functions/references/useAsyncState.md +185 -0
- package/skills/vueuse-functions/references/useAsyncValidator.md +70 -0
- package/skills/vueuse-functions/references/useAuth.md +123 -0
- package/skills/vueuse-functions/references/useAverage.md +36 -0
- package/skills/vueuse-functions/references/useAxios.md +325 -0
- package/skills/vueuse-functions/references/useBase64.md +136 -0
- package/skills/vueuse-functions/references/useBattery.md +80 -0
- package/skills/vueuse-functions/references/useBluetooth.md +174 -0
- package/skills/vueuse-functions/references/useBreakpoints.md +176 -0
- package/skills/vueuse-functions/references/useBroadcastChannel.md +73 -0
- package/skills/vueuse-functions/references/useBrowserLocation.md +56 -0
- package/skills/vueuse-functions/references/useCached.md +52 -0
- package/skills/vueuse-functions/references/useCeil.md +31 -0
- package/skills/vueuse-functions/references/useChangeCase.md +79 -0
- package/skills/vueuse-functions/references/useClamp.md +85 -0
- package/skills/vueuse-functions/references/useClipboard.md +122 -0
- package/skills/vueuse-functions/references/useClipboardItems.md +93 -0
- package/skills/vueuse-functions/references/useCloned.md +91 -0
- package/skills/vueuse-functions/references/useColorMode.md +172 -0
- package/skills/vueuse-functions/references/useConfirmDialog.md +159 -0
- package/skills/vueuse-functions/references/useCookies.md +162 -0
- package/skills/vueuse-functions/references/useCountdown.md +105 -0
- package/skills/vueuse-functions/references/useCounter.md +86 -0
- package/skills/vueuse-functions/references/useCssSupports.md +33 -0
- package/skills/vueuse-functions/references/useCssVar.md +50 -0
- package/skills/vueuse-functions/references/useCurrentElement.md +61 -0
- package/skills/vueuse-functions/references/useCycleList.md +75 -0
- package/skills/vueuse-functions/references/useDark.md +142 -0
- package/skills/vueuse-functions/references/useDateFormat.md +145 -0
- package/skills/vueuse-functions/references/useDebounceFn.md +100 -0
- package/skills/vueuse-functions/references/useDebouncedRefHistory.md +40 -0
- package/skills/vueuse-functions/references/useDeviceMotion.md +80 -0
- package/skills/vueuse-functions/references/useDeviceOrientation.md +64 -0
- package/skills/vueuse-functions/references/useDevicePixelRatio.md +47 -0
- package/skills/vueuse-functions/references/useDevicesList.md +89 -0
- package/skills/vueuse-functions/references/useDisplayMedia.md +67 -0
- package/skills/vueuse-functions/references/useDocumentVisibility.md +44 -0
- package/skills/vueuse-functions/references/useDraggable.md +289 -0
- package/skills/vueuse-functions/references/useDrauu.md +65 -0
- package/skills/vueuse-functions/references/useDropZone.md +83 -0
- package/skills/vueuse-functions/references/useElementBounding.md +131 -0
- package/skills/vueuse-functions/references/useElementByPoint.md +46 -0
- package/skills/vueuse-functions/references/useElementHover.md +79 -0
- package/skills/vueuse-functions/references/useElementSize.md +79 -0
- package/skills/vueuse-functions/references/useElementVisibility.md +163 -0
- package/skills/vueuse-functions/references/useEventBus.md +101 -0
- package/skills/vueuse-functions/references/useEventListener.md +226 -0
- package/skills/vueuse-functions/references/useEventSource.md +204 -0
- package/skills/vueuse-functions/references/useExtractedObservable.md +198 -0
- package/skills/vueuse-functions/references/useEyeDropper.md +72 -0
- package/skills/vueuse-functions/references/useFavicon.md +69 -0
- package/skills/vueuse-functions/references/useFetch.md +546 -0
- package/skills/vueuse-functions/references/useFileDialog.md +91 -0
- package/skills/vueuse-functions/references/useFileSystemAccess.md +161 -0
- package/skills/vueuse-functions/references/useFirestore.md +129 -0
- package/skills/vueuse-functions/references/useFloor.md +31 -0
- package/skills/vueuse-functions/references/useFocus.md +99 -0
- package/skills/vueuse-functions/references/useFocusTrap.md +245 -0
- package/skills/vueuse-functions/references/useFocusWithin.md +57 -0
- package/skills/vueuse-functions/references/useFps.md +28 -0
- package/skills/vueuse-functions/references/useFullscreen.md +74 -0
- package/skills/vueuse-functions/references/useFuse.md +75 -0
- package/skills/vueuse-functions/references/useGamepad.md +176 -0
- package/skills/vueuse-functions/references/useGeolocation.md +63 -0
- package/skills/vueuse-functions/references/useIDBKeyval.md +93 -0
- package/skills/vueuse-functions/references/useIdle.md +88 -0
- package/skills/vueuse-functions/references/useImage.md +90 -0
- package/skills/vueuse-functions/references/useInfiniteScroll.md +156 -0
- package/skills/vueuse-functions/references/useIntersectionObserver.md +117 -0
- package/skills/vueuse-functions/references/useInterval.md +112 -0
- package/skills/vueuse-functions/references/useIntervalFn.md +50 -0
- package/skills/vueuse-functions/references/useIpcRenderer.md +144 -0
- package/skills/vueuse-functions/references/useIpcRendererInvoke.md +58 -0
- package/skills/vueuse-functions/references/useIpcRendererOn.md +52 -0
- package/skills/vueuse-functions/references/useJwt.md +57 -0
- package/skills/vueuse-functions/references/useKeyModifier.md +87 -0
- package/skills/vueuse-functions/references/useLastChanged.md +63 -0
- package/skills/vueuse-functions/references/useLocalStorage.md +41 -0
- package/skills/vueuse-functions/references/useMagicKeys.md +245 -0
- package/skills/vueuse-functions/references/useManualRefHistory.md +204 -0
- package/skills/vueuse-functions/references/useMath.md +47 -0
- package/skills/vueuse-functions/references/useMax.md +36 -0
- package/skills/vueuse-functions/references/useMediaControls.md +201 -0
- package/skills/vueuse-functions/references/useMediaQuery.md +53 -0
- package/skills/vueuse-functions/references/useMemoize.md +175 -0
- package/skills/vueuse-functions/references/useMemory.md +70 -0
- package/skills/vueuse-functions/references/useMin.md +36 -0
- package/skills/vueuse-functions/references/useMounted.md +38 -0
- package/skills/vueuse-functions/references/useMouse.md +113 -0
- package/skills/vueuse-functions/references/useMouseInElement.md +132 -0
- package/skills/vueuse-functions/references/useMousePressed.md +116 -0
- package/skills/vueuse-functions/references/useMutationObserver.md +60 -0
- package/skills/vueuse-functions/references/useNProgress.md +78 -0
- package/skills/vueuse-functions/references/useNavigatorLanguage.md +57 -0
- package/skills/vueuse-functions/references/useNetwork.md +106 -0
- package/skills/vueuse-functions/references/useNow.md +83 -0
- package/skills/vueuse-functions/references/useObjectUrl.md +55 -0
- package/skills/vueuse-functions/references/useObservable.md +91 -0
- package/skills/vueuse-functions/references/useOffsetPagination.md +199 -0
- package/skills/vueuse-functions/references/useOnline.md +41 -0
- package/skills/vueuse-functions/references/usePageLeave.md +43 -0
- package/skills/vueuse-functions/references/useParallax.md +58 -0
- package/skills/vueuse-functions/references/useParentElement.md +54 -0
- package/skills/vueuse-functions/references/usePerformanceObserver.md +48 -0
- package/skills/vueuse-functions/references/usePermission.md +78 -0
- package/skills/vueuse-functions/references/usePointer.md +91 -0
- package/skills/vueuse-functions/references/usePointerLock.md +59 -0
- package/skills/vueuse-functions/references/usePointerSwipe.md +80 -0
- package/skills/vueuse-functions/references/usePrecision.md +49 -0
- package/skills/vueuse-functions/references/usePreferredColorScheme.md +42 -0
- package/skills/vueuse-functions/references/usePreferredContrast.md +42 -0
- package/skills/vueuse-functions/references/usePreferredDark.md +41 -0
- package/skills/vueuse-functions/references/usePreferredLanguages.md +41 -0
- package/skills/vueuse-functions/references/usePreferredReducedMotion.md +42 -0
- package/skills/vueuse-functions/references/usePreferredReducedTransparency.md +42 -0
- package/skills/vueuse-functions/references/usePrevious.md +40 -0
- package/skills/vueuse-functions/references/useProjection.md +38 -0
- package/skills/vueuse-functions/references/useQRCode.md +53 -0
- package/skills/vueuse-functions/references/useRTDB.md +83 -0
- package/skills/vueuse-functions/references/useRafFn.md +68 -0
- package/skills/vueuse-functions/references/useRefHistory.md +285 -0
- package/skills/vueuse-functions/references/useResizeObserver.md +108 -0
- package/skills/vueuse-functions/references/useRound.md +31 -0
- package/skills/vueuse-functions/references/useRouteHash.md +27 -0
- package/skills/vueuse-functions/references/useRouteParams.md +38 -0
- package/skills/vueuse-functions/references/useRouteQuery.md +79 -0
- package/skills/vueuse-functions/references/useSSRWidth.md +47 -0
- package/skills/vueuse-functions/references/useScreenOrientation.md +98 -0
- package/skills/vueuse-functions/references/useScreenSafeArea.md +60 -0
- package/skills/vueuse-functions/references/useScriptTag.md +116 -0
- package/skills/vueuse-functions/references/useScroll.md +238 -0
- package/skills/vueuse-functions/references/useScrollLock.md +66 -0
- package/skills/vueuse-functions/references/useSessionStorage.md +41 -0
- package/skills/vueuse-functions/references/useShare.md +67 -0
- package/skills/vueuse-functions/references/useSortable.md +276 -0
- package/skills/vueuse-functions/references/useSorted.md +90 -0
- package/skills/vueuse-functions/references/useSpeechRecognition.md +90 -0
- package/skills/vueuse-functions/references/useSpeechSynthesis.md +101 -0
- package/skills/vueuse-functions/references/useStepper.md +137 -0
- package/skills/vueuse-functions/references/useStorage.md +278 -0
- package/skills/vueuse-functions/references/useStorageAsync.md +136 -0
- package/skills/vueuse-functions/references/useStyleTag.md +131 -0
- package/skills/vueuse-functions/references/useSubject.md +77 -0
- package/skills/vueuse-functions/references/useSubscription.md +33 -0
- package/skills/vueuse-functions/references/useSum.md +36 -0
- package/skills/vueuse-functions/references/useSupported.md +29 -0
- package/skills/vueuse-functions/references/useSwipe.md +75 -0
- package/skills/vueuse-functions/references/useTemplateRefsList.md +37 -0
- package/skills/vueuse-functions/references/useTextDirection.md +75 -0
- package/skills/vueuse-functions/references/useTextSelection.md +43 -0
- package/skills/vueuse-functions/references/useTextareaAutosize.md +94 -0
- package/skills/vueuse-functions/references/useThrottleFn.md +57 -0
- package/skills/vueuse-functions/references/useThrottledRefHistory.md +47 -0
- package/skills/vueuse-functions/references/useTimeAgo.md +154 -0
- package/skills/vueuse-functions/references/useTimeAgoIntl.md +117 -0
- package/skills/vueuse-functions/references/useTimeout.md +113 -0
- package/skills/vueuse-functions/references/useTimeoutFn.md +51 -0
- package/skills/vueuse-functions/references/useTimeoutPoll.md +47 -0
- package/skills/vueuse-functions/references/useTimestamp.md +93 -0
- package/skills/vueuse-functions/references/useTitle.md +115 -0
- package/skills/vueuse-functions/references/useToNumber.md +54 -0
- package/skills/vueuse-functions/references/useToString.md +34 -0
- package/skills/vueuse-functions/references/useToggle.md +103 -0
- package/skills/vueuse-functions/references/useTransition.md +265 -0
- package/skills/vueuse-functions/references/useTrunc.md +33 -0
- package/skills/vueuse-functions/references/useUrlSearchParams.md +121 -0
- package/skills/vueuse-functions/references/useUserMedia.md +96 -0
- package/skills/vueuse-functions/references/useVModel.md +182 -0
- package/skills/vueuse-functions/references/useVModels.md +67 -0
- package/skills/vueuse-functions/references/useVibrate.md +86 -0
- package/skills/vueuse-functions/references/useVirtualList.md +182 -0
- package/skills/vueuse-functions/references/useWakeLock.md +51 -0
- package/skills/vueuse-functions/references/useWebNotification.md +175 -0
- package/skills/vueuse-functions/references/useWebSocket.md +299 -0
- package/skills/vueuse-functions/references/useWebWorker.md +60 -0
- package/skills/vueuse-functions/references/useWebWorkerFn.md +102 -0
- package/skills/vueuse-functions/references/useWindowFocus.md +46 -0
- package/skills/vueuse-functions/references/useWindowScroll.md +46 -0
- package/skills/vueuse-functions/references/useWindowSize.md +78 -0
- package/skills/vueuse-functions/references/useZoomFactor.md +53 -0
- package/skills/vueuse-functions/references/useZoomLevel.md +53 -0
- package/skills/vueuse-functions/references/watchArray.md +53 -0
- package/skills/vueuse-functions/references/watchAtMost.md +63 -0
- package/skills/vueuse-functions/references/watchDebounced.md +101 -0
- package/skills/vueuse-functions/references/watchDeep.md +54 -0
- package/skills/vueuse-functions/references/watchExtractedObservable.md +192 -0
- package/skills/vueuse-functions/references/watchIgnorable.md +120 -0
- package/skills/vueuse-functions/references/watchImmediate.md +44 -0
- package/skills/vueuse-functions/references/watchOnce.md +41 -0
- package/skills/vueuse-functions/references/watchPausable.md +86 -0
- package/skills/vueuse-functions/references/watchThrottled.md +108 -0
- package/skills/vueuse-functions/references/watchTriggerable.md +98 -0
- package/skills/vueuse-functions/references/watchWithFilter.md +54 -0
- package/skills/vueuse-functions/references/whenever.md +108 -0
- package/skills/web-design-guidelines/SKILL.md +39 -0
- package/skills/web-design-guidelines/SYNC.md +5 -0
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: performance
|
|
3
|
+
description: Performance optimization techniques
|
|
4
|
+
metadata:
|
|
5
|
+
tags: performance, optimization, memory, worker-threads
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Performance in Node.js
|
|
9
|
+
|
|
10
|
+
## Avoid Blocking the Event Loop
|
|
11
|
+
|
|
12
|
+
Never perform CPU-intensive operations synchronously:
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// BAD - blocks event loop
|
|
16
|
+
function hashPasswordSync(password: string): string {
|
|
17
|
+
return crypto.pbkdf2Sync(password, salt, 100000, 64, 'sha512').toString('hex');
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// GOOD - async operation
|
|
21
|
+
function hashPassword(password: string): Promise<string> {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
crypto.pbkdf2(password, salt, 100000, 64, 'sha512', (err, key) => {
|
|
24
|
+
if (err) reject(err);
|
|
25
|
+
else resolve(key.toString('hex'));
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Worker Threads with Piscina
|
|
32
|
+
|
|
33
|
+
Use [piscina](https://github.com/piscinajs/piscina) for CPU-intensive tasks:
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
// worker.ts
|
|
37
|
+
export default function heavyComputation(data: { input: string }): string {
|
|
38
|
+
// CPU-intensive work here
|
|
39
|
+
return result;
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
// main.ts
|
|
45
|
+
import Piscina from 'piscina';
|
|
46
|
+
|
|
47
|
+
const piscina = new Piscina({
|
|
48
|
+
filename: new URL('./worker.ts', import.meta.url).href,
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
const result = await piscina.run({ input: 'data' });
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
Piscina handles worker pool management, task queuing, and load balancing automatically.
|
|
55
|
+
|
|
56
|
+
## Connection Pooling
|
|
57
|
+
|
|
58
|
+
Always use connection pools for databases:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
import { Pool } from 'pg';
|
|
62
|
+
|
|
63
|
+
const pool = new Pool({
|
|
64
|
+
max: 20,
|
|
65
|
+
idleTimeoutMillis: 30000,
|
|
66
|
+
connectionTimeoutMillis: 2000,
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
async function query<T>(sql: string, params: unknown[]): Promise<T[]> {
|
|
70
|
+
const client = await pool.connect();
|
|
71
|
+
try {
|
|
72
|
+
const result = await client.query(sql, params);
|
|
73
|
+
return result.rows;
|
|
74
|
+
} finally {
|
|
75
|
+
client.release();
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Avoid Memory Leaks
|
|
81
|
+
|
|
82
|
+
Common memory leak patterns to avoid:
|
|
83
|
+
|
|
84
|
+
```typescript
|
|
85
|
+
// BAD - unbounded cache
|
|
86
|
+
const cache = new Map();
|
|
87
|
+
function addToCache(key: string, value: unknown) {
|
|
88
|
+
cache.set(key, value); // Never cleaned up
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// GOOD - LRU cache with max size
|
|
92
|
+
import { LRUCache } from 'lru-cache';
|
|
93
|
+
|
|
94
|
+
const cache = new LRUCache<string, unknown>({
|
|
95
|
+
max: 500,
|
|
96
|
+
ttl: 1000 * 60 * 5,
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
// BAD - listener leak
|
|
100
|
+
function subscribe(emitter: EventEmitter) {
|
|
101
|
+
emitter.on('event', handler); // Never removed
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// GOOD - cleanup listeners
|
|
105
|
+
function subscribe(emitter: EventEmitter): () => void {
|
|
106
|
+
emitter.on('event', handler);
|
|
107
|
+
return () => emitter.off('event', handler);
|
|
108
|
+
}
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Lazy Loading
|
|
112
|
+
|
|
113
|
+
Load modules only when needed:
|
|
114
|
+
|
|
115
|
+
```typescript
|
|
116
|
+
let heavyModule: HeavyModule | null = null;
|
|
117
|
+
|
|
118
|
+
async function getHeavyModule(): Promise<HeavyModule> {
|
|
119
|
+
if (!heavyModule) {
|
|
120
|
+
const { HeavyModule } = await import('./heavy-module.js');
|
|
121
|
+
heavyModule = new HeavyModule();
|
|
122
|
+
}
|
|
123
|
+
return heavyModule;
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
## Related
|
|
128
|
+
|
|
129
|
+
- [caching.md](./caching.md) - Caching patterns and libraries
|
|
130
|
+
- [profiling.md](./profiling.md) - Profiling and benchmarking tools
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: profiling
|
|
3
|
+
description: Profiling and benchmarking tools
|
|
4
|
+
metadata:
|
|
5
|
+
tags: profiling, benchmarking, performance, flame-graphs
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Profiling in Node.js
|
|
9
|
+
|
|
10
|
+
## Flame Graphs with @platformatic/flame
|
|
11
|
+
|
|
12
|
+
Use [@platformatic/flame](https://github.com/platformatic/flame) for CPU profiling with flame graph visualization:
|
|
13
|
+
|
|
14
|
+
```bash
|
|
15
|
+
npx @platformatic/flame app.ts
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
This starts your application with profiling enabled and generates an interactive flame graph.
|
|
19
|
+
|
|
20
|
+
### Markdown Output for AI Analysis
|
|
21
|
+
|
|
22
|
+
flame can output markdown reports suitable for AI-assisted performance analysis:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npx @platformatic/flame --output markdown app.ts
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
This enables a fully agentic workflow where you can:
|
|
29
|
+
1. Profile your application
|
|
30
|
+
2. Get markdown output describing hotspots
|
|
31
|
+
3. Feed the report to an AI assistant for optimization suggestions
|
|
32
|
+
|
|
33
|
+
### Programmatic Usage
|
|
34
|
+
|
|
35
|
+
```typescript
|
|
36
|
+
import { profile } from '@platformatic/flame';
|
|
37
|
+
|
|
38
|
+
const stop = await profile({
|
|
39
|
+
outputFile: 'profile.html',
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
// Run your workload
|
|
43
|
+
await runBenchmark();
|
|
44
|
+
|
|
45
|
+
await stop();
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Load Testing Tools
|
|
49
|
+
|
|
50
|
+
### autocannon
|
|
51
|
+
|
|
52
|
+
Use [autocannon](https://github.com/mcollina/autocannon) for HTTP benchmarking:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
# Basic benchmark
|
|
56
|
+
npx autocannon http://localhost:3000
|
|
57
|
+
|
|
58
|
+
# With options
|
|
59
|
+
npx autocannon -c 100 -d 30 -p 10 http://localhost:3000
|
|
60
|
+
|
|
61
|
+
# POST request with body
|
|
62
|
+
npx autocannon -m POST -H "Content-Type: application/json" -b '{"name":"test"}' http://localhost:3000/users
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Options:
|
|
66
|
+
- `-c` - Number of concurrent connections (default: 10)
|
|
67
|
+
- `-d` - Duration in seconds (default: 10)
|
|
68
|
+
- `-p` - Number of pipelined requests (default: 1)
|
|
69
|
+
- `-m` - HTTP method
|
|
70
|
+
- `-b` - Request body
|
|
71
|
+
|
|
72
|
+
### Programmatic autocannon
|
|
73
|
+
|
|
74
|
+
```typescript
|
|
75
|
+
import autocannon from 'autocannon';
|
|
76
|
+
|
|
77
|
+
const result = await autocannon({
|
|
78
|
+
url: 'http://localhost:3000',
|
|
79
|
+
connections: 100,
|
|
80
|
+
duration: 30,
|
|
81
|
+
pipelining: 10,
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
console.log(autocannon.printResult(result));
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### wrk
|
|
88
|
+
|
|
89
|
+
[wrk](https://github.com/wg/wrk) is a high-performance HTTP benchmarking tool:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
# Basic benchmark
|
|
93
|
+
wrk -t12 -c400 -d30s http://localhost:3000
|
|
94
|
+
|
|
95
|
+
# With Lua script for custom requests
|
|
96
|
+
wrk -t12 -c400 -d30s -s post.lua http://localhost:3000
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Options:
|
|
100
|
+
- `-t` - Number of threads
|
|
101
|
+
- `-c` - Number of connections
|
|
102
|
+
- `-d` - Duration
|
|
103
|
+
- `-s` - Lua script for custom logic
|
|
104
|
+
|
|
105
|
+
### k6
|
|
106
|
+
|
|
107
|
+
[k6](https://k6.io/) is ideal for complex load testing scenarios:
|
|
108
|
+
|
|
109
|
+
```javascript
|
|
110
|
+
// load-test.js
|
|
111
|
+
import http from 'k6/http';
|
|
112
|
+
import { check, sleep } from 'k6';
|
|
113
|
+
|
|
114
|
+
export const options = {
|
|
115
|
+
vus: 100,
|
|
116
|
+
duration: '30s',
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default function () {
|
|
120
|
+
const res = http.get('http://localhost:3000');
|
|
121
|
+
check(res, {
|
|
122
|
+
'status is 200': (r) => r.status === 200,
|
|
123
|
+
'response time < 200ms': (r) => r.timings.duration < 200,
|
|
124
|
+
});
|
|
125
|
+
sleep(1);
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
k6 run load-test.js
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
## Built-in Node.js Profiling
|
|
134
|
+
|
|
135
|
+
### CPU Profiling
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Generate V8 profiling log
|
|
139
|
+
node --prof app.js
|
|
140
|
+
|
|
141
|
+
# Process the log
|
|
142
|
+
node --prof-process isolate-*.log > profile.txt
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Heap Snapshots
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
# Start with inspector
|
|
149
|
+
node --inspect app.js
|
|
150
|
+
|
|
151
|
+
# Then use Chrome DevTools (chrome://inspect) to:
|
|
152
|
+
# - Take heap snapshots
|
|
153
|
+
# - Record allocation timelines
|
|
154
|
+
# - Find memory leaks
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
### Diagnostic Reports
|
|
158
|
+
|
|
159
|
+
```bash
|
|
160
|
+
# Generate report on signal
|
|
161
|
+
node --report-on-signal app.js
|
|
162
|
+
kill -SIGUSR2 <pid>
|
|
163
|
+
|
|
164
|
+
# Generate report on uncaught exception
|
|
165
|
+
node --report-on-fatalerror app.js
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Profiling Workflow
|
|
169
|
+
|
|
170
|
+
1. **Establish baseline** - Run autocannon to get initial metrics
|
|
171
|
+
2. **Profile** - Use @platformatic/flame to identify hotspots
|
|
172
|
+
3. **Optimize** - Fix the identified bottlenecks
|
|
173
|
+
4. **Verify** - Run autocannon again to measure improvement
|
|
174
|
+
5. **Repeat** - Continue until performance goals are met
|
|
175
|
+
|
|
176
|
+
## Tool Comparison
|
|
177
|
+
|
|
178
|
+
| Tool | Best For |
|
|
179
|
+
|------|----------|
|
|
180
|
+
| @platformatic/flame | CPU profiling, flame graphs, AI-assisted analysis |
|
|
181
|
+
| autocannon | Quick HTTP benchmarks, Node.js native |
|
|
182
|
+
| wrk | Maximum throughput testing |
|
|
183
|
+
| k6 | Complex scenarios, CI/CD integration, scripted tests |
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: streams
|
|
3
|
+
description: Working with Node.js streams
|
|
4
|
+
metadata:
|
|
5
|
+
tags: streams, readable, writable, transform, pipeline
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Node.js Streams
|
|
9
|
+
|
|
10
|
+
## High-signal triggers
|
|
11
|
+
|
|
12
|
+
If the prompt mentions **CSV**, **ETL**, **ingestion**, **large files**, **transform streams**, **backpressure**, or **line-by-line processing**, prioritize `pipeline()` + explicit async-generator transforms.
|
|
13
|
+
|
|
14
|
+
## Use pipeline for Stream Composition
|
|
15
|
+
|
|
16
|
+
Always use `pipeline` instead of `.pipe()` for proper error handling:
|
|
17
|
+
|
|
18
|
+
```typescript
|
|
19
|
+
import { pipeline } from 'node:stream/promises';
|
|
20
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
21
|
+
import { createGzip } from 'node:zlib';
|
|
22
|
+
|
|
23
|
+
async function compressFile(input: string, output: string): Promise<void> {
|
|
24
|
+
await pipeline(
|
|
25
|
+
createReadStream(input),
|
|
26
|
+
createGzip(),
|
|
27
|
+
createWriteStream(output)
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Async Generators in Pipeline
|
|
33
|
+
|
|
34
|
+
Use async generators for transformation:
|
|
35
|
+
|
|
36
|
+
```typescript
|
|
37
|
+
import { pipeline } from 'node:stream/promises';
|
|
38
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
39
|
+
|
|
40
|
+
async function* toUpperCase(source: AsyncIterable<Buffer>): AsyncGenerator<string> {
|
|
41
|
+
for await (const chunk of source) {
|
|
42
|
+
yield chunk.toString().toUpperCase();
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
async function processFile(input: string, output: string): Promise<void> {
|
|
47
|
+
await pipeline(
|
|
48
|
+
createReadStream(input),
|
|
49
|
+
toUpperCase,
|
|
50
|
+
createWriteStream(output)
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### CSV/ETL pattern: pipeline + async transform + deduplicated enrichment
|
|
56
|
+
|
|
57
|
+
For ingestion-style tasks, show an explicit `async function*` transform and integrate deduped async lookups:
|
|
58
|
+
|
|
59
|
+
```typescript
|
|
60
|
+
import { pipeline } from 'node:stream/promises';
|
|
61
|
+
import { createReadStream, createWriteStream } from 'node:fs';
|
|
62
|
+
import { createCache } from 'async-cache-dedupe';
|
|
63
|
+
|
|
64
|
+
const cache = createCache({
|
|
65
|
+
ttl: 60,
|
|
66
|
+
stale: 5,
|
|
67
|
+
storage: { type: 'memory' },
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
cache.define('lookupPlan', async (planId: string) => {
|
|
71
|
+
return await fetch(`https://billing.internal/plans/${planId}`).then(async (res) => await res.json());
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
async function* enrichCsvRows(source: AsyncIterable<Buffer>): AsyncGenerator<string> {
|
|
75
|
+
let tail = '';
|
|
76
|
+
|
|
77
|
+
for await (const chunk of source) {
|
|
78
|
+
tail += chunk.toString('utf8');
|
|
79
|
+
const lines = tail.split('\n');
|
|
80
|
+
tail = lines.pop() ?? '';
|
|
81
|
+
|
|
82
|
+
for (const line of lines) {
|
|
83
|
+
if (line.trim().length === 0) continue;
|
|
84
|
+
const [userId, planId] = line.split(',');
|
|
85
|
+
const plan = await cache.lookupPlan(planId); // concurrent requests dedupe by key
|
|
86
|
+
yield `${userId},${planId},${plan.tier}\n`;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
if (tail.trim().length > 0) {
|
|
91
|
+
const [userId, planId] = tail.split(',');
|
|
92
|
+
const plan = await cache.lookupPlan(planId);
|
|
93
|
+
yield `${userId},${planId},${plan.tier}\n`;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
await pipeline(
|
|
98
|
+
createReadStream('users.csv'),
|
|
99
|
+
enrichCsvRows,
|
|
100
|
+
createWriteStream('users-enriched.csv')
|
|
101
|
+
);
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### Multiple Transformations
|
|
105
|
+
|
|
106
|
+
Chain multiple async generators:
|
|
107
|
+
|
|
108
|
+
```typescript
|
|
109
|
+
import { pipeline } from 'node:stream/promises';
|
|
110
|
+
|
|
111
|
+
async function* parseLines(source: AsyncIterable<Buffer>): AsyncGenerator<string> {
|
|
112
|
+
let buffer = '';
|
|
113
|
+
for await (const chunk of source) {
|
|
114
|
+
buffer += chunk.toString();
|
|
115
|
+
const lines = buffer.split('\n');
|
|
116
|
+
buffer = lines.pop() ?? '';
|
|
117
|
+
for (const line of lines) {
|
|
118
|
+
yield line;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (buffer) yield buffer;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
async function* filterNonEmpty(source: AsyncIterable<string>): AsyncGenerator<string> {
|
|
125
|
+
for await (const line of source) {
|
|
126
|
+
if (line.trim()) {
|
|
127
|
+
yield line + '\n';
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
await pipeline(
|
|
133
|
+
createReadStream('input.txt'),
|
|
134
|
+
parseLines,
|
|
135
|
+
filterNonEmpty,
|
|
136
|
+
createWriteStream('output.txt')
|
|
137
|
+
);
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Async Iterators with Streams
|
|
141
|
+
|
|
142
|
+
Use async iterators for consuming streams:
|
|
143
|
+
|
|
144
|
+
```typescript
|
|
145
|
+
import { createReadStream } from 'node:fs';
|
|
146
|
+
import { createInterface } from 'node:readline';
|
|
147
|
+
|
|
148
|
+
async function processLines(filePath: string): Promise<void> {
|
|
149
|
+
const fileStream = createReadStream(filePath);
|
|
150
|
+
const rl = createInterface({
|
|
151
|
+
input: fileStream,
|
|
152
|
+
crlfDelay: Infinity,
|
|
153
|
+
});
|
|
154
|
+
|
|
155
|
+
for await (const line of rl) {
|
|
156
|
+
await processLine(line);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
## Readable.from for Creating Streams
|
|
162
|
+
|
|
163
|
+
Create readable streams from iterables:
|
|
164
|
+
|
|
165
|
+
```typescript
|
|
166
|
+
import { Readable } from 'node:stream';
|
|
167
|
+
|
|
168
|
+
async function* generateData(): AsyncGenerator<string> {
|
|
169
|
+
for (let i = 0; i < 100; i++) {
|
|
170
|
+
yield JSON.stringify({ id: i, timestamp: Date.now() }) + '\n';
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
const stream = Readable.from(generateData());
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## Backpressure Handling
|
|
178
|
+
|
|
179
|
+
Respect backpressure signals using `once` from events:
|
|
180
|
+
|
|
181
|
+
```typescript
|
|
182
|
+
import { Writable } from 'node:stream';
|
|
183
|
+
import { once } from 'node:events';
|
|
184
|
+
|
|
185
|
+
async function writeData(
|
|
186
|
+
writable: Writable,
|
|
187
|
+
data: string[]
|
|
188
|
+
): Promise<void> {
|
|
189
|
+
for (const chunk of data) {
|
|
190
|
+
const canContinue = writable.write(chunk);
|
|
191
|
+
if (!canContinue) {
|
|
192
|
+
await once(writable, 'drain');
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Stream Consumers (Node.js 18+)
|
|
199
|
+
|
|
200
|
+
Use stream consumers for common operations:
|
|
201
|
+
|
|
202
|
+
```typescript
|
|
203
|
+
import { text, json, buffer } from 'node:stream/consumers';
|
|
204
|
+
import { Readable } from 'node:stream';
|
|
205
|
+
|
|
206
|
+
async function readStreamAsJson<T>(stream: Readable): Promise<T> {
|
|
207
|
+
return json(stream) as Promise<T>;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
async function readStreamAsText(stream: Readable): Promise<string> {
|
|
211
|
+
return text(stream);
|
|
212
|
+
}
|
|
213
|
+
```
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: stuck-processes-and-tests
|
|
3
|
+
description: Diagnosing Node.js processes that do not exit and tests that get stuck
|
|
4
|
+
metadata:
|
|
5
|
+
tags: node, debugging, testing, hangs, open-handles, diagnostics
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# Diagnosing Stuck Node.js Processes and Hanging Tests
|
|
9
|
+
|
|
10
|
+
## Activation triggers (apply this rule immediately)
|
|
11
|
+
|
|
12
|
+
Use this rule when prompts/logs include any of:
|
|
13
|
+
- "`node --test` hangs" / "test run never exits"
|
|
14
|
+
- "CI timed out" after tests appear done
|
|
15
|
+
- "process is still running" / "did not exit cleanly"
|
|
16
|
+
- "open handles" / "active handles"
|
|
17
|
+
- "passes alone, hangs in full suite"
|
|
18
|
+
|
|
19
|
+
## Non-negotiable checklist (all 5 required)
|
|
20
|
+
|
|
21
|
+
1. **Isolate first**: reproduce with one file, then one test name.
|
|
22
|
+
2. **Fail fast**: run with explicit timeout + reporter so hangs produce location context.
|
|
23
|
+
3. **Capture handles**: run `why-is-node-running` and record the reported handle owner.
|
|
24
|
+
4. **Patch teardown in the same scope that created the resource** (`t.after(...)`, await close/terminate/disconnect).
|
|
25
|
+
5. **Verify stability**: repeat isolated test many times, then run full suite.
|
|
26
|
+
|
|
27
|
+
Do **not** mark the issue fixed unless step 5 passes.
|
|
28
|
+
|
|
29
|
+
## Command path (run in order)
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
# 1) Reproduce full command with fail-fast settings
|
|
33
|
+
node --test --test-reporter=spec --test-timeout=15000
|
|
34
|
+
|
|
35
|
+
# 2) Isolate file, then test name
|
|
36
|
+
node --test --test-timeout=15000 path/to/file.test.ts
|
|
37
|
+
node --test --test-timeout=15000 --test-name-pattern="should close resources" path/to/file.test.ts
|
|
38
|
+
|
|
39
|
+
# 3) Dump active handles when hung
|
|
40
|
+
node --import why-is-node-running/include --test path/to/file.test.ts
|
|
41
|
+
# in another shell, send SIGUSR1 to printed PID
|
|
42
|
+
kill -SIGUSR1 <pid>
|
|
43
|
+
|
|
44
|
+
# 4) Stress rerun isolated repro (Linux: timeout, macOS: gtimeout)
|
|
45
|
+
TIMEOUT_BIN="$(command -v timeout || command -v gtimeout)"
|
|
46
|
+
for i in {1..30}; do
|
|
47
|
+
"$TIMEOUT_BIN" 30s node --test path/to/file.test.ts || { echo "failed on run $i"; break; }
|
|
48
|
+
done
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### `why-is-node-running` install note
|
|
52
|
+
|
|
53
|
+
- ESM / modern Node: `npm i -D why-is-node-running`
|
|
54
|
+
- older CommonJS projects: `npm i -D why-is-node-running@v2`
|
|
55
|
+
|
|
56
|
+
Use it for diagnostics only; gate noisy output behind an environment flag in CI.
|
|
57
|
+
|
|
58
|
+
## High-probability root causes
|
|
59
|
+
|
|
60
|
+
- HTTP server started but never closed (`server.close()` not awaited)
|
|
61
|
+
- `setInterval` left running (or timer not `unref()`ed when appropriate)
|
|
62
|
+
- DB/Redis/Kafka clients not disconnected
|
|
63
|
+
- worker threads, child processes, or message channels left alive
|
|
64
|
+
- file watchers / readline interfaces still open
|
|
65
|
+
- unresolved promises from fire-and-forget async code
|
|
66
|
+
- teardown hooks that throw before cleanup completes
|
|
67
|
+
|
|
68
|
+
## Integrated fix example (CI hangs after tests appear complete)
|
|
69
|
+
|
|
70
|
+
**Symptom:** CI times out; local full-suite run hangs after most tests pass.
|
|
71
|
+
|
|
72
|
+
### Step sequence
|
|
73
|
+
|
|
74
|
+
1. Reproduce with:
|
|
75
|
+
```bash
|
|
76
|
+
node --test --test-reporter=spec --test-timeout=15000
|
|
77
|
+
```
|
|
78
|
+
2. Isolate to one test using `--test-name-pattern`.
|
|
79
|
+
3. Run with `--import why-is-node-running/include` and send `SIGUSR1`.
|
|
80
|
+
4. Patch teardown where resource is created.
|
|
81
|
+
5. Verify isolated 30x, then full suite.
|
|
82
|
+
|
|
83
|
+
### Bad (common leak)
|
|
84
|
+
|
|
85
|
+
```typescript
|
|
86
|
+
it('serves requests', async () => {
|
|
87
|
+
const server = await startServer({ port: 0 });
|
|
88
|
+
const id = setInterval(() => {}, 1000);
|
|
89
|
+
// test body...
|
|
90
|
+
// ❌ no deterministic teardown
|
|
91
|
+
});
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### Good (deterministic teardown)
|
|
95
|
+
|
|
96
|
+
```typescript
|
|
97
|
+
import { once } from 'node:events';
|
|
98
|
+
|
|
99
|
+
it('serves requests', async (t) => {
|
|
100
|
+
const server = await startServer({ port: 0 });
|
|
101
|
+
const id = setInterval(() => {}, 1000);
|
|
102
|
+
|
|
103
|
+
t.after(async () => {
|
|
104
|
+
clearInterval(id);
|
|
105
|
+
server.close();
|
|
106
|
+
await once(server, 'close');
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// test body...
|
|
110
|
+
});
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Definition of done (must all pass)
|
|
114
|
+
|
|
115
|
+
- [ ] Isolated repro passes repeatedly (recommended: 30 runs) with no hangs
|
|
116
|
+
- [ ] Full `node --test` run exits with code 0
|
|
117
|
+
- [ ] CI completes with no timeout
|
|
118
|
+
- [ ] `why-is-node-running` shows no unexpected leftover handles
|
|
119
|
+
|
|
120
|
+
## Related rules
|
|
121
|
+
|
|
122
|
+
- [flaky-tests.md](flaky-tests.md)
|
|
123
|
+
- [testing.md](testing.md)
|
|
124
|
+
- [graceful-shutdown.md](graceful-shutdown.md)
|