{"_id":"@douglance/stdb-standard-types","name":"@douglance/stdb-standard-types","dist-tags":{"latest":"1.0.0"},"versions":{"1.0.0":{"name":"@douglance/stdb-standard-types","version":"1.0.0","description":"Strictly-typed foundation for SpacetimeDB modules, eliminating implicit any types","types":"./index.d.ts","keywords":["spacetimedb","typescript","types","reducer","database"],"author":"","license":"MIT","peerDependencies":{"spacetimedb":"^1.0.0"},"repository":{"type":"git","url":"git+https://github.com/clockworklabs/spacetimedb.git"},"_id":"@douglance/stdb-standard-types@1.0.0","gitHead":"d95209c60e55e862b01f3a505241d5059eacf573","bugs":{"url":"https://github.com/clockworklabs/spacetimedb/issues"},"homepage":"https://github.com/clockworklabs/spacetimedb#readme","_nodeVersion":"23.10.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-+7ST2z+q15DB0+yeWzxariGuxRNd/V5JGRmuQnubOCy+sLWPzFH1ghnghfvCBPe9wbAcYBacAvhrCZca1q2EJg==","shasum":"5aa519fae7addde7978b7e2980624594e9a3446b","tarball":"https://registry.npmjs.org/@douglance/stdb-standard-types/-/stdb-standard-types-1.0.0.tgz","fileCount":4,"unpackedSize":7424,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFEqb6Gsw/W4kZlhaJcvm4WWIchlQBhR10vPsLAmONgUAiEA+2Tnk5DApxUB8eCKFN56hANFYvnfBCOw63rNpYQGpMg="}]},"_npmUser":{"name":"douglance","email":"douglance@gmail.com"},"directories":{},"maintainers":[{"name":"douglance","email":"douglance@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/stdb-standard-types_1.0.0_1761473533889_0.20308304204381744"},"_hasShrinkwrap":false}},"time":{"created":"2025-10-26T10:12:13.779Z","1.0.0":"2025-10-26T10:12:14.095Z","modified":"2025-10-26T10:12:14.412Z"},"maintainers":[{"name":"douglance","email":"douglance@gmail.com"}],"description":"Strictly-typed foundation for SpacetimeDB modules, eliminating implicit any types","homepage":"https://github.com/clockworklabs/spacetimedb#readme","keywords":["spacetimedb","typescript","types","reducer","database"],"repository":{"type":"git","url":"git+https://github.com/clockworklabs/spacetimedb.git"},"bugs":{"url":"https://github.com/clockworklabs/spacetimedb/issues"},"license":"MIT","readme":"# @spacetimedb/standard-types\n\nStrictly-typed foundation for SpacetimeDB modules, eliminating implicit `any` types and providing rich IntelliSense.\n\n## Problems Solved\n\n- **Implicit `any` types** for `ctx` and `args` in reducers and systems\n- **Lack of autocomplete** for `ctx.db` tables and their methods\n- **Confusion** around `ctx.timestamp` object vs. a primitive `bigint`\n\n## Installation\n\n```bash\nnpm install @spacetimedb/standard-types\n```\n\n## Usage\n\n### Before: Untyped, Error-Prone\n\n```typescript\n// ❌ No type safety, no autocomplete, runtime errors\nexport function joinGame(ctx, args) {\n  ctx.db.PlayerTag.insert({ entity_id: ctx.sender, name: args.name });\n}\n```\n\n**Problems:**\n- No compile-time errors if table name is wrong (`PlayerTag` vs `playerTag`)\n- No autocomplete for `ctx.db` properties\n- No validation of `args` shape\n- Implicit `any` types everywhere\n\n### After: Fully Typed\n\n```typescript\nimport type { ReducerContext } from \"@spacetimedb/standard-types\";\nimport type { GameSchema } from \"../generated/schema\";\n\ntype JoinGameArgs = { name: string };\n\n// ✅ Full type safety, compile-time errors, full autocomplete\nexport function joinGame(ctx: ReducerContext<GameSchema, JoinGameArgs>, args: JoinGameArgs) {\n  // TypeScript autocomplete shows `ctx.db.playerTag`, not `PlayerTag`\n  // ❌ Compile Error if wrong: Property 'PlayerTag' does not exist on type 'DbView<GameSchema>'\n  ctx.db.playerTag.insert({\n    entity_id: ctx.sender,\n    name: args.name,\n    color: \"#FF0000\",\n  });\n}\n```\n\n**Benefits:**\n- Compile-time errors catch typos in table names\n- Full IntelliSense autocomplete for all tables and methods\n- Args are validated at compile time\n- No implicit `any` types\n\n## API Reference\n\n### `SpacetimeSchema`\n\nBase type for a generated schema object.\n\n```typescript\nexport type SpacetimeSchema = {\n  db: Record<string, {\n    insert: (row: any) => void;\n    update: (row: any) => void;\n    delete: (row: any) => void;\n    find: (pk: any) => any | undefined;\n    iter: () => Iterable<any>;\n  }>;\n};\n```\n\n### `DbView<S>`\n\nThe fully typed database view based on a schema.\n\n```typescript\nexport type DbView<S extends SpacetimeSchema> = S[\"db\"];\n```\n\n### `ReducerContext<S, Args>`\n\nThe context passed to reducers, generic over the schema and reducer arguments.\n\n```typescript\nexport type ReducerContext<\n  S extends SpacetimeSchema,\n  Args extends Record<string, any> = {}\n> = {\n  readonly sender: SpacetimeIdentity;\n  readonly timestamp: SpacetimeTimestamp;\n  readonly connectionId: SpacetimeConnectionId | null;\n  readonly db: DbView<S>;\n  readonly args: Args;\n};\n```\n\n### `SystemContext<S>`\n\nThe context passed to systems.\n\n```typescript\nexport type SystemContext<S extends SpacetimeSchema> = {\n  readonly timestamp: SpacetimeTimestamp;\n  readonly db: DbView<S>;\n};\n```\n\n### `ClientLifecycleContext<S>`\n\nContext for client connection/disconnection hooks.\n\n```typescript\nexport type ClientLifecycleContext<S extends SpacetimeSchema> = {\n  readonly sender: SpacetimeIdentity;\n  readonly connectionId: SpacetimeConnectionId;\n  readonly db: DbView<S>;\n};\n```\n\n## Example: Full Module\n\n```typescript\nimport { schema, table, t } from \"spacetimedb/server\";\nimport type { ReducerContext, SystemContext, ClientLifecycleContext } from \"@spacetimedb/standard-types\";\n\n// Define schema\nconst PlayerTag = table({ name: 'PlayerTag', public: true }, {\n  entity_id: t.identity().primaryKey(),\n  name: t.string(),\n});\n\nconst Position = table({ name: 'Position', public: true }, {\n  entity_id: t.identity().primaryKey(),\n  x: t.f32(),\n  y: t.f32(),\n});\n\nexport const gameSchema = schema(PlayerTag, Position);\nexport type GameSchema = typeof gameSchema;\n\n// Fully typed reducer\ntype JoinGameArgs = { name: string };\n\nexport function joinGame(ctx: ReducerContext<GameSchema, JoinGameArgs>, args: JoinGameArgs) {\n  ctx.db.playerTag.insert({ entity_id: ctx.sender, name: args.name });\n  ctx.db.position.insert({ entity_id: ctx.sender, x: 0, y: 0 });\n}\n\n// Fully typed system\nexport function updatePhysics(ctx: SystemContext<GameSchema>) {\n  for (const pos of ctx.db.position.iter()) {\n    // Physics logic with full type safety\n  }\n}\n\n// Fully typed lifecycle hook\nexport function handleConnect(ctx: ClientLifecycleContext<GameSchema>) {\n  console.log(\"Client connected:\", ctx.sender);\n}\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md","_rev":"1-e7510583a271e90d8e82760a6ba07b4c"}