[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6ENYKAMT2ZXJEC1KCPWAMPF":3,"skill-same:01M6ENYKAMT2ZXJEC1KCPWAMPF":73},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":39,"linkOnly":40,"markdownContent":41,"markdownBody":42,"frontMatter":43,"refName":44,"commitSha":45,"skillDirectory":46,"forksCount":47,"repositoryHtmlUrl":48,"repositoryHomepageUrl":49,"ownerHtmlUrl":50,"ownerBlogUrl":6,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M6ENYKAMT2ZXJEC1KCPWAMPF","react-async-patterns",null,"Async\u002Fawait correctness in React with Zustand. Use when debugging race conditions, missing awaits, floating promises, or async timing issues. Works for both React web and React Native.","ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",66,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcjharmath\u002Freact-async-patterns\u002FSKILL.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38],"react","async","patterns","react async patterns","web","debugging","issues","zustand","react native","use","promises","missing","timing","react web","native","2026-11-10 10:12:30",false,"---\nname: react-async-patterns\ndescription: Async\u002Fawait correctness in React with Zustand. Use when debugging race conditions, missing awaits, floating promises, or async timing issues. Works for both React web and React Native.\n---\n\n# React Async Patterns\n\n## Problem Statement\n\nAsync bugs in React are insidious because they often work in development but fail under load or in edge cases. The most common issues: missing `await` on async functions, race conditions between state updates, and assuming operations complete in order.\n\n---\n\n## Pattern: Floating Promise Detection\n\n**Problem:** Calling an async function without `await` causes it to run in the background. If subsequent code depends on its completion, you get a race condition.\n\n```typescript\n\u002F\u002F Before (buggy) - saveData is async but not awaited\nsaveData(item);              \u002F\u002F Fire and forget ❌\nawait processData(item);     \u002F\u002F Runs before save completes\n\n\u002F\u002F After (fixed)\nawait saveData(item);        \u002F\u002F Wait for state update ✅\nawait processData(item);     \u002F\u002F Now runs in correct order\n```\n\n**Why it's subtle:** Both functions might have `async` in their signature, but only one was awaited. The code \"looks right\" at a glance.\n\n**Detection:**\n\n```bash\n# Find potential floating promises - async calls without await\ngrep -rn \"^\\s*[a-zA-Z]*\\s*(\" --include=\"*.ts\" --include=\"*.tsx\" | \\\n  grep -v \"await\\|return\\|const\\|let\\|if\\|else\\|=>\"\n```\n\n**Prevention:**\n\n1. ESLint rule `@typescript-eslint\u002Fno-floating-promises` - catches this at lint time\n2. Code review trigger: Any line calling a function that might be async without `await`, `return`, or assignment\n\n---\n\n## Pattern: Post-Condition Validation\n\n**Problem:** Assuming an async call succeeded without verifying. The call might return early, throw silently, or fail to update state.\n\n```typescript\n\u002F\u002F Before (buggy) - assumed load worked\nawait loadData(id);\n\u002F\u002F Proceeded blindly with next steps...\n\n\u002F\u002F After (defensive)\nawait loadData(id);\nconst loaded = useStore.getState().data;\nif (Object.keys(loaded).length === 0) {\n  throw new Error(\n    `Failed to load data for ${id} - cannot proceed`\n  );\n}\n```\n\n**Principle:** Treat every async call as potentially failed until proven otherwise.\n\n**When to validate:**\n\n- After loading data that subsequent operations depend on\n- After state updates that must complete before continuing\n- Before irreversible operations (submissions, deletions)\n\n**Pattern template:**\n\n```typescript\nawait someAsyncOperation();\nconst result = getRelevantState();\nif (!isValid(result)) {\n  throw new Error(`[${functionName}] Post-condition failed: ${diagnosticContext}`);\n}\n```\n\n---\n\n## Pattern: Async Function Identification\n\n**Problem:** Not all async functions look async. Zustand actions, callbacks, and promise-returning functions may not have obvious `async` keywords.\n\n**Hidden async patterns:**\n\n```typescript\n\u002F\u002F Obvious async\nasync function fetchData() { ... }\n\n\u002F\u002F Less obvious - returns Promise\nfunction fetchData(): Promise\u003CData> { ... }\n\n\u002F\u002F Hidden - Zustand action that's actually async\nconst useStore = create((set, get) => ({\n  \u002F\u002F This looks sync but calls async internally\n  enableFeature: (id: string) => {\n    someAsyncSetup().then(() => {  \u002F\u002F ← Hidden async!\n      set({ features: [...get().features, id] });\n    });\n  },\n}));\n\n\u002F\u002F Proper async Zustand action\nconst useStore = create((set, get) => ({\n  enableFeature: async (id: string) => {\n    await someAsyncSetup();\n    set({ features: [...get().features, id] });\n  },\n}));\n```\n\n**Detection:** Check function signatures and implementations:\n\n```bash\n# Find functions returning Promise\ngrep -rn \"): Promise\u003C\" --include=\"*.ts\" --include=\"*.tsx\"\n\n# Find .then() chains that might need await\ngrep -rn \"\\.then(\" --include=\"*.ts\" --include=\"*.tsx\"\n```\n\n---\n\n## Pattern: Sequential vs Parallel Async\n\n**Problem:** Running async operations sequentially when they could be parallel (slow), or parallel when they must be sequential (race condition).\n\n```typescript\n\u002F\u002F Sequential - correct when order matters\nawait stepOne();\nawait stepTwo();\nawait stepThree();\n\n\u002F\u002F Parallel - correct when operations are independent\nconst [user, settings, history] = await Promise.all([\n  fetchUser(id),\n  fetchSettings(id),\n  fetchHistory(id),\n]);\n\n\u002F\u002F WRONG - parallel when order matters\nawait Promise.all([\n  stepOne(),   \u002F\u002F These have dependencies!\n  stepTwo(),\n]);\n```\n\n**Decision framework:**\n\n| Operations share state? | Must run in order? | Pattern |\n|------------------------|-------------------|---------|\n| No | No | `Promise.all()` |\n| Yes | Yes | Sequential `await` |\n| Yes | No | Usually sequential to be safe |\n\n---\n\n## Pattern: Async in useEffect\n\n**Problem:** `useEffect` callbacks can't be async directly. Common mistakes with cleanup and race conditions.\n\n```typescript\n\u002F\u002F WRONG - useEffect can't be async\nuseEffect(async () => {\n  const data = await fetchData();\n  setData(data);\n}, []);\n\n\u002F\u002F CORRECT - async function inside\nuseEffect(() => {\n  async function load() {\n    const data = await fetchData();\n    setData(data);\n  }\n  load();\n}, []);\n\n\u002F\u002F BETTER - with cleanup for race conditions\nuseEffect(() => {\n  let cancelled = false;\n\n  async function load() {\n    const data = await fetchData();\n    if (!cancelled) {\n      setData(data);\n    }\n  }\n  load();\n\n  return () => {\n    cancelled = true;\n  };\n}, [dependency]);\n\n\u002F\u002F BEST - use AbortController for fetch\nuseEffect(() => {\n  const controller = new AbortController();\n\n  async function load() {\n    try {\n      const response = await fetch(url, { signal: controller.signal });\n      const data = await response.json();\n      setData(data);\n    } catch (error) {\n      if (error.name !== 'AbortError') {\n        setError(error);\n      }\n    }\n  }\n  load();\n\n  return () => controller.abort();\n}, [url]);\n```\n\n---\n\n## Pattern: React Query \u002F TanStack Query\n\n**Problem:** Manual async state management is error-prone. Use a library.\n\n```typescript\nimport { useQuery, useMutation, useQueryClient } from '@tanstack\u002Freact-query';\n\n\u002F\u002F Fetching data\nfunction UserProfile({ userId }) {\n  const { data, isLoading, error } = useQuery({\n    queryKey: ['user', userId],\n    queryFn: () => fetchUser(userId),\n  });\n\n  if (isLoading) return \u003CSpinner \u002F>;\n  if (error) return \u003CError error={error} \u002F>;\n  return \u003CProfile user={data} \u002F>;\n}\n\n\u002F\u002F Mutations with cache invalidation\nfunction UpdateUser() {\n  const queryClient = useQueryClient();\n\n  const mutation = useMutation({\n    mutationFn: updateUser,\n    onSuccess: () => {\n      queryClient.invalidateQueries({ queryKey: ['user'] });\n    },\n  });\n\n  return (\n    \u003Cbutton onClick={() => mutation.mutate(userData)}>\n      Save\n    \u003C\u002Fbutton>\n  );\n}\n```\n\n---\n\n## ESLint Configuration\n\nAdd these rules to catch async issues at lint time:\n\n```json\n{\n  \"rules\": {\n    \"@typescript-eslint\u002Fno-floating-promises\": \"error\",\n    \"@typescript-eslint\u002Frequire-await\": \"warn\",\n    \"@typescript-eslint\u002Fawait-thenable\": \"error\",\n    \"@typescript-eslint\u002Fno-misused-promises\": \"error\"\n  }\n}\n```\n\n**Required:** `@typescript-eslint\u002Feslint-plugin` and proper TypeScript configuration.\n\n---\n\n## Code Review Checklist\n\nWhen reviewing async code, check:\n\n- [ ] Every async function call is either `await`ed, `return`ed, or explicitly fire-and-forget with comment\n- [ ] Operations that depend on each other are sequenced with `await`\n- [ ] Post-conditions validated after critical async operations\n- [ ] `useEffect` with async uses the inner function pattern\n- [ ] Race conditions considered when component could unmount during async\n- [ ] Error handling exists for async failures\n- [ ] AbortController used for fetch calls that should be cancellable\n\n---\n\n## Quick Debugging\n\nWhen async timing issues occur:\n\n```typescript\n\u002F\u002F Add timestamps to trace execution order\nconsole.log(`[${Date.now()}] Starting step 1`);\nawait stepOne();\nconsole.log(`[${Date.now()}] Finished step 1`);\nconsole.log(`[${Date.now()}] Starting step 2`);\nawait stepTwo();\nconsole.log(`[${Date.now()}] Finished step 2`);\n```\n\nLook for:\n- Operations finishing out of expected order\n- Operations starting before previous ones complete\n- Suspiciously fast \"completions\" (might not have awaited)\n","# React Async Patterns\n\n## Problem Statement\n\nAsync bugs in React are insidious because they often work in development but fail under load or in edge cases. The most common issues: missing `await` on async functions, race conditions between state updates, and assuming operations complete in order.\n\n---\n\n## Pattern: Floating Promise Detection\n\n**Problem:** Calling an async function without `await` causes it to run in the background. If subsequent code depends on its completion, you get a race condition.\n\n```typescript\n\u002F\u002F Before (buggy) - saveData is async but not awaited\nsaveData(item);              \u002F\u002F Fire and forget ❌\nawait processData(item);     \u002F\u002F Runs before save completes\n\n\u002F\u002F After (fixed)\nawait saveData(item);        \u002F\u002F Wait for state update ✅\nawait processData(item);     \u002F\u002F Now runs in correct order\n```\n\n**Why it's subtle:** Both functions might have `async` in their signature, but only one was awaited. The code \"looks right\" at a glance.\n\n**Detection:**\n\n```bash\n# Find potential floating promises - async calls without await\ngrep -rn \"^\\s*[a-zA-Z]*\\s*(\" --include=\"*.ts\" --include=\"*.tsx\" | \\\n  grep -v \"await\\|return\\|const\\|let\\|if\\|else\\|=>\"\n```\n\n**Prevention:**\n\n1. ESLint rule `@typescript-eslint\u002Fno-floating-promises` - catches this at lint time\n2. Code review trigger: Any line calling a function that might be async without `await`, `return`, or assignment\n\n---\n\n## Pattern: Post-Condition Validation\n\n**Problem:** Assuming an async call succeeded without verifying. The call might return early, throw silently, or fail to update state.\n\n```typescript\n\u002F\u002F Before (buggy) - assumed load worked\nawait loadData(id);\n\u002F\u002F Proceeded blindly with next steps...\n\n\u002F\u002F After (defensive)\nawait loadData(id);\nconst loaded = useStore.getState().data;\nif (Object.keys(loaded).length === 0) {\n  throw new Error(\n    `Failed to load data for ${id} - cannot proceed`\n  );\n}\n```\n\n**Principle:** Treat every async call as potentially failed until proven otherwise.\n\n**When to validate:**\n\n- After loading data that subsequent operations depend on\n- After state updates that must complete before continuing\n- Before irreversible operations (submissions, deletions)\n\n**Pattern template:**\n\n```typescript\nawait someAsyncOperation();\nconst result = getRelevantState();\nif (!isValid(result)) {\n  throw new Error(`[${functionName}] Post-condition failed: ${diagnosticContext}`);\n}\n```\n\n---\n\n## Pattern: Async Function Identification\n\n**Problem:** Not all async functions look async. Zustand actions, callbacks, and promise-returning functions may not have obvious `async` keywords.\n\n**Hidden async patterns:**\n\n```typescript\n\u002F\u002F Obvious async\nasync function fetchData() { ... }\n\n\u002F\u002F Less obvious - returns Promise\nfunction fetchData(): Promise\u003CData> { ... }\n\n\u002F\u002F Hidden - Zustand action that's actually async\nconst useStore = create((set, get) => ({\n  \u002F\u002F This looks sync but calls async internally\n  enableFeature: (id: string) => {\n    someAsyncSetup().then(() => {  \u002F\u002F ← Hidden async!\n      set({ features: [...get().features, id] });\n    });\n  },\n}));\n\n\u002F\u002F Proper async Zustand action\nconst useStore = create((set, get) => ({\n  enableFeature: async (id: string) => {\n    await someAsyncSetup();\n    set({ features: [...get().features, id] });\n  },\n}));\n```\n\n**Detection:** Check function signatures and implementations:\n\n```bash\n# Find functions returning Promise\ngrep -rn \"): Promise\u003C\" --include=\"*.ts\" --include=\"*.tsx\"\n\n# Find .then() chains that might need await\ngrep -rn \"\\.then(\" --include=\"*.ts\" --include=\"*.tsx\"\n```\n\n---\n\n## Pattern: Sequential vs Parallel Async\n\n**Problem:** Running async operations sequentially when they could be parallel (slow), or parallel when they must be sequential (race condition).\n\n```typescript\n\u002F\u002F Sequential - correct when order matters\nawait stepOne();\nawait stepTwo();\nawait stepThree();\n\n\u002F\u002F Parallel - correct when operations are independent\nconst [user, settings, history] = await Promise.all([\n  fetchUser(id),\n  fetchSettings(id),\n  fetchHistory(id),\n]);\n\n\u002F\u002F WRONG - parallel when order matters\nawait Promise.all([\n  stepOne(),   \u002F\u002F These have dependencies!\n  stepTwo(),\n]);\n```\n\n**Decision framework:**\n\n| Operations share state? | Must run in order? | Pattern |\n|------------------------|-------------------|---------|\n| No | No | `Promise.all()` |\n| Yes | Yes | Sequential `await` |\n| Yes | No | Usually sequential to be safe |\n\n---\n\n## Pattern: Async in useEffect\n\n**Problem:** `useEffect` callbacks can't be async directly. Common mistakes with cleanup and race conditions.\n\n```typescript\n\u002F\u002F WRONG - useEffect can't be async\nuseEffect(async () => {\n  const data = await fetchData();\n  setData(data);\n}, []);\n\n\u002F\u002F CORRECT - async function inside\nuseEffect(() => {\n  async function load() {\n    const data = await fetchData();\n    setData(data);\n  }\n  load();\n}, []);\n\n\u002F\u002F BETTER - with cleanup for race conditions\nuseEffect(() => {\n  let cancelled = false;\n\n  async function load() {\n    const data = await fetchData();\n    if (!cancelled) {\n      setData(data);\n    }\n  }\n  load();\n\n  return () => {\n    cancelled = true;\n  };\n}, [dependency]);\n\n\u002F\u002F BEST - use AbortController for fetch\nuseEffect(() => {\n  const controller = new AbortController();\n\n  async function load() {\n    try {\n      const response = await fetch(url, { signal: controller.signal });\n      const data = await response.json();\n      setData(data);\n    } catch (error) {\n      if (error.name !== 'AbortError') {\n        setError(error);\n      }\n    }\n  }\n  load();\n\n  return () => controller.abort();\n}, [url]);\n```\n\n---\n\n## Pattern: React Query \u002F TanStack Query\n\n**Problem:** Manual async state management is error-prone. Use a library.\n\n```typescript\nimport { useQuery, useMutation, useQueryClient } from '@tanstack\u002Freact-query';\n\n\u002F\u002F Fetching data\nfunction UserProfile({ userId }) {\n  const { data, isLoading, error } = useQuery({\n    queryKey: ['user', userId],\n    queryFn: () => fetchUser(userId),\n  });\n\n  if (isLoading) return \u003CSpinner \u002F>;\n  if (error) return \u003CError error={error} \u002F>;\n  return \u003CProfile user={data} \u002F>;\n}\n\n\u002F\u002F Mutations with cache invalidation\nfunction UpdateUser() {\n  const queryClient = useQueryClient();\n\n  const mutation = useMutation({\n    mutationFn: updateUser,\n    onSuccess: () => {\n      queryClient.invalidateQueries({ queryKey: ['user'] });\n    },\n  });\n\n  return (\n    \u003Cbutton onClick={() => mutation.mutate(userData)}>\n      Save\n    \u003C\u002Fbutton>\n  );\n}\n```\n\n---\n\n## ESLint Configuration\n\nAdd these rules to catch async issues at lint time:\n\n```json\n{\n  \"rules\": {\n    \"@typescript-eslint\u002Fno-floating-promises\": \"error\",\n    \"@typescript-eslint\u002Frequire-await\": \"warn\",\n    \"@typescript-eslint\u002Fawait-thenable\": \"error\",\n    \"@typescript-eslint\u002Fno-misused-promises\": \"error\"\n  }\n}\n```\n\n**Required:** `@typescript-eslint\u002Feslint-plugin` and proper TypeScript configuration.\n\n---\n\n## Code Review Checklist\n\nWhen reviewing async code, check:\n\n- [ ] Every async function call is either `await`ed, `return`ed, or explicitly fire-and-forget with comment\n- [ ] Operations that depend on each other are sequenced with `await`\n- [ ] Post-conditions validated after critical async operations\n- [ ] `useEffect` with async uses the inner function pattern\n- [ ] Race conditions considered when component could unmount during async\n- [ ] Error handling exists for async failures\n- [ ] AbortController used for fetch calls that should be cancellable\n\n---\n\n## Quick Debugging\n\nWhen async timing issues occur:\n\n```typescript\n\u002F\u002F Add timestamps to trace execution order\nconsole.log(`[${Date.now()}] Starting step 1`);\nawait stepOne();\nconsole.log(`[${Date.now()}] Finished step 1`);\nconsole.log(`[${Date.now()}] Starting step 2`);\nawait stepTwo();\nconsole.log(`[${Date.now()}] Finished step 2`);\n```\n\nLook for:\n- Operations finishing out of expected order\n- Operations starting before previous ones complete\n- Suspiciously fast \"completions\" (might not have awaited)\n",{"name":5,"description":7},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002Faiskillstore\u002Fmarketplace\u002Fcjharmath\u002Freact-async-patterns",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill react-async-patterns",{"tool":59,"command":60},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill react-async-patterns",{"tool":62,"command":63},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill react-async-patterns","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcjharmath\u002Freact-async-patterns\u002FSKILL.md",true,[67],{"path":68,"resourceType":69,"resourceTypeDesc":70,"sizeBytes":71,"sourceHtmlUrl":72},"skill-report.json","REFERENCE","参考文档",14548,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Faiskillstore\u002Fmarketplace\u002Fcjharmath\u002Freact-async-patterns\u002Fskill-report.json",[74,86,96,105,111,118],{"skillNo":75,"name":76,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":77,"categories":78,"keywords":82,"publishedAt":39},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[79],{"categoryNo":80,"categoryName":81,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[83,84,85],"model","model hierarchy","model hierarchy skill",{"skillNo":87,"name":88,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":89,"categories":90,"keywords":92,"publishedAt":39},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[91],{"categoryNo":80,"categoryName":81,"taxonomyType":21,"taxonomyTypeDesc":22},[93,94,95],"MCP","zoom","zoom mcp",{"skillNo":97,"name":98,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":99,"categories":100,"keywords":101,"publishedAt":39},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[102,103,104,94],"sdk","zoom apps sdk","apps",{"skillNo":106,"name":107,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":108,"categories":109,"keywords":110,"publishedAt":39},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[107],{"skillNo":112,"name":113,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":114,"categories":115,"keywords":117,"publishedAt":39},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[116],{"categoryNo":80,"categoryName":81,"taxonomyType":21,"taxonomyTypeDesc":22},[113],{"skillNo":119,"name":120,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":121,"categories":122,"keywords":123,"publishedAt":39},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[120]]