Token导航 LogoToken导航TokenDH.com
研究检索需要联网github未标认证来源可访问许可证需确认审计提醒

spacetimedb-typescriptspacetimedb TypeScript 搜索

Agent Skill

spacetimedb-typescript 用于查找、检索和筛选相关信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要根据关键词、任务场景或来源线索快速定位候选结果时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

1,963

周安装

81

GitHub Stars

24,575

下载量

642
CodexClaudeCursorGemini CLI

安装说明

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

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

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

请帮我安装这个 Agent Skill:spacetimedb-typescript(spacetimedb TypeScript 搜索)
来源仓库:https://github.com/clockworklabs/spacetimedb
仓库路径:skills/spacetimedb-typescript
安装命令:
npx skills add https://github.com/clockworklabs/spacetimedb --skill spacetimedb-typescript
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

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

skills.shnpx skills
npx skills add https://github.com/clockworklabs/spacetimedb --skill spacetimedb-typescript

简介

spacetimedb-typescript 用于查找、检索和筛选相关信息。

  • 适合在 Codex、Claude、Cursor、Gemini CLI 中根据关键词、任务场景或来源线索快速定位候选结果。
  • 通过 npx skills add 命令从指定 GitHub 仓库安装,需结合原始 README 核验具体用法。
  • 安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写操作。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

SpacetimeDB TypeScript SDK

Build real-time TypeScript clients that connect directly to SpacetimeDB modules. The SDK provides type-safe database access, automatic synchronization, and reactive updates for web apps, Node.js, Deno, Bun, and other JavaScript runtimes.


HALLUCINATED APIs — DO NOT USE

These APIs DO NOT EXIST. LLMs frequently hallucinate them.

// WRONG PACKAGE — does not exist
import { SpacetimeDBClient } from "@clockworklabs/spacetimedb-sdk";

// WRONG — these methods don't exist
SpacetimeDBClient.connect(...);
SpacetimeDBClient.call("reducer_name", [...]);
connection.call("reducer_name", [arg1, arg2]);

// WRONG — positional reducer arguments
conn.reducers.doSomething("value");  // WRONG!

// WRONG — old 1.0 patterns
spacetimedb.reducer('reducer_name', params, fn);  // Use export const name = spacetimedb.reducer(params, fn)
schema(myTable);          // Use schema({ myTable })
schema(t1, t2, t3);      // Use schema({ t1, t2, t3 })
scheduled: 'run_cleanup'  // Use scheduled: () => run_cleanup
.withModuleName('db')     // Use .withDatabaseName('db') (2.0)
setReducerFlags.x('NoSuccessNotify')  // Removed in 2.0

CORRECT PATTERNS:

// CORRECT IMPORTS
import { DbConnection, tables } from './module_bindings';  // Generated!
import { SpacetimeDBProvider, useTable } from 'spacetimedb/react';
import { Identity } from 'spacetimedb';

// CORRECT REDUCER CALLS — object syntax, not positional!
conn.reducers.doSomething({ value: 'test' });
conn.reducers.updateItem({ itemId: 1n, newValue: 42 });

// CORRECT DATA ACCESS — useTable returns [rows, isReady]
const [items, isReady] = useTable(tables.item);

DO NOT:

  • Invent hooks like useItems(), useData() — use useTable(tables.tableName)
  • Import from fake packages — only spacetimedb, spacetimedb/react, ./module_bindings

Common Mistakes Table

Server-side errors

WrongRightError
Missing package.jsonCreate package.json"could not detect language"
Missing tsconfig.jsonCreate tsconfig.json"TsconfigNotFound"
Entrypoint not at src/index.tsUse src/index.tsModule won't bundle
indexes in COLUMNS (2nd arg)indexes in OPTIONS (1st arg) of table()"reading 'tag'" error
Index without algorithmalgorithm: 'btree'"reading 'tag'" error
filter({ownerId})filter(ownerId)"does not exist in type 'Range'"
.filter() on unique column.find() on unique columnTypeError
insert({...without id})insert({id: 0n,...})"Property 'id' is missing"
const id = table.insert(...)const row = table.insert(...).insert() returns ROW, not ID
.unique() + explicit indexJust use .unique()"name is used for multiple entities"
Import spacetimedb from index.tsImport from schema.ts"Cannot access before initialization"
Incorrect multi-column .filter() range shapeMatch index prefix/tuple shapeEmpty results or range/type errors
.iter() in viewsUse index lookups onlyViews can't scan tables
ctx.db in proceduresctx.withTx(tx => tx.db...)Procedures need explicit transactions

Client-side errors

WrongRightError
Inline connectionBuilderuseMemo(() =>..., [])Reconnects every render
const rows = useTable(table)const [rows, isReady] = useTable(table)Tuple destructuring
Optimistic UI updatesLet subscriptions drive stateDesync issues
<SpacetimeDBProvider builder={...}>connectionBuilder={...}Wrong prop name

Hard Requirements

  1. schema({table}) — use a single tables object; optional module settings are allowed as a second argument
  2. Reducer/procedure names from exportsexport const name = spacetimedb.reducer(params, fn); never reducer('name',...)
  3. Reducer calls use object syntax{param: 'value'} not positional args
  4. Import DbConnection from ./module_bindings — not from spacetimedb
  5. DO NOT edit generated bindings — regenerate with spacetime generate
  6. Indexes go in OPTIONS (1st arg) — not in COLUMNS (2nd arg) of table()
  7. Use BigInt for u64/i64 fields0n, 1n, not 0, 1
  8. Reducers are transactional — they do not return data
  9. Reducers must be deterministic — no filesystem, network, timers, random
  10. Views should use index lookups.iter() causes severe performance issues
  11. Procedures need ctx.withTx()ctx.db doesn't exist in procedures
  12. Sum type values — use {tag: 'variant', value: payload} not {variant: payload}
  13. Use .withDatabaseName() — not .withModuleName() (2.0)

Installation

npm install spacetimedb

For Node.js environments without native fetch/WebSocket support, install undici.

Generating Type Bindings

spacetime generate --lang typescript --out-dir ./src/module_bindings --module-path ./server

Client Connection

import { DbConnection } from './module_bindings';

const connection = DbConnection.builder()
  .withUri('ws://localhost:3000')
  .withDatabaseName('my_database')
  .withToken(localStorage.getItem('spacetimedb_token') ?? undefined)
  .onConnect((conn, identity, token) => {
    // identity: your unique Identity for this database
    console.log('Connected as:', identity.toHexString());

    // Save token for reconnection (preserves identity across sessions)
    localStorage.setItem('spacetimedb_token', token);

    conn.subscriptionBuilder()
      .onApplied(() => console.log('Cache ready'))
      .subscribe('SELECT * FROM player');
  })
  .onDisconnect((ctx) => console.log('Disconnected'))
  .onConnectError((ctx, error) => console.error('Connection failed:', error))
  .build();

Subscribing to Tables

// Basic subscription
connection.subscriptionBuilder()
  .onApplied((ctx) => console.log('Cache ready'))
  .subscribe('SELECT * FROM player');

// Multiple queries
connection.subscriptionBuilder()
  .subscribe(['SELECT * FROM player', 'SELECT * FROM game_state']);

// Subscribe to all tables (development only — cannot mix with Subscribe)
connection.subscriptionBuilder().subscribeToAllTables();

// Subscription handle for later unsubscribe
const handle = connection.subscriptionBuilder()
  .onApplied(() => console.log('Subscribed'))
  .subscribe('SELECT * FROM player');

handle.unsubscribeThen(() => console.log('Unsubscribed'));

Accessing Table Data

for (const player of connection.db.player.iter()) { console.log(player.name); }
const players = Array.from(connection.db.player.iter());
const count = connection.db.player.count();
const player = connection.db.player.id.find(42n);

Table Event Callbacks

connection.db.player.onInsert((ctx, player) => console.log('New:', player.name));
connection.db.player.onDelete((ctx, player) => console.log('Left:', player.name));
connection.db.player.onUpdate((ctx, old, new_) => console.log(`${old.score} -> ${new_.score}`));

Calling Reducers

CRITICAL: Use object syntax, not positional arguments.

connection.reducers.createPlayer({ name: 'Alice', location: { x: 0, y: 0 } });

Snake_case to camelCase conversion

  • Server: export const do_something = spacetimedb.reducer(...)
  • Client: conn.reducers.doSomething({...})

Identity and Authentication

  • identity and token are provided in the onConnect callback (see Client Connection above)
  • identity.toHexString() for display or logging
  • Omit .withToken() for anonymous connection — server assigns a new identity
  • Pass a stale/invalid token: server issues a new identity and token in onConnect

Error Handling

Connection-level errors (.onConnectError, .onDisconnect) are shown in the Client Connection example above.

// Subscription error
connection.subscriptionBuilder()
  .onApplied(() => console.log('Subscribed'))
  .onError((ctx) => console.error('Subscription error:', ctx.event))
  .subscribe('SELECT * FROM player');

Server-Side Module Development

Table Definition

import { schema, table, t } from 'spacetimedb/server';

export const Task = table({
  name: 'task',
  public: true,
  indexes: [{ name: 'task_owner_id', algorithm: 'btree', columns: ['ownerId'] }]
}, {
  id: t.u64().primaryKey().autoInc(),
  ownerId: t.identity(),
  title: t.string(),
  createdAt: t.timestamp(),
});

Column types

t.identity()           // User identity
t.u64()                // Unsigned 64-bit integer (use for IDs)
t.string()             // Text
t.bool()               // Boolean
t.timestamp()          // Timestamp
t.scheduleAt()         // For scheduled tables only
t.object('Name', {})   // Product types (nested objects)
t.enum('Name', {})     // Sum types (tagged unions)
t.string().optional()  // Nullable
BigInt syntax: All u64/i64 fields use 0n, 1n, not 0, 1.

Schema export

const spacetimedb = schema({ Task, Player });
export default spacetimedb;

Reducer Definition (2.0)

Name comes from the export — NOT from a string argument.

import spacetimedb from './schema';
import { t, SenderError } from 'spacetimedb/server';

export const create_task = spacetimedb.reducer(
  { title: t.string() },
  (ctx, { title }) => {
    if (!title) throw new SenderError('title required');
    ctx.db.task.insert({ id: 0n, ownerId: ctx.sender, title, createdAt: ctx.timestamp });
  }
);

Update Pattern

const existing = ctx.db.task.id.find(taskId);
if (!existing) throw new SenderError('Task not found');
ctx.db.task.id.update({ ...existing, title: newTitle, updatedAt: ctx.timestamp });

Lifecycle Hooks

spacetimedb.clientConnected((ctx) => { /* ctx.sender is the connecting identity */ });
spacetimedb.clientDisconnected((ctx) => { /* clean up */ });

Event Tables (2.0)

Reducer callbacks are removed in 2.0. Use event tables + onInsert instead.

export const DamageEvent = table(
  { name: 'damage_event', public: true, event: true },
  { target: t.identity(), amount: t.u32() }
);

export const deal_damage = spacetimedb.reducer(
  { target: t.identity(), amount: t.u32() },
  (ctx, { target, amount }) => {
    ctx.db.damageEvent.insert({ target, amount });
  }
);

Client subscribes and uses onInsert:

conn.db.damageEvent.onInsert((ctx, evt) => {
  playDamageAnimation(evt.target, evt.amount);
});

Event tables must be subscribed explicitly — they are excluded from subscribeToAllTables().


Views

ViewContext vs AnonymousViewContext

// ViewContext — has ctx.sender, result varies per user
spacetimedb.view({ name: 'my_items', public: true }, t.array(Item.rowType), (ctx) => {
  return [...ctx.db.item.by_owner.filter(ctx.sender)];
});

// AnonymousViewContext — no ctx.sender, same result for everyone (better perf)
spacetimedb.anonymousView({ name: 'leaderboard', public: true }, t.array(Player.rowType), (ctx) => {
  return ctx.from.player.where(p => p.score.gt(1000));
});

Views can only use index lookups — .iter() is NOT allowed.


Scheduled Tables

export const CleanupJob = table({
  name: 'cleanup_job',
  scheduled: () => run_cleanup  // function returning the exported reducer
}, {
  scheduledId: t.u64().primaryKey().autoInc(),
  scheduledAt: t.scheduleAt(),
  targetId: t.u64(),
});

export const run_cleanup = spacetimedb.reducer(
  { arg: CleanupJob.rowType },
  (ctx, { arg }) => { /* arg.scheduledId, arg.targetId available */ }
);

// Schedule a job
import { ScheduleAt } from 'spacetimedb';
ctx.db.cleanupJob.insert({
  scheduledId: 0n,
  scheduledAt: ScheduleAt.time(ctx.timestamp.microsSinceUnixEpoch + 60_000_000n),
  targetId: someId
});

ScheduleAt on Client

// ScheduleAt is a tagged union on the client
// { tag: 'Time', value: Timestamp } or { tag: 'Interval', value: TimeDuration }
const schedule = row.scheduledAt;
if (schedule.tag === 'Time') {
  const date = new Date(Number(schedule.value.microsSinceUnixEpoch / 1000n));
}

Timestamps

Server-side

ctx.db.item.insert({ id: 0n, createdAt: ctx.timestamp });
const future = ctx.timestamp.microsSinceUnixEpoch + 300_000_000n;

Client-side

// Timestamps are objects with BigInt, not numbers
const date = new Date(Number(row.createdAt.microsSinceUnixEpoch / 1000n));

Procedures (Beta)

export const fetch_data = spacetimedb.procedure(
  { url: t.string() }, t.string(),
  (ctx, { url }) => {
    const response = ctx.http.fetch(url);
    ctx.withTx(tx => { tx.db.myTable.insert({ id: 0n, content: response.text() }); });
    return response.text();
  }
);

Procedures don't have ctx.db — use ctx.withTx(tx => tx.db...).


React Integration

import { useMemo } from 'react';
import { SpacetimeDBProvider, useTable } from 'spacetimedb/react';
import { DbConnection, tables } from './module_bindings';

function Root() {
  const connectionBuilder = useMemo(() =>
    DbConnection.builder()
      .withUri('ws://localhost:3000')
      .withDatabaseName('my_game')
      .withToken(localStorage.getItem('auth_token') || undefined)
      .onConnect((conn, identity, token) => {
        localStorage.setItem('auth_token', token);
        conn.subscriptionBuilder().subscribe(tables.player);
      }),
    []
  );

  return (
    <SpacetimeDBProvider connectionBuilder={connectionBuilder}>
      <App />
    </SpacetimeDBProvider>
  );
}

function PlayerList() {
  const [players, isReady] = useTable(tables.player);
  if (!isReady) return <div>Loading...</div>;
  return <ul>{players.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
}

Project Structure

Server (backend/spacetimedb/)

src/schema.ts   -> Tables, export spacetimedb
src/index.ts    -> Reducers, lifecycle, import schema
package.json    -> { "type": "module", "dependencies": { "spacetimedb": "^2.0.0" } }
tsconfig.json   -> Standard config

Client (client/)

src/module_bindings/ -> Generated (spacetime generate)
src/main.tsx         -> Provider, connection setup
src/App.tsx          -> UI components

Commands

spacetime start
spacetime publish <module-name> --module-path <backend-dir>
spacetime publish <module-name> --clear-database -y --module-path <backend-dir>
spacetime generate --lang typescript --out-dir <client>/src/module_bindings --module-path <backend-dir>
spacetime logs <module-name>

适合场景

01

用户想查找某类 Agent Skill 时

02

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

03

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

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

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

能力 4

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

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

平台分布

Codex

35.75%
按下载量换算230

Claude

29.99%
按下载量换算193

Cursor

16.12%
按下载量换算103

Gemini CLI

9.86%
按下载量换算63

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

可疑

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

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

来源信息

继续浏览同类 Skills