Token导航 LogoToken导航TokenDH.com
前端设计操作浏览器github未标认证来源可访问许可证需确认审计通过

sync-construction-async-property-ui-render-gate-pattern同步构造异步属性 ui 渲染门模式

Agent Skill

用于辅助界面设计、视觉规范、排版、配色、布局和交互体验优化。它适合让 Agent 根据产品场景整理页面结构、生成 UI 方案、检查视觉一致性或改进组件层级。使用时需要结合现有品牌、设计系统和用户任务,不应只堆装饰元素;涉及真实页面改动时,应通过截图或浏览器预览检查文本溢出、对齐和响应式表现。

总安装

1,212

周安装

50

GitHub Stars

4,462

下载量

396
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:sync-construction-async-property-ui-render-gate-pattern(同步构造异步属性 ui 渲染门模式)
来源仓库:https://github.com/epicenterhq/epicenter
仓库路径:skills/sync-construction-async-property-ui-render-gate-pattern
安装命令:
npx skills add https://github.com/epicenterhq/epicenter --skill sync-construction-async-property-ui-render-gate-pattern
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/epicenterhq/epicenter --skill sync-construction-async-property-ui-render-gate-pattern

简介

sync-construction-async-property-ui-render-gate-pattern 用于辅助界面设计、视觉规范和交互体验优化,适合在 Codex、Claude、Cursor、Gemini CLI 中生成 UI 方案或检查一致性时使用。

  • 适用于异步数据加载、动态属性渲染或响应式布局设计等前端开发场景。
  • 可结合现有品牌规范生成组件层级建议,但需人工验证实际渲染效果。
  • 安装命令为 npx skills add https://github.com/epicenterhq/epicenter --skill sync-construction-async-property-ui-render-gate-pattern。
  • 涉及真实页面改动时应通过浏览器预览检查文本溢出、对齐和响应式表现问题。

SKILL.md

Sync Construction, Async Property

The initialization of the client is synchronous. The async work is stored as a property you can await, while passing the reference around.

When to Apply This Pattern

Use this when you have:

  • Async client initialization (IndexedDB, server connection, file system)
  • Module exports that need to be importable without await
  • UI components that want sync access to the client
  • SvelteKit apps where you want to gate rendering on readiness

Signals you're fighting async construction:

  • await getX() patterns everywhere
  • Top-level await complaints from bundlers
  • Getter functions wrapping singleton access
  • Components that can't import a client directly

The Problem

Async constructors can't be exported:

// This doesn't work
export const client = await createClient(); // Top-level await breaks bundlers

So you end up with getter patterns:

let client: Client | null = null;

export async function getClient() {
	if (!client) {
		client = await createClient();
	}
	return client;
}

// Every consumer must await
const client = await getClient();

Every call site needs await. You're passing promises around instead of objects.

The Pattern

Make construction synchronous. Attach async work to the object:

// client.ts
export const client = createClient();

// Sync access works immediately
client.save(data);
client.load(id);

// Await the async work when you need to
await client.whenSynced;

Construction returns immediately. The async initialization (loading from disk, connecting to servers) happens in the background and is tracked via whenSynced.

The UI Render Gate

In Svelte, gate once at the root using @epicenter/ui/spinner for the loading state and @epicenter/ui/empty for error recovery:

<!-- +layout.svelte -->
<script>
	import * as Empty from '@epicenter/ui/empty';
	import { Spinner } from '@epicenter/ui/spinner';
	import TriangleAlertIcon from '@lucide/svelte/icons/triangle-alert';
	import { client } from '$lib/client';
</script>

{#await client.whenSynced}
	<Empty.Root class="flex-1">
		<Empty.Media>
			<Spinner class="size-5 text-muted-foreground" />
		</Empty.Media>
		<Empty.Title>Loading…</Empty.Title>
	</Empty.Root>
{:then}
	{@render children?.()}
{:catch}
	<Empty.Root class="flex-1">
		<Empty.Media>
			<TriangleAlertIcon class="size-8 text-muted-foreground" />
		</Empty.Media>
		<Empty.Title>Failed to load</Empty.Title>
		<Empty.Description>
			Something went wrong during initialization. Try reloading.
		</Empty.Description>
	</Empty.Root>

The gate guarantees: by the time any child component's script runs, the async work is complete. Children use sync access without checking readiness.

Always include {:catch} — if the async seed fails (e.g. browser.windows.getAll throws), the user sees an actionable error instead of an infinite spinner.

Implementation

The withCapabilities() fluent builder attaches async work to a sync-constructed object:

function createClient() {
	const state = initializeSyncState();

	return {
		save(data) {
			/* sync method */
		},
		load(id) {
			/* sync method */
		},

		withCapabilities({ persistence }) {
			const whenSynced = persistence(state);
			return Object.assign(this, { whenSynced });
		},
	};
}

// Usage
export const client = createClient().withCapabilities({
	persistence: (state) => loadFromIndexedDB(state),
});

Before and After

AspectAsync ConstructionSync + whenSynced
Module exportCan't export directlyExport the object
Consumer codeawait getX() everywhereDirect import, sync use
UI integrationAwkward promise handlingSingle {#await} gate
Type signaturePromise<X>X with .whenSynced

Real-World Example: y-indexeddb

The Yjs ecosystem uses this pattern everywhere:

const provider = new IndexeddbPersistence('my-db', doc);
// Constructor returns immediately

provider.on('update', handleUpdate); // Sync access works

await provider.whenSynced; // Wait when you need to

They never block construction. The async work is always deferred to a property you can await.

Alternate Pattern: Await in Every Method

Alternatively, you can skip the whenReady property entirely and hide the initialization await inside each method. The canonical example is idb:

const dbPromise = openDB('keyval-store', 1, { upgrade(db) { db.createObjectStore('keyval') } });

export async function get(key) { return (await dbPromise).get('keyval', key); }
export async function set(key, val) { return (await dbPromise).put('keyval', val, key); }

Use whenReady when your client has sync methods that depend on initialized state. Use await-in-every-method when every method is async anyway (like database access). See the idb await-in-every-method article for a deeper comparison.

Related Patterns

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

34.22%
按下载量换算136

Claude

31.99%
按下载量换算127

Cursor

17.5%
按下载量换算69

Gemini CLI

9.88%
按下载量换算39

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

操作浏览器

该 Skill 可能涉及浏览器控制能力,使用时可能读取或操作网页内容,需要在受控环境中确认权限边界。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills